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

Unified Diff: src/x64/macro-assembler-x64.cc

Issue 201042: Win64 - Allow returning two values from a runtime function. (Closed)
Patch Set: Fixed typo. Created 11 years, 3 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
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));

Powered by Google App Engine
This is Rietveld 408576698