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

Unified Diff: runtime/vm/stub_code_x64.cc

Issue 317773002: Fix Win64 build of Dart VM. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 6 years, 6 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
« no previous file with comments | « runtime/vm/stack_frame_x64.h ('k') | runtime/vm/stub_code_x64_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/stub_code_x64.cc
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 490d473692993c48e5a38167f13756265c03bda5..9da0ef2d2537eb5cc047ed89d57270c2a5d8a0e9 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -88,7 +88,11 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
__ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments.
__ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument.
__ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments.
- __ call(RBX);
+#if defined(_WIN64)
+ ASSERT(sizeof(NativeArguments) > CallingConventions::kRegisterTransferLimit);
+ __ movq(CallingConventions::kArg1Reg, RSP);
+#endif
+ __ CallCFunction(RBX);
// Mark that the isolate is executing Dart code.
__ movq(Address(CTX, Isolate::vm_tag_offset()),
@@ -126,6 +130,9 @@ END_LEAF_RUNTIME_ENTRY
void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
__ EnterCallRuntimeFrame(0);
// Call the runtime leaf function. RDI already contains the parameter.
+#if defined(_WIN64)
+ __ movq(CallingConventions::kArg1Reg, RDI);
+#endif
__ CallRuntime(kPrintStopMessageRuntimeEntry, 1);
__ LeaveCallRuntimeFrame();
__ ret();
@@ -192,18 +199,21 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
__ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments.
__ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr.
__ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments.
- __ movq(RDI, RSP); // Pass the pointer to the NativeArguments.
+
+ // Pass the pointer to the NativeArguments.
+ __ movq(CallingConventions::kArg1Reg, RSP);
// Call native function (setsup scope if not leaf function).
Label leaf_call;
Label done;
__ testq(R10, Immediate(NativeArguments::AutoSetupScopeMask()));
__ j(ZERO, &leaf_call);
- __ movq(RSI, RBX); // Pass pointer to function entrypoint.
- __ call(&NativeEntry::NativeCallWrapperLabel());
+ // Pass pointer to function entrypoint.
+ __ movq(CallingConventions::kArg2Reg, RBX);
+ __ CallCFunction(&NativeEntry::NativeCallWrapperLabel());
__ jmp(&done);
__ Bind(&leaf_call);
- __ call(RBX);
+ __ CallCFunction(RBX);
__ Bind(&done);
// Mark that the isolate is executing Dart code.
@@ -288,8 +298,10 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
__ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments.
__ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr.
__ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments.
- __ movq(RDI, RSP); // Pass the pointer to the NativeArguments.
- __ call(RBX);
+
+ // Pass the pointer to the NativeArguments.
+ __ movq(CallingConventions::kArg1Reg, RSP);
+ __ CallCFunction(RBX);
// Mark that the isolate is executing Dart code.
__ movq(Address(CTX, Isolate::vm_tag_offset()),
@@ -438,8 +450,9 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
offset += kFpuRegisterSize;
}
- __ movq(RDI, RSP); // Pass address of saved registers block.
- __ ReserveAlignedFrameSpace(0);
+ // Pass address of saved registers block.
+ __ movq(CallingConventions::kArg1Reg, RSP);
+ __ ReserveAlignedFrameSpace(0); // Ensure stack is aligned before the call.
__ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1);
// Result (RAX) is stack-size (FP - SP) in bytes.
@@ -466,7 +479,8 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
__ pushq(RBX); // Preserve result as first local.
}
__ ReserveAlignedFrameSpace(0);
- __ movq(RDI, RBP); // Pass last FP as parameter in RDI.
+ // Pass last FP as a parameter.
+ __ movq(CallingConventions::kArg1Reg, RBP);
__ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
if (preserve_result) {
// Restore result into RBX.
@@ -685,6 +699,11 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
// Save frame pointer coming in.
__ EnterFrame(0);
+ const Register kEntryPointReg = CallingConventions::kArg1Reg;
+ const Register kArgDescReg = CallingConventions::kArg2Reg;
+ const Register kArgsReg = CallingConventions::kArg3Reg;
+ const Register kNewContextReg = CallingConventions::kArg4Reg;
+
// At this point, the stack looks like:
// | saved RBP | <-- RBP
// | saved PC (return to DartEntry::InvokeFunction) |
@@ -692,16 +711,13 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
const intptr_t kInitialOffset = 1;
// Save arguments descriptor array and new context.
const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize;
- __ pushq(RSI);
+ __ pushq(kArgDescReg);
const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize;
- __ pushq(RCX);
+ __ pushq(kNewContextReg);
// Save C++ ABI callee-saved registers.
- __ pushq(RBX);
- __ pushq(R12);
- __ pushq(R13);
- __ pushq(R14);
- __ pushq(R15);
+ __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
+ CallingConventions::kCalleeSaveXmmRegisters);
// We now load the pool pointer(PP) as we are about to invoke dart code and we
// could potentially invoke some intrinsic functions which need the PP to be
@@ -719,28 +735,50 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
// compiled or runtime stub code.
// Cache the new Context pointer into CTX while executing Dart code.
- __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
+ __ movq(CTX, Address(kNewContextReg, VMHandles::kOffsetOfRawPtrInHandle));
+
+ const Register kIsolateReg = RBX;
// Load Isolate pointer from Context structure into R8.
- __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
+ __ movq(kIsolateReg, FieldAddress(CTX, Context::isolate_offset()));
// Save the current VMTag on the stack.
- ASSERT(kSavedVMTagSlotFromEntryFp == -8);
- __ movq(RAX, Address(R8, Isolate::vm_tag_offset()));
+ __ movq(RAX, Address(kIsolateReg, Isolate::vm_tag_offset()));
__ pushq(RAX);
+#if defined(DEBUG)
+ {
+ Label ok;
+ __ leaq(RAX, Address(RBP, kSavedVMTagSlotFromEntryFp * kWordSize));
+ __ cmpq(RAX, RSP);
+ __ j(EQUAL, &ok);
+ __ Stop("kSavedVMTagSlotFromEntryFp mismatch");
+ __ Bind(&ok);
+ }
+#endif
// Mark that the isolate is executing Dart code.
- __ movq(Address(R8, Isolate::vm_tag_offset()),
+ __ movq(Address(kIsolateReg, Isolate::vm_tag_offset()),
Immediate(VMTag::kScriptTagId));
// Save the top exit frame info. Use RAX as a temporary register.
// StackFrameIterator reads the top exit frame info saved in this frame.
// The constant kExitLinkSlotFromEntryFp must be kept in sync with the
// code below.
- ASSERT(kExitLinkSlotFromEntryFp == -9);
- __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset()));
+ __ movq(RAX, Address(kIsolateReg, Isolate::top_exit_frame_info_offset()));
__ pushq(RAX);
- __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0));
+#if defined(DEBUG)
+ {
+ Label ok;
+ __ leaq(RAX, Address(RBP, kExitLinkSlotFromEntryFp * kWordSize));
+ __ cmpq(RAX, RSP);
+ __ j(EQUAL, &ok);
+ __ Stop("kExitLinkSlotFromEntryFp mismatch");
+ __ Bind(&ok);
+ }
+#endif
+
+ __ movq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()),
+ Immediate(0));
// Save the old Context pointer. Use RAX as a temporary register.
// Note that VisitObjectPointers will find this saved Context pointer during
@@ -749,19 +787,31 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
// EntryFrame::SavedContext reads the context saved in this frame.
// The constant kSavedContextSlotFromEntryFp must be kept in sync with
// the code below.
- ASSERT(kSavedContextSlotFromEntryFp == -10);
- __ movq(RAX, Address(R8, Isolate::top_context_offset()));
+ __ movq(RAX, Address(kIsolateReg, Isolate::top_context_offset()));
__ pushq(RAX);
+#if defined(DEBUG)
+ {
+ Label ok;
+ __ leaq(RAX, Address(RBP, kSavedContextSlotFromEntryFp * kWordSize));
+ __ cmpq(RAX, RSP);
+ __ j(EQUAL, &ok);
+ __ Stop("kSavedContextSlotFromEntryFp mismatch");
+ __ Bind(&ok);
+ }
+#endif
// Load arguments descriptor array into R10, which is passed to Dart code.
- __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
+ __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle));
+
+ // Push arguments. At this point we only need to preserve kEntryPointReg.
+ ASSERT(kEntryPointReg != RDX);
// Load number of arguments into RBX.
__ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
__ SmiUntag(RBX);
// Compute address of 'arguments array' data area into RDX.
- __ movq(RDX, Address(RDX, VMHandles::kOffsetOfRawPtrInHandle));
+ __ movq(RDX, Address(kArgsReg, VMHandles::kOffsetOfRawPtrInHandle));
__ leaq(RDX, FieldAddress(RDX, Array::data_offset()));
// Set up arguments for the Dart call.
@@ -771,51 +821,45 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
__ j(ZERO, &done_push_arguments, Assembler::kNearJump);
__ movq(RAX, Immediate(0));
__ Bind(&push_arguments);
- __ movq(RCX, Address(RDX, RAX, TIMES_8, 0)); // RDX is start of arguments.
- __ pushq(RCX);
+ __ pushq(Address(RDX, RAX, TIMES_8, 0));
__ incq(RAX);
__ cmpq(RAX, RBX);
__ j(LESS, &push_arguments, Assembler::kNearJump);
__ Bind(&done_push_arguments);
// Call the Dart code entrypoint.
- __ call(RDI); // R10 is the arguments descriptor array.
+ __ call(kEntryPointReg); // R10 is the arguments descriptor array.
- // Read the saved new Context pointer.
+ // Restore CTX from the saved context handle.
__ movq(CTX, Address(RBP, kNewContextOffset));
__ movq(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle));
// Read the saved arguments descriptor array to obtain the number of passed
// arguments.
- __ movq(RSI, Address(RBP, kArgumentsDescOffset));
- __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
+ __ movq(kArgDescReg, Address(RBP, kArgumentsDescOffset));
+ __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle));
__ movq(RDX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
// Get rid of arguments pushed on the stack.
__ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi.
// Load Isolate pointer from Context structure into CTX. Drop Context.
- __ movq(CTX, FieldAddress(CTX, Context::isolate_offset()));
+ __ movq(kIsolateReg, FieldAddress(CTX, Context::isolate_offset()));
// Restore the saved Context pointer into the Isolate structure.
- // Uses RCX as a temporary register for this.
- __ popq(RCX);
- __ movq(Address(CTX, Isolate::top_context_offset()), RCX);
+ __ popq(RDX);
+ __ movq(Address(kIsolateReg, Isolate::top_context_offset()), RDX);
// Restore the saved top exit frame info back into the Isolate structure.
- // Uses RDX as a temporary register for this.
__ popq(RDX);
- __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX);
+ __ movq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()), RDX);
// Restore the current VMTag from the stack.
__ popq(RDX);
- __ movq(Address(CTX, Isolate::vm_tag_offset()), RDX);
+ __ movq(Address(kIsolateReg, Isolate::vm_tag_offset()), RDX);
// Restore C++ ABI callee-saved registers.
- __ popq(R15);
- __ popq(R14);
- __ popq(R13);
- __ popq(R12);
- __ popq(RBX);
+ __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
+ CallingConventions::kCalleeSaveXmmRegisters);
// Restore the frame pointer.
__ LeaveFrame();
@@ -1005,7 +1049,8 @@ void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
__ Bind(&L);
// Setup frame, push callee-saved registers.
__ EnterCallRuntimeFrame(0);
- __ movq(RDI, FieldAddress(CTX, Context::isolate_offset()));
+ __ movq(CallingConventions::kArg1Reg,
+ FieldAddress(CTX, Context::isolate_offset()));
__ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
__ LeaveCallRuntimeFrame();
__ ret();
@@ -1667,20 +1712,30 @@ void StubCode::GenerateGetStackPointerStub(Assembler* assembler) {
// Jump to the exception or error handler.
// TOS + 0: return address
-// RDI: program counter
-// RSI: stack pointer
-// RDX: frame_pointer
-// RCX: exception object
-// R8: stacktrace object
+// Arg1: program counter
+// Arg2: stack pointer
+// Arg3: frame_pointer
+// Arg4: exception object
+// Arg5: stacktrace object
// No Result.
void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
ASSERT(kExceptionObjectReg == RAX);
ASSERT(kStackTraceObjectReg == RDX);
- __ movq(RBP, RDX); // target frame pointer.
- __ movq(kStackTraceObjectReg, R8); // stacktrace object.
- __ movq(kExceptionObjectReg, RCX); // exception object.
- __ movq(RSP, RSI); // target stack_pointer.
- __ jmp(RDI); // Jump to the exception handler code.
+ ASSERT(CallingConventions::kArg4Reg != kStackTraceObjectReg);
+ ASSERT(CallingConventions::kArg1Reg != kStackTraceObjectReg);
+
+#if defined(_WIN64)
+ Register stacktrace_reg = RBX;
+ __ movq(stacktrace_reg, Address(RSP, 5 * kWordSize));
+#else
+ Register stacktrace_reg = CallingConventions::kArg5Reg;
+#endif
+
+ __ movq(RBP, CallingConventions::kArg3Reg);
+ __ movq(RSP, CallingConventions::kArg2Reg);
+ __ movq(kStackTraceObjectReg, stacktrace_reg);
+ __ movq(kExceptionObjectReg, CallingConventions::kArg4Reg);
+ __ jmp(CallingConventions::kArg1Reg); // Jump to the exception handler code.
}
@@ -1756,8 +1811,8 @@ void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
__ j(NOT_EQUAL, &done, Assembler::kNearJump);
__ EnterFrame(0);
__ ReserveAlignedFrameSpace(0);
- __ movq(RDI, left);
- __ movq(RSI, right);
+ __ movq(CallingConventions::kArg1Reg, left);
+ __ movq(CallingConventions::kArg2Reg, right);
__ CallRuntime(kBigintCompareRuntimeEntry, 2);
// Result in RAX, 0 means equal.
__ LeaveFrame();
« no previous file with comments | « runtime/vm/stack_frame_x64.h ('k') | runtime/vm/stub_code_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698