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

Unified Diff: runtime/vm/stub_code_x64.cc

Issue 8818001: Add 64-bit stubs to call into the runtime and to call native functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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/stub_code_ia32_test.cc ('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
===================================================================
--- runtime/vm/stub_code_x64.cc (revision 2205)
+++ runtime/vm/stub_code_x64.cc (working copy)
@@ -5,34 +5,165 @@
#include "vm/globals.h"
#if defined(TARGET_ARCH_X64)
+#include "vm/native_entry.h"
#include "vm/stub_code.h"
#define __ assembler->
namespace dart {
+// Input parameters:
+// RSP : points to return address.
+// RSP + 8 : address of last argument in argument array.
+// RSP + 8*R10 : address of first argument in argument array.
+// RSP + 8*R10 + 8 : address of return value.
+// RBX : address of the runtime function to call.
+// R10 : number of arguments to the call.
+static void GenerateCallRuntimeStub(Assembler* assembler) {
+ const intptr_t isolate_offset = NativeArguments::isolate_offset();
+ const intptr_t argc_offset = NativeArguments::argc_offset();
+ const intptr_t argv_offset = NativeArguments::argv_offset();
+ const intptr_t retval_offset = NativeArguments::retval_offset();
+
+ __ EnterFrame(0);
+
+ // Load current Isolate pointer from Context structure into RAX.
+ __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
+
+ // Save exit frame information to enable stack walking as we are about
+ // to transition to Dart VM C++ code.
+ __ movq(Address(RAX, Isolate::top_exit_frame_info_offset()), RSP);
+
+ // Save current Context pointer into Isolate structure.
+ __ movq(Address(RAX, Isolate::top_context_offset()), CTX);
+
+ // Cache Isolate pointer into CTX while executing runtime code.
+ __ movq(CTX, RAX);
+
+ // Reserve space for arguments and align frame before entering C++ world.
+ __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+ if (OS::ActivationFrameAlignment() > 0) {
+ __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+ }
+
+ // Pass NativeArguments structure by value and call runtime.
+ __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs.
+ __ movq(Address(RSP, argc_offset), R10); // Set argc in NativeArguments.
+ __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv.
+ __ 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);
+
+ // Reset exit frame information in Isolate structure.
+ __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
+
+ // Load Context pointer from Isolate structure into RBX.
+ __ movq(RBX, Address(CTX, Isolate::top_context_offset()));
+
+ // Reset Context pointer in Isolate structure.
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ __ movq(Address(CTX, Isolate::top_context_offset()), raw_null);
+
+ // Cache Context pointer into CTX while executing Dart code.
+ __ movq(CTX, RBX);
+
+ __ LeaveFrame();
+ __ ret();
+}
+
+
+// Input parameters:
+// RSP : points to return address.
+// RSP + 8 : address of last argument in argument array.
+// RSP + 8*R10 : address of first argument in argument array.
+// RSP + 8*R10 + 8 : address of return value.
+// RBX : address of the runtime function to call.
+// R10 : number of arguments to the call.
void StubCode::GenerateDartCallToRuntimeStub(Assembler* assembler) {
- __ Unimplemented("DartCallToRuntime stub");
+ GenerateCallRuntimeStub(assembler);
}
+// Input parameters:
+// RSP : points to return address.
+// RSP + 8 : address of last argument in argument array.
+// RSP + 8*R10 : address of first argument in argument array.
+// RSP + 8*R10 + 8 : address of return value.
+// RBX : address of the runtime function to call.
+// R10 : number of arguments to the call.
void StubCode::GenerateStubCallToRuntimeStub(Assembler* assembler) {
- __ Unimplemented("StubCallToRuntime stub");
+ GenerateCallRuntimeStub(assembler);
}
+// Input parameters:
+// RSP : points to return address.
+// RSP + 8 : address of return value.
+// RAX : address of first argument in argument array.
+// RAX - 8*R10 + 8 : address of last argument in argument array.
+// RBX : address of the native function to call.
+// R10 : number of arguments to the call.
void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
- __ Unimplemented("CallNativeCFunction stub");
-}
+ const intptr_t native_args_struct_offset = 0;
+ const intptr_t isolate_offset =
+ NativeArguments::isolate_offset() + native_args_struct_offset;
+ const intptr_t argc_offset =
+ NativeArguments::argc_offset() + native_args_struct_offset;
+ const intptr_t argv_offset =
+ NativeArguments::argv_offset() + native_args_struct_offset;
+ const intptr_t retval_offset =
+ NativeArguments::retval_offset() + native_args_struct_offset;
+ __ EnterFrame(0);
-void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
- __ Unimplemented("CallNoSuchMethodFunction stub");
-}
+ // Load current Isolate pointer from Context structure into R8.
+ __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
+ // Save exit frame information to enable stack walking as we are about
+ // to transition to native code.
+ __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), RSP);
-void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
- __ Unimplemented("InvokeDartCode stub");
+ // Save current Context pointer into Isolate structure.
+ __ movq(Address(R8, Isolate::top_context_offset()), CTX);
+
+ // Cache Isolate pointer into CTX while executing native code.
+ __ movq(CTX, R8);
+
+ // Reserve space for the native arguments structure passed on the stack (the
+ // outgoing pointer parameter to the native arguments structure is passed in
+ // RDI) and align frame before entering the C++ world.
+ __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+ if (OS::ActivationFrameAlignment() > 0) {
+ __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+ }
+
+ // Pass NativeArguments structure by value and call native function.
+ __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs.
+ __ movq(Address(RSP, argc_offset), R10); // Set argc in NativeArguments.
+ __ 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);
+
+ // Reset exit frame information in Isolate structure.
+ __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
+
+ // Load Context pointer from Isolate structure into R8.
+ __ movq(R8, Address(CTX, Isolate::top_context_offset()));
+
+ // Reset Context pointer in Isolate structure.
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ __ movq(Address(CTX, Isolate::top_context_offset()), raw_null);
+
+ // Cache Context pointer into CTX while executing Dart code.
+ __ movq(CTX, R8);
+
+ __ LeaveFrame();
+ __ ret();
}
@@ -41,16 +172,157 @@
}
+void StubCode::GenerateStackOverflowStub(Assembler* assembler) {
+ __ Unimplemented("StackOverflow stub");
+}
+
+
+void StubCode::GenerateOptimizeInvokedFunctionStub(Assembler* assembler) {
+ __ Unimplemented("OptimizeInvokedFunction stub");
+}
+
+
+void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
+ __ Unimplemented("FixCallersTarget stub");
+}
+
+
void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
__ Unimplemented("MegamorphicLookup stub");
}
+void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
+ __ Unimplemented("Deoptimize stub");
+}
+
+
+void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
+ __ Unimplemented("AllocateArray stub");
+}
+
+
void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
__ Unimplemented("CallClosureFunction stub");
}
+// Called when invoking Dart code from C++ (VM code).
+// Input parameters:
+// RSP : points to return address.
+// RDI : entrypoint of the Dart function to call.
+// RSI : arguments descriptor array.
+// RDX : pointer to the argument array.
+// RCX : new context containing the current isolate pointer.
+void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
+ // Save frame pointer coming in.
+ __ EnterFrame(0);
+
+ // Save arguments descriptor array and new context.
+ const intptr_t kArgumentsDescOffset = -1 * kWordSize;
+ __ pushq(RSI);
+ const intptr_t kNewContextOffset = -2 * kWordSize;
+ __ pushq(RCX);
+
+ // Save C++ ABI callee-saved registers.
+ __ pushq(RBX);
+ __ pushq(R12);
+ __ pushq(R13);
+ __ pushq(R14);
+ __ pushq(R15);
+
+ // The new Context structure contains a pointer to the current Isolate
+ // structure. Cache the Context pointer in the CTX register so that it is
+ // available in generated code and calls to Isolate::Current() need not be
+ // done. The assumption is that this register will never be clobbered by
+ // compiled or runtime stub code.
+
+ // Cache the new Context pointer into CTX while executing Dart code.
+ __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
+
+ // Load Isolate pointer from Context structure into R8.
+ __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
+
+ // Save the top exit frame info. Use RAX as a temporary register.
+ __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset()));
+ __ pushq(RAX);
+ __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0));
+
+ // StackFrameIterator reads the top exit frame info saved in this frame.
+ // The constant kExitLinkOffsetInEntryFrame must be kept in sync with the
+ // code above: kExitLinkOffsetInEntryFrame = -8 * kWordSize.
+
+ // Save the old Context pointer. Use RAX as a temporary register.
+ // Note that VisitObjectPointers will find this saved Context pointer during
+ // GC marking, since it traverses any information between SP and
+ // FP - kExitLinkOffsetInEntryFrame.
+ __ movq(RAX, Address(R8, Isolate::top_context_offset()));
+ __ pushq(RAX);
+
+ // Load arguments descriptor array into R10, which is passed to Dart code.
+ __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
+
+ // Load number of arguments into RBX.
+ __ movq(RBX, FieldAddress(R10, Array::data_offset()));
+ __ SmiUntag(RBX);
+
+ // Set up arguments for the Dart call.
+ Label push_arguments;
+ Label done_push_arguments;
+ __ testq(RBX, RBX); // check if there are arguments.
+ __ 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.
+ __ movq(RCX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
+ __ pushq(RCX);
+ __ 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.
+
+ // Read the saved new Context pointer.
+ __ movq(CTX, Address(RBP, kNewContextOffset));
+ __ movq(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle));
+
+ // Read the saved arguments descriptor array to obtain the number of passed
+ // arguments, which is the first element of the array, a Smi.
+ __ movq(RSI, Address(RBP, kArgumentsDescOffset));
+ __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
+ __ movq(RDX, FieldAddress(R10, Array::data_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()));
+
+ // 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);
+
+ // 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);
+
+ // Restore C++ ABI callee-saved registers.
+ __ popq(R15);
+ __ popq(R14);
+ __ popq(R13);
+ __ popq(R12);
+ __ popq(RBX);
+
+ // Restore the frame pointer.
+ __ LeaveFrame();
+
+ __ ret();
+}
+
+
void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
__ Unimplemented("AllocateContext stub");
}
@@ -67,6 +339,26 @@
__ Unimplemented("AllocateClosure stub");
}
+
+void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
+ __ Unimplemented("CallNoSuchMethodFunction stub");
+}
+
+
+void StubCode::GenerateInlineCacheStub(Assembler* assembler) {
+ __ Unimplemented("InlineCache stub");
+}
+
+
+void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
+ __ Unimplemented("BreakpointStatic stub");
+}
+
+
+void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
+ __ Unimplemented("BreakpointDynamic stub");
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_X64
« no previous file with comments | « runtime/vm/stub_code_ia32_test.cc ('k') | runtime/vm/stub_code_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698