Chromium Code Reviews| Index: src/ia32/macro-assembler-ia32.cc | 
| =================================================================== | 
| --- src/ia32/macro-assembler-ia32.cc (revision 3911) | 
| +++ src/ia32/macro-assembler-ia32.cc (working copy) | 
| @@ -1145,17 +1145,80 @@ | 
| return; | 
| } | 
| - // TODO(1236192): Most runtime routines don't need the number of | 
| - // arguments passed in because it is constant. At some point we | 
| - // should remove this need and make the runtime routine entry code | 
| - // smarter. | 
| - Set(eax, Immediate(num_arguments)); | 
| - mov(ebx, Immediate(ExternalReference(f))); | 
| - CEntryStub ces(1); | 
| - CallStub(&ces); | 
| + if (Runtime::EXIT_FRAME_CALL == f->calling_convention) { | 
| + // TODO(1236192): Most runtime routines don't need the number of | 
| + // arguments passed in because it is constant. At some point we | 
| + // should remove this need and make the runtime routine entry code | 
| + // smarter. | 
| + Set(eax, Immediate(num_arguments)); | 
| + mov(ebx, Immediate(ExternalReference(f))); | 
| + CEntryStub ces(1); | 
| + CallStub(&ces); | 
| + } else { | 
| + DirectInvokeRuntime(f, CALL_FUNCTION); | 
| + } | 
| } | 
| +void MacroAssembler::DirectInvokeRuntime(Runtime::Function* f, | 
| + InvokeFlag flag) { | 
| + // Stack: | 
| + // arg1 | 
| + // ... | 
| + // argN | 
| + // ret addr (if tail call) | 
| + static const int kFrameAlignment = OS::ActivationFrameAlignment(); | 
| + | 
| 
 
Søren Thygesen Gjesse
2010/02/22 12:38:22
I still think we should have the handling of calli
 
 | 
| + ASSERT(kFrameAlignment > 0); | 
| + if (flag == JUMP_FUNCTION) { | 
| + mov(eax, esp); | 
| + } else { | 
| + // This value will be stored on stack and then loaded into esp | 
| + // to remove arguments. | 
| + lea(eax, Operand(esp, f->nargs * kPointerSize)); | 
| + } | 
| + | 
| + ASSERT(IsPowerOf2(kFrameAlignment)); | 
| + and_(esp, -kFrameAlignment); | 
| + | 
| + // How many bytes need to be reserved to keep stack aligned after | 
| + // pushing eax and args. | 
| + const int alignmentPlaceholder = (-(f->nargs + 1) * kPointerSize) | 
| + & (kFrameAlignment - 1); | 
| + sub(Operand(esp), Immediate(alignmentPlaceholder)); | 
| + ASSERT((alignmentPlaceholder + kPointerSize * (f->nargs + 1)) | 
| + % kFrameAlignment == 0); | 
| + | 
| + push(eax); | 
| + for (int i = 0; i < f->nargs; i++) { | 
| + if (flag == JUMP_FUNCTION) { | 
| + push(Operand(eax, (i + 1) * kPointerSize)); | 
| + } else { | 
| + push(Operand(eax, (i - f->nargs) * kPointerSize)); | 
| + } | 
| + } | 
| + | 
| + // Stack: | 
| + // ag1 | 
| + // ... | 
| + // argN | 
| + // ret addr (if tail call) | 
| + // <stack alignment placeholder> | 
| + // esp to restore | 
| + // argN | 
| + // ... | 
| + // arg1 | 
| + | 
| + // Performing a semi tail call as we need to copy the arguments for alignment. | 
| + call(FUNCTION_ADDR(ExternalReference(f).address()), RelocInfo::RUNTIME_ENTRY); | 
| + | 
| + mov(esp, Operand(esp, f->nargs * kPointerSize)); | 
| + if (flag == JUMP_FUNCTION) { | 
| + ret(f->nargs); | 
| + } | 
| 
 
Søren Thygesen Gjesse
2010/02/22 12:38:22
Maybe just adjust the stack by f->nargs in an else
 
 | 
| +} | 
| + | 
| + | 
| void MacroAssembler::CallExternalReference(ExternalReference ref, | 
| int num_arguments) { | 
| mov(eax, Immediate(num_arguments)); | 
| @@ -1186,13 +1249,29 @@ | 
| } | 
| -void MacroAssembler::TailCallRuntime(const ExternalReference& ext, | 
| +void MacroAssembler::TailCallRuntime(Runtime::FunctionId id, | 
| int num_arguments, | 
| int result_size) { | 
| + Runtime::Function* f = Runtime::FunctionForId(id); | 
| // TODO(1236192): Most runtime routines don't need the number of | 
| // arguments passed in because it is constant. At some point we | 
| // should remove this need and make the runtime routine entry code | 
| // smarter. | 
| + if (f->calling_convention == Runtime::EXIT_FRAME_CALL) { | 
| + TailCallExternalReference(ExternalReference(f), num_arguments, result_size); | 
| + } else { | 
| + DirectInvokeRuntime(f, JUMP_FUNCTION); | 
| + } | 
| +} | 
| + | 
| + | 
| +void MacroAssembler::TailCallExternalReference(const ExternalReference& ext, | 
| + int num_arguments, | 
| + int result_size) { | 
| + // TODO(1236192): Most runtime routines don't need the number of | 
| + // arguments passed in because it is constant. At some point we | 
| + // should remove this need and make the runtime routine entry code | 
| + // smarter. | 
| Set(eax, Immediate(num_arguments)); | 
| JumpToRuntime(ext); | 
| } |