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

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

Powered by Google App Engine
This is Rietveld 408576698