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

Side by Side Diff: runtime/vm/stub_code_arm64.cc

Issue 243773002: Adds Runtime call stub and Dart entry stub to ARM64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stack_frame_arm64.h ('k') | runtime/vm/stub_code_arm64_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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/heap.h" 13 #include "vm/heap.h"
14 #include "vm/instructions.h" 14 #include "vm/instructions.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/stack_frame.h" 16 #include "vm/stack_frame.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/tags.h" 18 #include "vm/tags.h"
19 19
20 #define __ assembler-> 20 #define __ assembler->
21 21
22 namespace dart { 22 namespace dart {
23 23
24 // Input parameters:
25 // LR : return address.
26 // SP : address of last argument in argument array.
27 // SP + 8*R4 - 8 : address of first argument in argument array.
28 // SP + 8*R4 : address of return value.
29 // R5 : address of the runtime function to call.
30 // R4 : number of arguments to the call.
24 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 31 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
25 __ Stop("GenerateCallToRuntimeStub"); 32 const intptr_t isolate_offset = NativeArguments::isolate_offset();
33 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
34 const intptr_t argv_offset = NativeArguments::argv_offset();
35 const intptr_t retval_offset = NativeArguments::retval_offset();
36 const intptr_t exitframe_last_param_slot_from_fp = 1;
37
38 __ SetPrologueOffset();
39 __ Comment("CallToRuntimeStub");
40 __ EnterFrame(0);
41
42 // Load current Isolate pointer from Context structure into A0.
43 __ LoadFieldFromOffset(R0, CTX, Context::isolate_offset());
44
45 // Save exit frame information to enable stack walking as we are about
46 // to transition to Dart VM C++ code.
47 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset());
48
49 // Save current Context pointer into Isolate structure.
50 __ StoreToOffset(CTX, R0, Isolate::top_context_offset());
51
52 // Cache Isolate pointer into CTX while executing runtime code.
53 __ mov(CTX, R0);
54
55 #if defined(DEBUG)
56 { Label ok;
57 // Check that we are always entering from Dart code.
58 __ LoadFromOffset(R8, R0, Isolate::vm_tag_offset());
59 __ CompareImmediate(R8, VMTag::kScriptTagId, kNoRegister);
60 __ b(&ok, EQ);
61 __ Stop("Not coming from Dart code.");
62 __ Bind(&ok);
63 }
64 #endif
65
66 // Mark that the isolate is executing VM code.
67 __ StoreToOffset(R5, R0, Isolate::vm_tag_offset());
68
69 // Reserve space for arguments and align frame before entering C++ world.
70 // NativeArguments are passed in registers.
71 __ Comment("align stack");
72 ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
73 __ ReserveAlignedFrameSpace(4 * kWordSize); // Reserve space for arguments.
74
75 // Pass NativeArguments structure by value and call runtime.
76 // Registers R0, R1, R2, and R3 are used.
77
78 ASSERT(isolate_offset == 0 * kWordSize);
79 // Set isolate in NativeArgs: R0 already contains CTX.
80
81 // There are no runtime calls to closures, so we do not need to set the tag
82 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
83 ASSERT(argc_tag_offset == 1 * kWordSize);
84 __ mov(R1, R4); // Set argc in NativeArguments.
85
86 ASSERT(argv_offset == 2 * kWordSize);
87 __ add(R2, ZR, Operand(R4, LSL, 3));
88 __ add(R2, FP, Operand(R2)); // Compute argv.
89 // Set argv in NativeArguments.
90 __ AddImmediate(R2, R2, exitframe_last_param_slot_from_fp * kWordSize,
91 kNoRegister);
92
93 ASSERT(retval_offset == 3 * kWordSize);
94 __ AddImmediate(R3, R2, kWordSize, kNoRegister);
95
96 // TODO(zra): Check that the ABI allows calling through this register.
97 __ blr(R5);
98
99 // Retval is next to 1st argument.
100 __ Comment("CallToRuntimeStub return");
101
102 // Mark that the isolate is executing Dart code.
103 __ LoadImmediate(R2, VMTag::kScriptTagId, kNoRegister);
104 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset());
105
106 // Reset exit frame information in Isolate structure.
107 __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset());
108
109 // Load Context pointer from Isolate structure into A2.
110 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset());
111
112 // Load null.
113 __ LoadObject(TMP, Object::null_object(), PP);
114
115 // Reset Context pointer in Isolate structure.
116 __ StoreToOffset(TMP, CTX, Isolate::top_context_offset());
117
118 // Cache Context pointer into CTX while executing Dart code.
119 __ mov(CTX, R2);
120
121 __ LeaveFrame();
122 __ ret();
26 } 123 }
27 124
28 125
29 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { 126 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
30 __ Stop("GeneratePrintStopMessageStub"); 127 __ Stop("GeneratePrintStopMessageStub");
31 } 128 }
32 129
33 130
34 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { 131 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
35 __ Stop("GenerateCallNativeCFunctionStub"); 132 __ Stop("GenerateCallNativeCFunctionStub");
(...skipping 28 matching lines...) Expand all
64 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 161 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
65 __ Stop("GenerateMegamorphicMissStub"); 162 __ Stop("GenerateMegamorphicMissStub");
66 } 163 }
67 164
68 165
69 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 166 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
70 __ Stop("GenerateAllocateArrayStub"); 167 __ Stop("GenerateAllocateArrayStub");
71 } 168 }
72 169
73 170
171 // Called when invoking Dart code from C++ (VM code).
172 // Input parameters:
173 // LR : points to return address.
174 // R0 : entrypoint of the Dart function to call.
175 // R1 : arguments descriptor array.
176 // R2 : arguments array.
177 // R3 : new context containing the current isolate pointer.
74 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 178 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
75 __ Stop("GenerateInvokeDartCodeStub"); 179 __ Comment("InvokeDartCodeStub");
180 __ EnterFrame(0);
181
182 // The new context, saved vm tag, the top exit frame, and the old context.
183 // const intptr_t kPreservedContextSlots = 4;
184 const intptr_t kNewContextOffsetFromFp =
185 -(1 + kAbiPreservedCpuRegCount) * kWordSize;
186 // const intptr_t kPreservedRegSpace =
187 // kWordSize * (kAbiPreservedCpuRegCount + kPreservedContextSlots);
188
189 // Save the callee-saved registers.
190 for (int i = R19; i <= R28; i++) {
191 const Register r = static_cast<Register>(i);
192 // We use str instead of the Push macro because we will be pushing the PP
193 // register when it is not holding a pool-pointer since we are coming from
194 // C++ code.
195 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex));
196 }
197
198 // TODO(zra): Save the bottom 64-bits of callee-saved floating point
199 // registers.
200
201 // Push new context.
202 __ Push(R3);
203
204 // We now load the pool pointer(PP) as we are about to invoke dart code and we
205 // could potentially invoke some intrinsic functions which need the PP to be
206 // set up.
207 __ LoadPoolPointer(PP);
208
209 // The new Context structure contains a pointer to the current Isolate
210 // structure. Cache the Context pointer in the CTX register so that it is
211 // available in generated code and calls to Isolate::Current() need not be
212 // done. The assumption is that this register will never be clobbered by
213 // compiled or runtime stub code.
214
215 // Cache the new Context pointer into CTX while executing Dart code.
216 __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle);
217
218 // Load Isolate pointer from Context structure into temporary register R4.
219 __ LoadFieldFromOffset(R5, CTX, Context::isolate_offset());
220
221 // Save the current VMTag on the stack.
222 ASSERT(kSavedVMTagSlotFromEntryFp == -12);
223 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset());
224 __ Push(R4);
225
226 // Mark that the isolate is executing Dart code.
227 __ LoadImmediate(R6, VMTag::kScriptTagId, PP);
228 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset());
229
230 // Save the top exit frame info. Use R6 as a temporary register.
231 // StackFrameIterator reads the top exit frame info saved in this frame.
232 __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset());
233 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset());
234
235 // Save the old Context pointer. Use R4 as a temporary register.
236 // Note that VisitObjectPointers will find this saved Context pointer during
237 // GC marking, since it traverses any information between SP and
238 // FP - kExitLinkSlotFromEntryFp.
239 // EntryFrame::SavedContext reads the context saved in this frame.
240 __ LoadFromOffset(R4, R5, Isolate::top_context_offset());
241
242 // The constants kSavedContextSlotFromEntryFp and
243 // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
244 ASSERT(kExitLinkSlotFromEntryFp == -13);
245 ASSERT(kSavedContextSlotFromEntryFp == -14);
246 __ Push(R6);
247 __ Push(R4);
248
249 // Load arguments descriptor array into R4, which is passed to Dart code.
250 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle);
251
252 // Load number of arguments into S5.
253 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset());
254 __ SmiUntag(R5);
255
256 // Compute address of 'arguments array' data area into R2.
257 __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle);
258 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag, PP);
259
260 // Set up arguments for the Dart call.
261 Label push_arguments;
262 Label done_push_arguments;
263 __ cmp(R5, Operand(0));
264 __ b(&done_push_arguments, EQ); // check if there are arguments.
265 __ LoadImmediate(R1, 0, PP);
266 __ Bind(&push_arguments);
267 __ ldr(R3, Address(R2));
268 __ Push(R3);
269 __ add(R1, R1, Operand(1));
270 __ add(R2, R2, Operand(kWordSize));
271 __ cmp(R1, Operand(R5));
272 __ b(&push_arguments, LT);
273 __ Bind(&done_push_arguments);
274
275 // Call the Dart code entrypoint.
276 __ blr(R0); // R4 is the arguments descriptor array.
277 __ Comment("InvokeDartCodeStub return");
278
279 // Read the saved new Context pointer.
280 __ LoadFromOffset(CTX, FP, kNewContextOffsetFromFp);
281 __ LoadFromOffset(CTX, CTX, VMHandles::kOffsetOfRawPtrInHandle);
282
283 // Get rid of arguments pushed on the stack.
284 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize, PP);
285
286 // Load Isolate pointer from Context structure into CTX. Drop Context.
287 __ LoadFieldFromOffset(CTX, CTX, Context::isolate_offset());
288
289 // Restore the current VMTag from the stack.
290 __ ldr(R4, Address(SP, 2 * kWordSize));
291 __ StoreToOffset(R4, CTX, Isolate::vm_tag_offset());
292
293 // Restore the saved Context pointer into the Isolate structure.
294 // Uses R4 as a temporary register for this.
295 // Restore the saved top exit frame info back into the Isolate structure.
296 // Uses R6 as a temporary register for this.
297 __ Pop(R4);
298 __ Pop(R6);
299 __ StoreToOffset(R4, CTX, Isolate::top_context_offset());
300 __ StoreToOffset(R6, CTX, Isolate::top_exit_frame_info_offset());
301
302 __ Pop(R3);
303 __ Pop(R4);
304
305 // Restore C++ ABI callee-saved registers.
306 for (int i = R28; i >= R19; i--) {
307 Register r = static_cast<Register>(i);
308 // We use ldr instead of the Pop macro because we will be popping the PP
309 // register when it is not holding a pool-pointer since we are returning to
310 // C++ code.
311 __ ldr(r, Address(SP, 1 * kWordSize, Address::PostIndex));
312 }
313
314 // TODO(zra): Restore callee-saved fpu registers.
315
316 // Restore the frame pointer and return.
317 __ LeaveFrame();
318 __ ret();
76 } 319 }
77 320
78 321
79 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 322 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
80 __ Stop("GenerateAllocateContextStub"); 323 __ Stop("GenerateAllocateContextStub");
81 } 324 }
82 325
83 326
84 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { 327 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
85 __ Stop("GenerateUpdateStoreBufferStub"); 328 __ Stop("GenerateUpdateStoreBufferStub");
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 473
231 474
232 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( 475 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
233 Assembler* assembler) { 476 Assembler* assembler) {
234 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub"); 477 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub");
235 } 478 }
236 479
237 } // namespace dart 480 } // namespace dart
238 481
239 #endif // defined TARGET_ARCH_ARM64 482 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/stack_frame_arm64.h ('k') | runtime/vm/stub_code_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698