Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Unified Diff: src/codegen-ia32.cc

Issue 7077: Under construction: Preliminary change to support per... Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/codegen-ia32.h ('k') | src/heap.cc » ('j') | src/objects.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codegen-ia32.cc
===================================================================
--- src/codegen-ia32.cc (revision 485)
+++ src/codegen-ia32.cc (working copy)
@@ -1179,7 +1179,11 @@
__ mov(edx, Operand(eax));
__ mov(Operand(eax), Immediate(Smi::FromInt(value_)));
__ CallStub(&stub);
- __ cmp(eax, 0);
+ if (cc_ == equal) {
+ __ test(eax, Operand(eax));
+ } else {
+ __ cmp(eax, 0);
+ }
// "result" is returned in the flags
}
@@ -1207,26 +1211,29 @@
class CallFunctionStub: public CodeStub {
public:
- explicit CallFunctionStub(int argc) : argc_(argc) { }
+ explicit CallFunctionStub(int argc, bool call_constructor)
+ : argc_(argc), call_constructor_(call_constructor) { }
void Generate(MacroAssembler* masm);
private:
int argc_;
+ bool call_constructor_;
#ifdef DEBUG
void Print() { PrintF("CallFunctionStub (args %d)\n", argc_); }
#endif
Major MajorKey() { return CallFunction; }
- int MinorKey() { return argc_; }
+ int MinorKey() { return (argc_ << 1) | (call_constructor_ ? 1 : 0); }
};
// Call the function just below TOS on the stack with the given
// arguments. The receiver is the TOS.
void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
- int position) {
+ bool call_constructor,
iposva 2008/10/10 13:56:18 Please change the bool parameter to an enum {FUNCT
+ int position) {
// Push the arguments ("left-to-right") on the stack.
for (int i = 0; i < args->length(); i++) {
Load(args->at(i));
@@ -1236,8 +1243,11 @@
__ RecordPosition(position);
// Use the shared code stub to call the function.
- CallFunctionStub call_function(args->length());
- __ CallStub(&call_function);
+ CallFunctionStub call_function(args->length(), call_constructor);
+ RelocInfo::Mode mode = call_constructor
+ ? RelocInfo::CONSTRUCT_CALL
+ : RelocInfo::CODE_TARGET;
+ __ CallStub(&call_function, mode);
// Restore context and pop function from the stack.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2597,7 +2607,7 @@
__ push(edx);
// Call the function.
- CallWithArguments(args, node->position());
+ CallWithArguments(args, false, node->position());
} else if (property != NULL) {
// Check if the key is a literal string.
@@ -2638,7 +2648,7 @@
__ push(Operand(esp, ref.size() * kPointerSize));
// Call the function.
- CallWithArguments(args, node->position());
+ CallWithArguments(args, false, node->position());
}
} else {
@@ -2653,7 +2663,7 @@
LoadGlobal();
// Call the function.
- CallWithArguments(args, node->position());
+ CallWithArguments(args, false, node->position());
}
}
@@ -2672,25 +2682,7 @@
Load(node->expression());
LoadGlobal();
- // Push the arguments ("left-to-right") on the stack.
- ZoneList<Expression*>* args = node->arguments();
- for (int i = 0; i < args->length(); i++) Load(args->at(i));
-
- // Constructors are called with the number of arguments in register
- // eax for now. Another option would be to have separate construct
- // call trampolines per different arguments counts encountered.
- __ Set(eax, Immediate(args->length()));
-
- // Load the function into temporary function slot as per calling
- // convention.
- __ mov(edi, Operand(esp, (args->length() + 1) * kPointerSize));
-
- // Call the construct call builtin that handles allocation and
- // constructor invocation.
- __ RecordPosition(node->position());
- __ call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
- RelocInfo::CONSTRUCT_CALL);
- __ mov(TOS, eax); // discard the function and "push" the newly created object
+ CallWithArguments(node->arguments(), true, node->position());
iposva 2008/10/10 13:56:18 Nice refactoring!
}
@@ -4653,16 +4645,34 @@
__ j(not_equal, &slow, not_taken);
// Fast-case: Just invoke the function.
- ParameterCount actual(argc_);
- __ InvokeFunction(edi, actual, JUMP_FUNCTION);
+ if (call_constructor_) {
+ __ Set(eax, Immediate(argc_));
+ __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+ __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
+ __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kConstructorOffset));
+ __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
+ __ jmp(Operand(edx));
+ } else {
+ ParameterCount actual(argc_);
+ __ InvokeFunction(edi, actual, JUMP_FUNCTION);
+ }
// Slow-case: Non-function called.
__ bind(&slow);
- __ Set(eax, Immediate(argc_));
- __ Set(ebx, Immediate(0));
- __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
- Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
- __ jmp(adaptor, RelocInfo::CODE_TARGET);
+ if (call_constructor_) {
+ // Get rid of the arguments and the receiver and call the NewObject
+ // runtime function to generate and throw an exception.
+ __ pop(ecx);
+ __ add(Operand(esp), Immediate((argc_ + 1) * kPointerSize));
+ __ push(ecx);
+ __ TailCallRuntime(ExternalReference(Runtime::kNewObject), 1);
+ } else {
+ __ Set(eax, Immediate(argc_));
+ __ Set(ebx, Immediate(0));
+ __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
+ Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
+ __ jmp(adaptor, RelocInfo::CODE_TARGET);
+ }
}
« no previous file with comments | « src/codegen-ia32.h ('k') | src/heap.cc » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698