OLD | NEW |
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" |
(...skipping 26 matching lines...) Expand all Loading... |
37 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 37 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
38 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 38 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
39 const intptr_t argv_offset = NativeArguments::argv_offset(); | 39 const intptr_t argv_offset = NativeArguments::argv_offset(); |
40 const intptr_t retval_offset = NativeArguments::retval_offset(); | 40 const intptr_t retval_offset = NativeArguments::retval_offset(); |
41 const intptr_t exitframe_last_param_slot_from_fp = 1; | 41 const intptr_t exitframe_last_param_slot_from_fp = 1; |
42 | 42 |
43 __ SetPrologueOffset(); | 43 __ SetPrologueOffset(); |
44 __ Comment("CallToRuntimeStub"); | 44 __ Comment("CallToRuntimeStub"); |
45 __ EnterFrame(0); | 45 __ EnterFrame(0); |
46 | 46 |
47 __ LoadIsolate(R0, kNoPP); | 47 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 48 __ LoadIsolate(R28, kNoPP); |
48 | 49 |
49 // Save exit frame information to enable stack walking as we are about | 50 // Save exit frame information to enable stack walking as we are about |
50 // to transition to Dart VM C++ code. | 51 // to transition to Dart VM C++ code. |
51 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP); | 52 __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
52 | |
53 // Save current Context pointer into Isolate structure. | |
54 __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP); | |
55 | |
56 // Cache Isolate pointer into CTX while executing runtime code. | |
57 __ mov(CTX, R0); | |
58 | 53 |
59 #if defined(DEBUG) | 54 #if defined(DEBUG) |
60 { Label ok; | 55 { Label ok; |
61 // Check that we are always entering from Dart code. | 56 // Check that we are always entering from Dart code. |
62 __ LoadFromOffset(R8, R0, Isolate::vm_tag_offset(), kNoPP); | 57 __ LoadFromOffset(R8, R28, Isolate::vm_tag_offset(), kNoPP); |
63 __ CompareImmediate(R8, VMTag::kDartTagId, kNoPP); | 58 __ CompareImmediate(R8, VMTag::kDartTagId, kNoPP); |
64 __ b(&ok, EQ); | 59 __ b(&ok, EQ); |
65 __ Stop("Not coming from Dart code."); | 60 __ Stop("Not coming from Dart code."); |
66 __ Bind(&ok); | 61 __ Bind(&ok); |
67 } | 62 } |
68 #endif | 63 #endif |
69 | 64 |
70 // Mark that the isolate is executing VM code. | 65 // Mark that the isolate is executing VM code. |
71 __ StoreToOffset(R5, R0, Isolate::vm_tag_offset(), kNoPP); | 66 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
72 | 67 |
73 // Reserve space for arguments and align frame before entering C++ world. | 68 // Reserve space for arguments and align frame before entering C++ world. |
74 // NativeArguments are passed in registers. | 69 // NativeArguments are passed in registers. |
75 __ Comment("align stack"); | 70 __ Comment("align stack"); |
76 // Reserve space for arguments. | 71 // Reserve space for arguments. |
77 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 72 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
78 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 73 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
79 | 74 |
80 // Pass NativeArguments structure by value and call runtime. | 75 // Pass NativeArguments structure by value and call runtime. |
81 // Registers R0, R1, R2, and R3 are used. | 76 // Registers R0, R1, R2, and R3 are used. |
82 | 77 |
83 ASSERT(isolate_offset == 0 * kWordSize); | 78 ASSERT(isolate_offset == 0 * kWordSize); |
84 // Set isolate in NativeArgs: R0 already contains CTX. | 79 // Set isolate in NativeArgs. |
| 80 __ mov(R0, R28); |
85 | 81 |
86 // There are no runtime calls to closures, so we do not need to set the tag | 82 // There are no runtime calls to closures, so we do not need to set the tag |
87 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 83 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
88 ASSERT(argc_tag_offset == 1 * kWordSize); | 84 ASSERT(argc_tag_offset == 1 * kWordSize); |
89 __ mov(R1, R4); // Set argc in NativeArguments. | 85 __ mov(R1, R4); // Set argc in NativeArguments. |
90 | 86 |
91 ASSERT(argv_offset == 2 * kWordSize); | 87 ASSERT(argv_offset == 2 * kWordSize); |
92 __ add(R2, ZR, Operand(R4, LSL, 3)); | 88 __ add(R2, ZR, Operand(R4, LSL, 3)); |
93 __ add(R2, FP, Operand(R2)); // Compute argv. | 89 __ add(R2, FP, Operand(R2)); // Compute argv. |
94 // Set argv in NativeArguments. | 90 // Set argv in NativeArguments. |
(...skipping 17 matching lines...) Expand all Loading... |
112 __ blr(R5); | 108 __ blr(R5); |
113 __ Comment("CallToRuntimeStub return"); | 109 __ Comment("CallToRuntimeStub return"); |
114 | 110 |
115 // Restore SP and CSP. | 111 // Restore SP and CSP. |
116 __ mov(SP, CSP); | 112 __ mov(SP, CSP); |
117 __ mov(CSP, R26); | 113 __ mov(CSP, R26); |
118 | 114 |
119 // Retval is next to 1st argument. | 115 // Retval is next to 1st argument. |
120 // Mark that the isolate is executing Dart code. | 116 // Mark that the isolate is executing Dart code. |
121 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 117 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
122 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP); | 118 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
123 | 119 |
124 // Reset exit frame information in Isolate structure. | 120 // Reset exit frame information in Isolate structure. |
125 __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP); | 121 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
126 | |
127 // Load Context pointer from Isolate structure into A2. | |
128 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP); | |
129 | |
130 // Load null. | |
131 __ LoadObject(TMP, Object::null_object(), PP); | |
132 | |
133 // Reset Context pointer in Isolate structure. | |
134 __ StoreToOffset(TMP, CTX, Isolate::top_context_offset(), kNoPP); | |
135 | |
136 // Cache Context pointer into CTX while executing Dart code. | |
137 __ mov(CTX, R2); | |
138 | 122 |
139 __ LeaveFrame(); | 123 __ LeaveFrame(); |
140 __ ret(); | 124 __ ret(); |
141 } | 125 } |
142 | 126 |
143 | 127 |
144 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 128 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
145 __ Stop("GeneratePrintStopMessageStub"); | 129 __ Stop("GeneratePrintStopMessageStub"); |
146 } | 130 } |
147 | 131 |
148 | 132 |
149 // Input parameters: | 133 // Input parameters: |
150 // LR : return address. | 134 // LR : return address. |
151 // SP : address of return value. | 135 // SP : address of return value. |
152 // R5 : address of the native function to call. | 136 // R5 : address of the native function to call. |
153 // R2 : address of first argument in argument array. | 137 // R2 : address of first argument in argument array. |
154 // R1 : argc_tag including number of arguments and function kind. | 138 // R1 : argc_tag including number of arguments and function kind. |
155 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 139 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
156 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 140 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
157 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 141 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
158 const intptr_t argv_offset = NativeArguments::argv_offset(); | 142 const intptr_t argv_offset = NativeArguments::argv_offset(); |
159 const intptr_t retval_offset = NativeArguments::retval_offset(); | 143 const intptr_t retval_offset = NativeArguments::retval_offset(); |
160 | 144 |
161 __ EnterFrame(0); | 145 __ EnterFrame(0); |
162 | 146 |
163 __ LoadIsolate(R0, kNoPP); | 147 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 148 __ LoadIsolate(R28, kNoPP); |
164 | 149 |
165 // Save exit frame information to enable stack walking as we are about | 150 // Save exit frame information to enable stack walking as we are about |
166 // to transition to native code. | 151 // to transition to native code. |
167 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP); | 152 __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
168 | |
169 // Save current Context pointer into Isolate structure. | |
170 __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP); | |
171 | |
172 // Cache Isolate pointer into CTX while executing native code. | |
173 __ mov(CTX, R0); | |
174 | 153 |
175 #if defined(DEBUG) | 154 #if defined(DEBUG) |
176 { Label ok; | 155 { Label ok; |
177 // Check that we are always entering from Dart code. | 156 // Check that we are always entering from Dart code. |
178 __ LoadFromOffset(R6, CTX, Isolate::vm_tag_offset(), kNoPP); | 157 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); |
179 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); | 158 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); |
180 __ b(&ok, EQ); | 159 __ b(&ok, EQ); |
181 __ Stop("Not coming from Dart code."); | 160 __ Stop("Not coming from Dart code."); |
182 __ Bind(&ok); | 161 __ Bind(&ok); |
183 } | 162 } |
184 #endif | 163 #endif |
185 | 164 |
186 // Mark that the isolate is executing Native code. | 165 // Mark that the isolate is executing Native code. |
187 __ StoreToOffset(R5, CTX, Isolate::vm_tag_offset(), kNoPP); | 166 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
188 | 167 |
189 // Reserve space for the native arguments structure passed on the stack (the | 168 // Reserve space for the native arguments structure passed on the stack (the |
190 // outgoing pointer parameter to the native arguments structure is passed in | 169 // outgoing pointer parameter to the native arguments structure is passed in |
191 // R0) and align frame before entering the C++ world. | 170 // R0) and align frame before entering the C++ world. |
192 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 171 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
193 | 172 |
194 // Initialize NativeArguments structure and call native function. | 173 // Initialize NativeArguments structure and call native function. |
195 // Registers R0, R1, R2, and R3 are used. | 174 // Registers R0, R1, R2, and R3 are used. |
196 | 175 |
197 ASSERT(isolate_offset == 0 * kWordSize); | 176 ASSERT(isolate_offset == 0 * kWordSize); |
198 // Set isolate in NativeArgs: R0 already contains CTX. | 177 // Set isolate in NativeArgs. |
| 178 __ mov(R0, R28); |
199 | 179 |
200 // There are no native calls to closures, so we do not need to set the tag | 180 // There are no native calls to closures, so we do not need to set the tag |
201 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 181 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
202 ASSERT(argc_tag_offset == 1 * kWordSize); | 182 ASSERT(argc_tag_offset == 1 * kWordSize); |
203 // Set argc in NativeArguments: R1 already contains argc. | 183 // Set argc in NativeArguments: R1 already contains argc. |
204 | 184 |
205 ASSERT(argv_offset == 2 * kWordSize); | 185 ASSERT(argv_offset == 2 * kWordSize); |
206 // Set argv in NativeArguments: R2 already contains argv. | 186 // Set argv in NativeArguments: R2 already contains argv. |
207 | 187 |
208 // Set retval in NativeArgs. | 188 // Set retval in NativeArgs. |
(...skipping 26 matching lines...) Expand all Loading... |
235 #else | 215 #else |
236 __ BranchLink(&NativeEntry::NativeCallWrapperLabel(), kNoPP); | 216 __ BranchLink(&NativeEntry::NativeCallWrapperLabel(), kNoPP); |
237 #endif | 217 #endif |
238 | 218 |
239 // Restore SP and CSP. | 219 // Restore SP and CSP. |
240 __ mov(SP, CSP); | 220 __ mov(SP, CSP); |
241 __ mov(CSP, R26); | 221 __ mov(CSP, R26); |
242 | 222 |
243 // Mark that the isolate is executing Dart code. | 223 // Mark that the isolate is executing Dart code. |
244 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 224 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
245 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP); | 225 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
246 | 226 |
247 // Reset exit frame information in Isolate structure. | 227 // Reset exit frame information in Isolate structure. |
248 __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP); | 228 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
249 | |
250 // Load Context pointer from Isolate structure into R2. | |
251 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP); | |
252 | |
253 // Reset Context pointer in Isolate structure. | |
254 __ LoadObject(R3, Object::null_object(), PP); | |
255 __ StoreToOffset(R3, CTX, Isolate::top_context_offset(), kNoPP); | |
256 | |
257 // Cache Context pointer into CTX while executing Dart code. | |
258 __ mov(CTX, R2); | |
259 | 229 |
260 __ LeaveFrame(); | 230 __ LeaveFrame(); |
261 __ ret(); | 231 __ ret(); |
262 } | 232 } |
263 | 233 |
264 | 234 |
265 // Input parameters: | 235 // Input parameters: |
266 // LR : return address. | 236 // LR : return address. |
267 // SP : address of return value. | 237 // SP : address of return value. |
268 // R5 : address of the native function to call. | 238 // R5 : address of the native function to call. |
269 // R2 : address of first argument in argument array. | 239 // R2 : address of first argument in argument array. |
270 // R1 : argc_tag including number of arguments and function kind. | 240 // R1 : argc_tag including number of arguments and function kind. |
271 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 241 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
272 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 242 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
273 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 243 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
274 const intptr_t argv_offset = NativeArguments::argv_offset(); | 244 const intptr_t argv_offset = NativeArguments::argv_offset(); |
275 const intptr_t retval_offset = NativeArguments::retval_offset(); | 245 const intptr_t retval_offset = NativeArguments::retval_offset(); |
276 | 246 |
277 __ EnterFrame(0); | 247 __ EnterFrame(0); |
278 | 248 |
279 __ LoadIsolate(R0, kNoPP); | 249 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0); |
| 250 __ LoadIsolate(R28, kNoPP); |
280 | 251 |
281 // Save exit frame information to enable stack walking as we are about | 252 // Save exit frame information to enable stack walking as we are about |
282 // to transition to native code. | 253 // to transition to native code. |
283 __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP); | 254 __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
284 | |
285 // Save current Context pointer into Isolate structure. | |
286 __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP); | |
287 | |
288 // Cache Isolate pointer into CTX while executing native code. | |
289 __ mov(CTX, R0); | |
290 | 255 |
291 #if defined(DEBUG) | 256 #if defined(DEBUG) |
292 { Label ok; | 257 { Label ok; |
293 // Check that we are always entering from Dart code. | 258 // Check that we are always entering from Dart code. |
294 __ LoadFromOffset(R6, CTX, Isolate::vm_tag_offset(), kNoPP); | 259 __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP); |
295 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); | 260 __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP); |
296 __ b(&ok, EQ); | 261 __ b(&ok, EQ); |
297 __ Stop("Not coming from Dart code."); | 262 __ Stop("Not coming from Dart code."); |
298 __ Bind(&ok); | 263 __ Bind(&ok); |
299 } | 264 } |
300 #endif | 265 #endif |
301 | 266 |
302 // Mark that the isolate is executing Native code. | 267 // Mark that the isolate is executing Native code. |
303 __ StoreToOffset(R5, CTX, Isolate::vm_tag_offset(), kNoPP); | 268 __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP); |
304 | 269 |
305 // Reserve space for the native arguments structure passed on the stack (the | 270 // Reserve space for the native arguments structure passed on the stack (the |
306 // outgoing pointer parameter to the native arguments structure is passed in | 271 // outgoing pointer parameter to the native arguments structure is passed in |
307 // R0) and align frame before entering the C++ world. | 272 // R0) and align frame before entering the C++ world. |
308 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 273 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
309 | 274 |
310 // Initialize NativeArguments structure and call native function. | 275 // Initialize NativeArguments structure and call native function. |
311 // Registers R0, R1, R2, and R3 are used. | 276 // Registers R0, R1, R2, and R3 are used. |
312 | 277 |
313 ASSERT(isolate_offset == 0 * kWordSize); | 278 ASSERT(isolate_offset == 0 * kWordSize); |
314 // Set isolate in NativeArgs: R0 already contains CTX. | 279 // Set isolate in NativeArgs. |
| 280 __ mov(R0, R28); |
315 | 281 |
316 // There are no native calls to closures, so we do not need to set the tag | 282 // There are no native calls to closures, so we do not need to set the tag |
317 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 283 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
318 ASSERT(argc_tag_offset == 1 * kWordSize); | 284 ASSERT(argc_tag_offset == 1 * kWordSize); |
319 // Set argc in NativeArguments: R1 already contains argc. | 285 // Set argc in NativeArguments: R1 already contains argc. |
320 | 286 |
321 ASSERT(argv_offset == 2 * kWordSize); | 287 ASSERT(argv_offset == 2 * kWordSize); |
322 // Set argv in NativeArguments: R2 already contains argv. | 288 // Set argv in NativeArguments: R2 already contains argv. |
323 | 289 |
324 // Set retval in NativeArgs. | 290 // Set retval in NativeArgs. |
(...skipping 17 matching lines...) Expand all Loading... |
342 | 308 |
343 // Call native function or redirection via simulator. | 309 // Call native function or redirection via simulator. |
344 __ blr(R5); | 310 __ blr(R5); |
345 | 311 |
346 // Restore SP and CSP. | 312 // Restore SP and CSP. |
347 __ mov(SP, CSP); | 313 __ mov(SP, CSP); |
348 __ mov(CSP, R26); | 314 __ mov(CSP, R26); |
349 | 315 |
350 // Mark that the isolate is executing Dart code. | 316 // Mark that the isolate is executing Dart code. |
351 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); | 317 __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP); |
352 __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP); | 318 __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP); |
353 | 319 |
354 // Reset exit frame information in Isolate structure. | 320 // Reset exit frame information in Isolate structure. |
355 __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP); | 321 __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP); |
356 | |
357 // Load Context pointer from Isolate structure into R2. | |
358 __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP); | |
359 | |
360 // Reset Context pointer in Isolate structure. | |
361 __ LoadObject(R3, Object::null_object(), PP); | |
362 __ StoreToOffset(R3, CTX, Isolate::top_context_offset(), kNoPP); | |
363 | |
364 // Cache Context pointer into CTX while executing Dart code. | |
365 __ mov(CTX, R2); | |
366 | 322 |
367 __ LeaveFrame(); | 323 __ LeaveFrame(); |
368 __ ret(); | 324 __ ret(); |
369 } | 325 } |
370 | 326 |
371 | 327 |
372 // Input parameters: | 328 // Input parameters: |
373 // R4: arguments descriptor array. | 329 // R4: arguments descriptor array. |
374 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 330 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
375 // Create a stub frame as we are pushing some objects on the stack before | 331 // Create a stub frame as we are pushing some objects on the stack before |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 // C++ code. | 782 // C++ code. |
827 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex)); | 783 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex)); |
828 } | 784 } |
829 | 785 |
830 // Save the bottom 64-bits of callee-saved V registers. | 786 // Save the bottom 64-bits of callee-saved V registers. |
831 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { | 787 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { |
832 const VRegister r = static_cast<VRegister>(i); | 788 const VRegister r = static_cast<VRegister>(i); |
833 __ PushDouble(r); | 789 __ PushDouble(r); |
834 } | 790 } |
835 | 791 |
836 // Push new context. | |
837 __ Push(R3); | |
838 #if defined(DEBUG) | |
839 { | |
840 Label ok; | |
841 // The new context, saved vm tag, the top exit frame, and the old context. | |
842 const intptr_t kNewContextOffsetFromFp = | |
843 -(1 + kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount) * kWordSize; | |
844 __ AddImmediate(R4, FP, kNewContextOffsetFromFp, kNoPP); | |
845 __ CompareRegisters(R4, SP); | |
846 __ b(&ok, EQ); | |
847 __ Stop("kNewContextOffsetFromFp mismatch"); | |
848 __ Bind(&ok); | |
849 } | |
850 #endif | |
851 | |
852 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 792 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
853 // could potentially invoke some intrinsic functions which need the PP to be | 793 // could potentially invoke some intrinsic functions which need the PP to be |
854 // set up. | 794 // set up. |
855 __ LoadPoolPointer(PP); | 795 __ LoadPoolPointer(PP); |
856 | 796 |
857 // The new Context structure contains a pointer to the current Isolate | |
858 // structure. Cache the Context pointer in the CTX register so that it is | |
859 // available in generated code and calls to Isolate::Current() need not be | |
860 // done. The assumption is that this register will never be clobbered by | |
861 // compiled or runtime stub code. | |
862 | |
863 // Cache the new Context pointer into CTX while executing Dart code. | |
864 __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle, PP); | |
865 | |
866 // Load Isolate pointer into temporary register R5. | 797 // Load Isolate pointer into temporary register R5. |
867 __ LoadIsolate(R5, PP); | 798 __ LoadIsolate(R5, PP); |
868 | 799 |
869 // Save the current VMTag on the stack. | 800 // Save the current VMTag on the stack. |
870 ASSERT(kSavedVMTagSlotFromEntryFp == -20); | |
871 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP); | 801 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP); |
872 __ Push(R4); | 802 __ Push(R4); |
873 | 803 |
874 // Mark that the isolate is executing Dart code. | 804 // Mark that the isolate is executing Dart code. |
875 __ LoadImmediate(R6, VMTag::kDartTagId, PP); | 805 __ LoadImmediate(R6, VMTag::kDartTagId, PP); |
876 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset(), PP); | 806 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset(), PP); |
877 | 807 |
878 // Save the top exit frame info. Use R6 as a temporary register. | 808 // Save the top exit frame info. Use R6 as a temporary register. |
879 // StackFrameIterator reads the top exit frame info saved in this frame. | 809 // StackFrameIterator reads the top exit frame info saved in this frame. |
880 __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset(), PP); | 810 __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset(), PP); |
881 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset(), PP); | 811 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset(), PP); |
882 | 812 |
883 // Save the old Context pointer. Use R4 as a temporary register. | |
884 // Note that VisitObjectPointers will find this saved Context pointer during | |
885 // GC marking, since it traverses any information between SP and | |
886 // FP - kExitLinkSlotFromEntryFp. | |
887 // EntryFrame::SavedContext reads the context saved in this frame. | |
888 __ LoadFromOffset(R4, R5, Isolate::top_context_offset(), PP); | |
889 | |
890 // The constants kSavedContextSlotFromEntryFp and | |
891 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 813 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
892 ASSERT(kExitLinkSlotFromEntryFp == -21); | 814 ASSERT(kExitLinkSlotFromEntryFp == -20); |
893 ASSERT(kSavedContextSlotFromEntryFp == -22); | |
894 __ Push(R6); | 815 __ Push(R6); |
895 __ Push(R4); | |
896 | 816 |
897 // Load arguments descriptor array into R4, which is passed to Dart code. | 817 // Load arguments descriptor array into R4, which is passed to Dart code. |
898 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle, PP); | 818 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle, PP); |
899 | 819 |
900 // Load number of arguments into S5. | 820 // Load number of arguments into S5. |
901 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset(), PP); | 821 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset(), PP); |
902 __ SmiUntag(R5); | 822 __ SmiUntag(R5); |
903 | 823 |
904 // Compute address of 'arguments array' data area into R2. | 824 // Compute address of 'arguments array' data area into R2. |
905 __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle, PP); | 825 __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle, PP); |
(...skipping 15 matching lines...) Expand all Loading... |
921 __ Bind(&done_push_arguments); | 841 __ Bind(&done_push_arguments); |
922 | 842 |
923 // Call the Dart code entrypoint. | 843 // Call the Dart code entrypoint. |
924 __ blr(R0); // R4 is the arguments descriptor array. | 844 __ blr(R0); // R4 is the arguments descriptor array. |
925 __ Comment("InvokeDartCodeStub return"); | 845 __ Comment("InvokeDartCodeStub return"); |
926 | 846 |
927 // Restore constant pool pointer after return. | 847 // Restore constant pool pointer after return. |
928 __ LoadPoolPointer(PP); | 848 __ LoadPoolPointer(PP); |
929 | 849 |
930 // Get rid of arguments pushed on the stack. | 850 // Get rid of arguments pushed on the stack. |
931 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize, PP); | 851 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize, PP); |
932 | 852 |
933 // Load Isolate pointer into CTX. | 853 __ LoadIsolate(R28, PP); |
934 __ LoadIsolate(CTX, PP); | 854 |
| 855 // Restore the saved top exit frame info back into the Isolate structure. |
| 856 // Uses R6 as a temporary register for this. |
| 857 __ Pop(R6); |
| 858 __ StoreToOffset(R6, R28, Isolate::top_exit_frame_info_offset(), PP); |
935 | 859 |
936 // Restore the current VMTag from the stack. | 860 // Restore the current VMTag from the stack. |
937 __ ldr(R4, Address(SP, 2 * kWordSize)); | |
938 __ StoreToOffset(R4, CTX, Isolate::vm_tag_offset(), PP); | |
939 | |
940 // Restore the saved Context pointer into the Isolate structure. | |
941 // Uses R4 as a temporary register for this. | |
942 // Restore the saved top exit frame info back into the Isolate structure. | |
943 // Uses R6 as a temporary register for this. | |
944 __ Pop(R4); | 861 __ Pop(R4); |
945 __ Pop(R6); | 862 __ StoreToOffset(R4, R28, Isolate::vm_tag_offset(), PP); |
946 __ StoreToOffset(R4, CTX, Isolate::top_context_offset(), PP); | |
947 __ StoreToOffset(R6, CTX, Isolate::top_exit_frame_info_offset(), PP); | |
948 | |
949 __ Pop(R3); | |
950 __ Pop(R4); | |
951 | 863 |
952 // Restore the bottom 64-bits of callee-saved V registers. | 864 // Restore the bottom 64-bits of callee-saved V registers. |
953 for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) { | 865 for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) { |
954 const VRegister r = static_cast<VRegister>(i); | 866 const VRegister r = static_cast<VRegister>(i); |
955 __ PopDouble(r); | 867 __ PopDouble(r); |
956 } | 868 } |
957 | 869 |
958 // Restore C++ ABI callee-saved registers. | 870 // Restore C++ ABI callee-saved registers. |
959 for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) { | 871 for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) { |
960 Register r = static_cast<Register>(i); | 872 Register r = static_cast<Register>(i); |
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2104 const Register right = R0; | 2016 const Register right = R0; |
2105 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); | 2017 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); |
2106 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); | 2018 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); |
2107 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2019 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2108 __ ret(); | 2020 __ ret(); |
2109 } | 2021 } |
2110 | 2022 |
2111 } // namespace dart | 2023 } // namespace dart |
2112 | 2024 |
2113 #endif // defined TARGET_ARCH_ARM64 | 2025 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |