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