Index: src/x64/macro-assembler-x64.cc |
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
index ae45eaba547c1df29643972f00b783fc7b2be212..c1fac030defddb637d8d894f8d4e78096ca5eace 100644 |
--- a/src/x64/macro-assembler-x64.cc |
+++ b/src/x64/macro-assembler-x64.cc |
@@ -318,7 +318,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) { |
void MacroAssembler::TailCallRuntime(ExternalReference const& ext, |
- int num_arguments) { |
+ int num_arguments, |
+ int result_size) { |
// ----------- S t a t e ------------- |
// -- rsp[0] : return address |
// -- rsp[8] : argument num_arguments - 1 |
@@ -331,14 +332,15 @@ void MacroAssembler::TailCallRuntime(ExternalReference const& ext, |
// should remove this need and make the runtime routine entry code |
// smarter. |
movq(rax, Immediate(num_arguments)); |
- JumpToBuiltin(ext); |
+ JumpToBuiltin(ext, result_size); |
} |
-void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) { |
+void MacroAssembler::JumpToBuiltin(const ExternalReference& ext, |
+ int result_size) { |
// Set the entry point and jump to the C entry runtime stub. |
movq(rbx, ext); |
- CEntryStub ces; |
+ CEntryStub ces(result_size); |
movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET); |
jmp(kScratchRegister); |
} |
@@ -971,7 +973,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
-void MacroAssembler::EnterExitFrame(StackFrame::Type type) { |
+void MacroAssembler::EnterExitFrame(StackFrame::Type type, int result_size) { |
ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG); |
// Setup the frame structure on the stack. |
@@ -1025,13 +1027,20 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) { |
} |
#ifdef _WIN64 |
+ // Reserve space on stack for result and argument structures, if necessary. |
+ ASSERT(result_size <= 2); |
+ // The structure on the stack must be 16-byte aligned. |
+ int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize; |
// Reserve space for the Arguments object. The Windows 64-bit ABI |
// requires us to pass this structure as a pointer to its location on |
- // the stack. The structure contains 2 pointers. |
- // The structure on the stack must be 16-byte aligned. |
+ // the stack. The structure contains 2 values. |
+ int argument_stack_space = 2 * kPointerSize; |
// We also need backing space for 4 parameters, even though |
- // we only pass one parameter, and it is in a register. |
- subq(rsp, Immediate(6 * kPointerSize)); |
+ // we only pass one or two parameter, and it is in a register. |
+ int argument_mirror_space = 4 * kPointerSize; |
+ int total_stack_space = |
+ argument_mirror_space + argument_stack_space + result_stack_space; |
+ subq(rsp, Immediate(total_stack_space)); |
ASSERT(kFrameAlignment == 2 * kPointerSize); // Change the padding if needed. |
William Hesse
2009/09/07 14:34:18
This assert needs to be changed, to assert that th
Lasse Reichstein
2009/09/08 11:51:35
Rather, we should move the stack aligning code bel
William Hesse
2009/09/08 12:43:52
We don't know that we are subtracting a multiple o
|
#endif |
@@ -1040,7 +1049,7 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) { |
} |
-void MacroAssembler::LeaveExitFrame(StackFrame::Type type) { |
+void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) { |
// Registers: |
// r15 : argv |
#ifdef ENABLE_DEBUGGER_SUPPORT |
@@ -1060,6 +1069,16 @@ void MacroAssembler::LeaveExitFrame(StackFrame::Type type) { |
movq(rcx, Operand(rbp, 1 * kPointerSize)); |
movq(rbp, Operand(rbp, 0 * kPointerSize)); |
+#ifdef _WIN64 |
+ // If return value is on the stack, pop it to registers. |
+ if (result_size > 1) { |
+ ASSERT_EQ(2, result_size); |
+ // Position above 4 argument mirrors and arguments object. |
+ movq(rax, Operand(rsp, 6 * kPointerSize)); |
+ movq(rdx, Operand(rsp, 7 * kPointerSize)); |
+ } |
+#endif |
+ |
// Pop the arguments and the receiver from the caller stack. |
lea(rsp, Operand(r15, 1 * kPointerSize)); |