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); |
| } |