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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/native_entry.h"
8 #include "vm/stub_code.h" 9 #include "vm/stub_code.h"
9 10
10 #define __ assembler-> 11 #define __ assembler->
11 12
12 namespace dart { 13 namespace dart {
13 14
14 void StubCode::GenerateDartCallToRuntimeStub(Assembler* assembler) { 15 // Input parameters:
15 __ Unimplemented("DartCallToRuntime stub"); 16 // RSP : points to return address.
17 // RSP + 8 : address of last argument in argument array.
18 // RSP + 8*R10 : address of first argument in argument array.
19 // RSP + 8*R10 + 8 : address of return value.
20 // RBX : address of the runtime function to call.
21 // R10 : number of arguments to the call.
22 static void GenerateCallRuntimeStub(Assembler* assembler) {
23 const intptr_t isolate_offset = NativeArguments::isolate_offset();
24 const intptr_t argc_offset = NativeArguments::argc_offset();
25 const intptr_t argv_offset = NativeArguments::argv_offset();
26 const intptr_t retval_offset = NativeArguments::retval_offset();
27
28 __ EnterFrame(0);
29
30 // Load current Isolate pointer from Context structure into RAX.
31 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
32
33 // Save exit frame information to enable stack walking as we are about
34 // to transition to Dart VM C++ code.
35 __ movq(Address(RAX, Isolate::top_exit_frame_info_offset()), RSP);
36
37 // Save current Context pointer into Isolate structure.
38 __ movq(Address(RAX, Isolate::top_context_offset()), CTX);
39
40 // Cache Isolate pointer into CTX while executing runtime code.
41 __ movq(CTX, RAX);
42
43 // Reserve space for arguments and align frame before entering C++ world.
44 __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
45 if (OS::ActivationFrameAlignment() > 0) {
46 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
47 }
48
49 // Pass NativeArguments structure by value and call runtime.
50 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs.
51 __ movq(Address(RSP, argc_offset), R10); // Set argc in NativeArguments.
52 __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv.
53 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments.
54 __ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument.
55 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments.
56 __ call(RBX);
57
58 // Reset exit frame information in Isolate structure.
59 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
60
61 // Load Context pointer from Isolate structure into RBX.
62 __ movq(RBX, Address(CTX, Isolate::top_context_offset()));
63
64 // Reset Context pointer in Isolate structure.
65 const Immediate raw_null =
66 Immediate(reinterpret_cast<intptr_t>(Object::null()));
67 __ movq(Address(CTX, Isolate::top_context_offset()), raw_null);
68
69 // Cache Context pointer into CTX while executing Dart code.
70 __ movq(CTX, RBX);
71
72 __ LeaveFrame();
73 __ ret();
16 } 74 }
17 75
18 76
19 void StubCode::GenerateStubCallToRuntimeStub(Assembler* assembler) { 77 // Input parameters:
20 __ Unimplemented("StubCallToRuntime stub"); 78 // RSP : points to return address.
79 // RSP + 8 : address of last argument in argument array.
80 // RSP + 8*R10 : address of first argument in argument array.
81 // RSP + 8*R10 + 8 : address of return value.
82 // RBX : address of the runtime function to call.
83 // R10 : number of arguments to the call.
84 void StubCode::GenerateDartCallToRuntimeStub(Assembler* assembler) {
85 GenerateCallRuntimeStub(assembler);
21 } 86 }
22 87
23 88
24 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { 89 // Input parameters:
25 __ Unimplemented("CallNativeCFunction stub"); 90 // RSP : points to return address.
91 // RSP + 8 : address of last argument in argument array.
92 // RSP + 8*R10 : address of first argument in argument array.
93 // RSP + 8*R10 + 8 : address of return value.
94 // RBX : address of the runtime function to call.
95 // R10 : number of arguments to the call.
96 void StubCode::GenerateStubCallToRuntimeStub(Assembler* assembler) {
97 GenerateCallRuntimeStub(assembler);
26 } 98 }
27 99
28 100
29 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 101 // Input parameters:
30 __ Unimplemented("CallNoSuchMethodFunction stub"); 102 // RSP : points to return address.
103 // RSP + 8 : address of return value.
104 // RAX : address of first argument in argument array.
105 // RAX - 8*R10 + 8 : address of last argument in argument array.
106 // RBX : address of the native function to call.
107 // R10 : number of arguments to the call.
108 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
109 const intptr_t native_args_struct_offset = 0;
110 const intptr_t isolate_offset =
111 NativeArguments::isolate_offset() + native_args_struct_offset;
112 const intptr_t argc_offset =
113 NativeArguments::argc_offset() + native_args_struct_offset;
114 const intptr_t argv_offset =
115 NativeArguments::argv_offset() + native_args_struct_offset;
116 const intptr_t retval_offset =
117 NativeArguments::retval_offset() + native_args_struct_offset;
118
119 __ EnterFrame(0);
120
121 // Load current Isolate pointer from Context structure into R8.
122 __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
123
124 // Save exit frame information to enable stack walking as we are about
125 // to transition to native code.
126 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), RSP);
127
128 // Save current Context pointer into Isolate structure.
129 __ movq(Address(R8, Isolate::top_context_offset()), CTX);
130
131 // Cache Isolate pointer into CTX while executing native code.
132 __ movq(CTX, R8);
133
134 // Reserve space for the native arguments structure passed on the stack (the
135 // outgoing pointer parameter to the native arguments structure is passed in
136 // RDI) and align frame before entering the C++ world.
137 __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
138 if (OS::ActivationFrameAlignment() > 0) {
139 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
140 }
141
142 // Pass NativeArguments structure by value and call native function.
143 __ movq(Address(RSP, isolate_offset), CTX); // Set isolate in NativeArgs.
144 __ movq(Address(RSP, argc_offset), R10); // Set argc in NativeArguments.
145 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments.
146 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr.
147 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments.
148 __ movq(RDI, RSP); // Pass the pointer to the NativeArguments.
149 __ call(RBX);
150
151 // Reset exit frame information in Isolate structure.
152 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
153
154 // Load Context pointer from Isolate structure into R8.
155 __ movq(R8, Address(CTX, Isolate::top_context_offset()));
156
157 // Reset Context pointer in Isolate structure.
158 const Immediate raw_null =
159 Immediate(reinterpret_cast<intptr_t>(Object::null()));
160 __ movq(Address(CTX, Isolate::top_context_offset()), raw_null);
161
162 // Cache Context pointer into CTX while executing Dart code.
163 __ movq(CTX, R8);
164
165 __ LeaveFrame();
166 __ ret();
31 } 167 }
32 168
33 169
34 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
35 __ Unimplemented("InvokeDartCode stub");
36 }
37
38
39 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { 170 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
40 __ Unimplemented("CallStaticFunction stub"); 171 __ Unimplemented("CallStaticFunction stub");
41 } 172 }
42 173
43 174
175 void StubCode::GenerateStackOverflowStub(Assembler* assembler) {
176 __ Unimplemented("StackOverflow stub");
177 }
178
179
180 void StubCode::GenerateOptimizeInvokedFunctionStub(Assembler* assembler) {
181 __ Unimplemented("OptimizeInvokedFunction stub");
182 }
183
184
185 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
186 __ Unimplemented("FixCallersTarget stub");
187 }
188
189
44 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 190 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
45 __ Unimplemented("MegamorphicLookup stub"); 191 __ Unimplemented("MegamorphicLookup stub");
46 } 192 }
47 193
48 194
195 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
196 __ Unimplemented("Deoptimize stub");
197 }
198
199
200 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
201 __ Unimplemented("AllocateArray stub");
202 }
203
204
49 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 205 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
50 __ Unimplemented("CallClosureFunction stub"); 206 __ Unimplemented("CallClosureFunction stub");
51 } 207 }
52 208
53 209
210 // Called when invoking Dart code from C++ (VM code).
211 // Input parameters:
212 // RSP : points to return address.
213 // RDI : entrypoint of the Dart function to call.
214 // RSI : arguments descriptor array.
215 // RDX : pointer to the argument array.
216 // RCX : new context containing the current isolate pointer.
217 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
218 // Save frame pointer coming in.
219 __ EnterFrame(0);
220
221 // Save arguments descriptor array and new context.
222 const intptr_t kArgumentsDescOffset = -1 * kWordSize;
223 __ pushq(RSI);
224 const intptr_t kNewContextOffset = -2 * kWordSize;
225 __ pushq(RCX);
226
227 // Save C++ ABI callee-saved registers.
228 __ pushq(RBX);
229 __ pushq(R12);
230 __ pushq(R13);
231 __ pushq(R14);
232 __ pushq(R15);
233
234 // The new Context structure contains a pointer to the current Isolate
235 // structure. Cache the Context pointer in the CTX register so that it is
236 // available in generated code and calls to Isolate::Current() need not be
237 // done. The assumption is that this register will never be clobbered by
238 // compiled or runtime stub code.
239
240 // Cache the new Context pointer into CTX while executing Dart code.
241 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
242
243 // Load Isolate pointer from Context structure into R8.
244 __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
245
246 // Save the top exit frame info. Use RAX as a temporary register.
247 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset()));
248 __ pushq(RAX);
249 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0));
250
251 // StackFrameIterator reads the top exit frame info saved in this frame.
252 // The constant kExitLinkOffsetInEntryFrame must be kept in sync with the
253 // code above: kExitLinkOffsetInEntryFrame = -8 * kWordSize.
254
255 // Save the old Context pointer. Use RAX as a temporary register.
256 // Note that VisitObjectPointers will find this saved Context pointer during
257 // GC marking, since it traverses any information between SP and
258 // FP - kExitLinkOffsetInEntryFrame.
259 __ movq(RAX, Address(R8, Isolate::top_context_offset()));
260 __ pushq(RAX);
261
262 // Load arguments descriptor array into R10, which is passed to Dart code.
263 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
264
265 // Load number of arguments into RBX.
266 __ movq(RBX, FieldAddress(R10, Array::data_offset()));
267 __ SmiUntag(RBX);
268
269 // Set up arguments for the Dart call.
270 Label push_arguments;
271 Label done_push_arguments;
272 __ testq(RBX, RBX); // check if there are arguments.
273 __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
274 __ movq(RAX, Immediate(0));
275 __ Bind(&push_arguments);
276 __ movq(RCX, Address(RDX, RAX, TIMES_8, 0)); // RDX is start of arguments.
277 __ movq(RCX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
278 __ pushq(RCX);
279 __ incq(RAX);
280 __ cmpq(RAX, RBX);
281 __ j(LESS, &push_arguments, Assembler::kNearJump);
282 __ Bind(&done_push_arguments);
283
284 // Call the Dart code entrypoint.
285 __ call(RDI); // R10 is the arguments descriptor array.
286
287 // Read the saved new Context pointer.
288 __ movq(CTX, Address(RBP, kNewContextOffset));
289 __ movq(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle));
290
291 // Read the saved arguments descriptor array to obtain the number of passed
292 // arguments, which is the first element of the array, a Smi.
293 __ movq(RSI, Address(RBP, kArgumentsDescOffset));
294 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
295 __ movq(RDX, FieldAddress(R10, Array::data_offset()));
296 // Get rid of arguments pushed on the stack.
297 __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi.
298
299 // Load Isolate pointer from Context structure into CTX. Drop Context.
300 __ movq(CTX, FieldAddress(CTX, Context::isolate_offset()));
301
302 // Restore the saved Context pointer into the Isolate structure.
303 // Uses RCX as a temporary register for this.
304 __ popq(RCX);
305 __ movq(Address(CTX, Isolate::top_context_offset()), RCX);
306
307 // Restore the saved top exit frame info back into the Isolate structure.
308 // Uses RDX as a temporary register for this.
309 __ popq(RDX);
310 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX);
311
312 // Restore C++ ABI callee-saved registers.
313 __ popq(R15);
314 __ popq(R14);
315 __ popq(R13);
316 __ popq(R12);
317 __ popq(RBX);
318
319 // Restore the frame pointer.
320 __ LeaveFrame();
321
322 __ ret();
323 }
324
325
54 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 326 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
55 __ Unimplemented("AllocateContext stub"); 327 __ Unimplemented("AllocateContext stub");
56 } 328 }
57 329
58 330
59 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 331 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
60 const Class& cls) { 332 const Class& cls) {
61 __ Unimplemented("AllocateObject stub"); 333 __ Unimplemented("AllocateObject stub");
62 } 334 }
63 335
64 336
65 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 337 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
66 const Function& func) { 338 const Function& func) {
67 __ Unimplemented("AllocateClosure stub"); 339 __ Unimplemented("AllocateClosure stub");
68 } 340 }
69 341
342
343 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
344 __ Unimplemented("CallNoSuchMethodFunction stub");
345 }
346
347
348 void StubCode::GenerateInlineCacheStub(Assembler* assembler) {
349 __ Unimplemented("InlineCache stub");
350 }
351
352
353 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
354 __ Unimplemented("BreakpointStatic stub");
355 }
356
357
358 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
359 __ Unimplemented("BreakpointDynamic stub");
360 }
361
70 } // namespace dart 362 } // namespace dart
71 363
72 #endif // defined TARGET_ARCH_X64 364 #endif // defined TARGET_ARCH_X64
OLDNEW
« 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