OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 38 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
39 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 39 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
40 const intptr_t argv_offset = NativeArguments::argv_offset(); | 40 const intptr_t argv_offset = NativeArguments::argv_offset(); |
41 const intptr_t retval_offset = NativeArguments::retval_offset(); | 41 const intptr_t retval_offset = NativeArguments::retval_offset(); |
42 const intptr_t exitframe_last_param_slot_from_fp = 2; | 42 const intptr_t exitframe_last_param_slot_from_fp = 2; |
43 | 43 |
44 __ mov(IP, Operand(0)); | 44 __ mov(IP, Operand(0)); |
45 __ Push(IP); // Push 0 for the PC marker. | 45 __ Push(IP); // Push 0 for the PC marker. |
46 __ EnterFrame((1 << FP) | (1 << LR), 0); | 46 __ EnterFrame((1 << FP) | (1 << LR), 0); |
47 | 47 |
48 __ LoadIsolate(R0); | 48 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 49 __ LoadIsolate(R9); |
49 | 50 |
50 // Save exit frame information to enable stack walking as we are about | 51 // Save exit frame information to enable stack walking as we are about |
51 // to transition to Dart VM C++ code. | 52 // to transition to Dart VM C++ code. |
52 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 53 __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset()); |
53 | |
54 // Save current Context pointer into Isolate structure. | |
55 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); | |
56 | |
57 // Cache Isolate pointer into CTX while executing runtime code. | |
58 __ mov(CTX, Operand(R0)); | |
59 | 54 |
60 #if defined(DEBUG) | 55 #if defined(DEBUG) |
61 { Label ok; | 56 { Label ok; |
62 // Check that we are always entering from Dart code. | 57 // Check that we are always entering from Dart code. |
63 __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset()); | 58 __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset()); |
64 __ CompareImmediate(R6, VMTag::kDartTagId); | 59 __ CompareImmediate(R6, VMTag::kDartTagId); |
65 __ b(&ok, EQ); | 60 __ b(&ok, EQ); |
66 __ Stop("Not coming from Dart code."); | 61 __ Stop("Not coming from Dart code."); |
67 __ Bind(&ok); | 62 __ Bind(&ok); |
68 } | 63 } |
69 #endif | 64 #endif |
70 | 65 |
71 // Mark that the isolate is executing VM code. | 66 // Mark that the isolate is executing VM code. |
72 __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset()); | 67 __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset()); |
73 | 68 |
74 // Reserve space for arguments and align frame before entering C++ world. | 69 // Reserve space for arguments and align frame before entering C++ world. |
75 // NativeArguments are passed in registers. | 70 // NativeArguments are passed in registers. |
76 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 71 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
77 __ ReserveAlignedFrameSpace(0); | 72 __ ReserveAlignedFrameSpace(0); |
78 | 73 |
79 // Pass NativeArguments structure by value and call runtime. | 74 // Pass NativeArguments structure by value and call runtime. |
80 // Registers R0, R1, R2, and R3 are used. | 75 // Registers R0, R1, R2, and R3 are used. |
81 | 76 |
82 ASSERT(isolate_offset == 0 * kWordSize); | 77 ASSERT(isolate_offset == 0 * kWordSize); |
83 // Set isolate in NativeArgs: R0 already contains CTX. | 78 // Set isolate in NativeArgs. |
| 79 __ mov(R0, Operand(R9)); |
84 | 80 |
85 // There are no runtime calls to closures, so we do not need to set the tag | 81 // There are no runtime calls to closures, so we do not need to set the tag |
86 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 82 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
87 ASSERT(argc_tag_offset == 1 * kWordSize); | 83 ASSERT(argc_tag_offset == 1 * kWordSize); |
88 __ mov(R1, Operand(R4)); // Set argc in NativeArguments. | 84 __ mov(R1, Operand(R4)); // Set argc in NativeArguments. |
89 | 85 |
90 ASSERT(argv_offset == 2 * kWordSize); | 86 ASSERT(argv_offset == 2 * kWordSize); |
91 __ add(R2, FP, Operand(R4, LSL, 2)); // Compute argv. | 87 __ add(R2, FP, Operand(R4, LSL, 2)); // Compute argv. |
92 // Set argv in NativeArguments. | 88 // Set argv in NativeArguments. |
93 __ AddImmediate(R2, exitframe_last_param_slot_from_fp * kWordSize); | 89 __ AddImmediate(R2, exitframe_last_param_slot_from_fp * kWordSize); |
94 | 90 |
95 ASSERT(retval_offset == 3 * kWordSize); | 91 ASSERT(retval_offset == 3 * kWordSize); |
96 __ add(R3, R2, Operand(kWordSize)); // Retval is next to 1st argument. | 92 __ add(R3, R2, Operand(kWordSize)); // Retval is next to 1st argument. |
97 | 93 |
98 // Call runtime or redirection via simulator. | 94 // Call runtime or redirection via simulator. |
99 __ blx(R5); | 95 __ blx(R5); |
100 | 96 |
101 // Mark that the isolate is executing Dart code. | 97 // Mark that the isolate is executing Dart code. |
102 __ LoadImmediate(R2, VMTag::kDartTagId); | 98 __ LoadImmediate(R2, VMTag::kDartTagId); |
103 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); | 99 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
104 | 100 |
105 // Reset exit frame information in Isolate structure. | 101 // Reset exit frame information in Isolate structure. |
106 __ LoadImmediate(R2, 0); | 102 __ LoadImmediate(R2, 0); |
107 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 103 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
108 | |
109 // Load Context pointer from Isolate structure into R2. | |
110 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | |
111 | |
112 // Reset Context pointer in Isolate structure. | |
113 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | |
114 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | |
115 | |
116 // Cache Context pointer into CTX while executing Dart code. | |
117 __ mov(CTX, Operand(R2)); | |
118 | 104 |
119 __ LeaveFrame((1 << FP) | (1 << LR)); | 105 __ LeaveFrame((1 << FP) | (1 << LR)); |
120 // Adjust SP for the empty PC marker. | 106 // Adjust SP for the empty PC marker. |
121 __ AddImmediate(SP, kWordSize); | 107 __ AddImmediate(SP, kWordSize); |
122 __ Ret(); | 108 __ Ret(); |
123 } | 109 } |
124 | 110 |
125 | 111 |
126 // Print the stop message. | 112 // Print the stop message. |
127 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 113 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
(...skipping 23 matching lines...) Expand all Loading... |
151 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 137 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
152 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 138 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
153 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 139 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
154 const intptr_t argv_offset = NativeArguments::argv_offset(); | 140 const intptr_t argv_offset = NativeArguments::argv_offset(); |
155 const intptr_t retval_offset = NativeArguments::retval_offset(); | 141 const intptr_t retval_offset = NativeArguments::retval_offset(); |
156 | 142 |
157 __ mov(IP, Operand(0)); | 143 __ mov(IP, Operand(0)); |
158 __ Push(IP); // Push 0 for the PC marker. | 144 __ Push(IP); // Push 0 for the PC marker. |
159 __ EnterFrame((1 << FP) | (1 << LR), 0); | 145 __ EnterFrame((1 << FP) | (1 << LR), 0); |
160 | 146 |
161 __ LoadIsolate(R0); | 147 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 148 __ LoadIsolate(R9); |
162 | 149 |
163 // 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 |
164 // to transition to native code. | 151 // to transition to native code. |
165 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 152 __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset()); |
166 | |
167 // Save current Context pointer into Isolate structure. | |
168 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); | |
169 | |
170 // Cache Isolate pointer into CTX while executing native code. | |
171 __ mov(CTX, Operand(R0)); | |
172 | 153 |
173 #if defined(DEBUG) | 154 #if defined(DEBUG) |
174 { Label ok; | 155 { Label ok; |
175 // Check that we are always entering from Dart code. | 156 // Check that we are always entering from Dart code. |
176 __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset()); | 157 __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset()); |
177 __ CompareImmediate(R6, VMTag::kDartTagId); | 158 __ CompareImmediate(R6, VMTag::kDartTagId); |
178 __ b(&ok, EQ); | 159 __ b(&ok, EQ); |
179 __ Stop("Not coming from Dart code."); | 160 __ Stop("Not coming from Dart code."); |
180 __ Bind(&ok); | 161 __ Bind(&ok); |
181 } | 162 } |
182 #endif | 163 #endif |
183 | 164 |
184 // Mark that the isolate is executing Native code. | 165 // Mark that the isolate is executing Native code. |
185 __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset()); | 166 __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset()); |
186 | 167 |
187 // 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 |
188 // outgoing pointer parameter to the native arguments structure is passed in | 169 // outgoing pointer parameter to the native arguments structure is passed in |
189 // R0) and align frame before entering the C++ world. | 170 // R0) and align frame before entering the C++ world. |
190 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 171 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
191 | 172 |
192 // Initialize NativeArguments structure and call native function. | 173 // Initialize NativeArguments structure and call native function. |
193 // Registers R0, R1, R2, and R3 are used. | 174 // Registers R0, R1, R2, and R3 are used. |
194 | 175 |
195 ASSERT(isolate_offset == 0 * kWordSize); | 176 ASSERT(isolate_offset == 0 * kWordSize); |
196 // Set isolate in NativeArgs: R0 already contains CTX. | 177 // Set isolate in NativeArgs. |
| 178 __ mov(R0, Operand(R9)); |
197 | 179 |
198 // 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 |
199 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 181 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
200 ASSERT(argc_tag_offset == 1 * kWordSize); | 182 ASSERT(argc_tag_offset == 1 * kWordSize); |
201 // Set argc in NativeArguments: R1 already contains argc. | 183 // Set argc in NativeArguments: R1 already contains argc. |
202 | 184 |
203 ASSERT(argv_offset == 2 * kWordSize); | 185 ASSERT(argv_offset == 2 * kWordSize); |
204 // Set argv in NativeArguments: R2 already contains argv. | 186 // Set argv in NativeArguments: R2 already contains argv. |
205 | 187 |
206 ASSERT(retval_offset == 3 * kWordSize); | 188 ASSERT(retval_offset == 3 * kWordSize); |
(...skipping 12 matching lines...) Expand all Loading... |
219 entry = Simulator::RedirectExternalReference( | 201 entry = Simulator::RedirectExternalReference( |
220 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); | 202 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); |
221 __ LoadImmediate(R2, entry); | 203 __ LoadImmediate(R2, entry); |
222 __ blx(R2); | 204 __ blx(R2); |
223 #else | 205 #else |
224 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); | 206 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); |
225 #endif | 207 #endif |
226 | 208 |
227 // Mark that the isolate is executing Dart code. | 209 // Mark that the isolate is executing Dart code. |
228 __ LoadImmediate(R2, VMTag::kDartTagId); | 210 __ LoadImmediate(R2, VMTag::kDartTagId); |
229 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); | 211 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
230 | 212 |
231 // Reset exit frame information in Isolate structure. | 213 // Reset exit frame information in Isolate structure. |
232 __ LoadImmediate(R2, 0); | 214 __ LoadImmediate(R2, 0); |
233 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 215 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
234 | |
235 // Load Context pointer from Isolate structure into R2. | |
236 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | |
237 | |
238 // Reset Context pointer in Isolate structure. | |
239 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | |
240 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | |
241 | |
242 // Cache Context pointer into CTX while executing Dart code. | |
243 __ mov(CTX, Operand(R2)); | |
244 | 216 |
245 __ LeaveFrame((1 << FP) | (1 << LR)); | 217 __ LeaveFrame((1 << FP) | (1 << LR)); |
246 // Adjust SP for the empty PC marker. | 218 // Adjust SP for the empty PC marker. |
247 __ AddImmediate(SP, kWordSize); | 219 __ AddImmediate(SP, kWordSize); |
248 __ Ret(); | 220 __ Ret(); |
249 } | 221 } |
250 | 222 |
251 | 223 |
252 // Input parameters: | 224 // Input parameters: |
253 // LR : return address. | 225 // LR : return address. |
254 // SP : address of return value. | 226 // SP : address of return value. |
255 // R5 : address of the native function to call. | 227 // R5 : address of the native function to call. |
256 // R2 : address of first argument in argument array. | 228 // R2 : address of first argument in argument array. |
257 // R1 : argc_tag including number of arguments and function kind. | 229 // R1 : argc_tag including number of arguments and function kind. |
258 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 230 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
259 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 231 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
260 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 232 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
261 const intptr_t argv_offset = NativeArguments::argv_offset(); | 233 const intptr_t argv_offset = NativeArguments::argv_offset(); |
262 const intptr_t retval_offset = NativeArguments::retval_offset(); | 234 const intptr_t retval_offset = NativeArguments::retval_offset(); |
263 | 235 |
264 __ mov(IP, Operand(0)); | 236 __ mov(IP, Operand(0)); |
265 __ Push(IP); // Push 0 for the PC marker. | 237 __ Push(IP); // Push 0 for the PC marker. |
266 __ EnterFrame((1 << FP) | (1 << LR), 0); | 238 __ EnterFrame((1 << FP) | (1 << LR), 0); |
267 | 239 |
268 __ LoadIsolate(R0); | 240 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 241 __ LoadIsolate(R9); |
269 | 242 |
270 // Save exit frame information to enable stack walking as we are about | 243 // Save exit frame information to enable stack walking as we are about |
271 // to transition to native code. | 244 // to transition to native code. |
272 __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); | 245 __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset()); |
273 | |
274 // Save current Context pointer into Isolate structure. | |
275 __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); | |
276 | |
277 // Cache Isolate pointer into CTX while executing native code. | |
278 __ mov(CTX, Operand(R0)); | |
279 | 246 |
280 #if defined(DEBUG) | 247 #if defined(DEBUG) |
281 { Label ok; | 248 { Label ok; |
282 // Check that we are always entering from Dart code. | 249 // Check that we are always entering from Dart code. |
283 __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset()); | 250 __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset()); |
284 __ CompareImmediate(R6, VMTag::kDartTagId); | 251 __ CompareImmediate(R6, VMTag::kDartTagId); |
285 __ b(&ok, EQ); | 252 __ b(&ok, EQ); |
286 __ Stop("Not coming from Dart code."); | 253 __ Stop("Not coming from Dart code."); |
287 __ Bind(&ok); | 254 __ Bind(&ok); |
288 } | 255 } |
289 #endif | 256 #endif |
290 | 257 |
291 // Mark that the isolate is executing Native code. | 258 // Mark that the isolate is executing Native code. |
292 __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset()); | 259 __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset()); |
293 | 260 |
294 // Reserve space for the native arguments structure passed on the stack (the | 261 // Reserve space for the native arguments structure passed on the stack (the |
295 // outgoing pointer parameter to the native arguments structure is passed in | 262 // outgoing pointer parameter to the native arguments structure is passed in |
296 // R0) and align frame before entering the C++ world. | 263 // R0) and align frame before entering the C++ world. |
297 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | 264 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
298 | 265 |
299 // Initialize NativeArguments structure and call native function. | 266 // Initialize NativeArguments structure and call native function. |
300 // Registers R0, R1, R2, and R3 are used. | 267 // Registers R0, R1, R2, and R3 are used. |
301 | 268 |
302 ASSERT(isolate_offset == 0 * kWordSize); | 269 ASSERT(isolate_offset == 0 * kWordSize); |
303 // Set isolate in NativeArgs: R0 already contains CTX. | 270 // Set isolate in NativeArgs. |
| 271 __ mov(R0, Operand(R9)); |
304 | 272 |
305 // There are no native calls to closures, so we do not need to set the tag | 273 // There are no native calls to closures, so we do not need to set the tag |
306 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 274 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
307 ASSERT(argc_tag_offset == 1 * kWordSize); | 275 ASSERT(argc_tag_offset == 1 * kWordSize); |
308 // Set argc in NativeArguments: R1 already contains argc. | 276 // Set argc in NativeArguments: R1 already contains argc. |
309 | 277 |
310 ASSERT(argv_offset == 2 * kWordSize); | 278 ASSERT(argv_offset == 2 * kWordSize); |
311 // Set argv in NativeArguments: R2 already contains argv. | 279 // Set argv in NativeArguments: R2 already contains argv. |
312 | 280 |
313 ASSERT(retval_offset == 3 * kWordSize); | 281 ASSERT(retval_offset == 3 * kWordSize); |
314 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. | 282 __ add(R3, FP, Operand(3 * kWordSize)); // Set retval in NativeArgs. |
315 | 283 |
316 // Passing the structure by value as in runtime calls would require changing | 284 // Passing the structure by value as in runtime calls would require changing |
317 // Dart API for native functions. | 285 // Dart API for native functions. |
318 // For now, space is reserved on the stack and we pass a pointer to it. | 286 // For now, space is reserved on the stack and we pass a pointer to it. |
319 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); | 287 __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
320 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. | 288 __ mov(R0, Operand(SP)); // Pass the pointer to the NativeArguments. |
321 | 289 |
322 // Call native function or redirection via simulator. | 290 // Call native function or redirection via simulator. |
323 __ blx(R5); | 291 __ blx(R5); |
324 | 292 |
325 // Mark that the isolate is executing Dart code. | 293 // Mark that the isolate is executing Dart code. |
326 __ LoadImmediate(R2, VMTag::kDartTagId); | 294 __ LoadImmediate(R2, VMTag::kDartTagId); |
327 __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset()); | 295 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
328 | 296 |
329 // Reset exit frame information in Isolate structure. | 297 // Reset exit frame information in Isolate structure. |
330 __ LoadImmediate(R2, 0); | 298 __ LoadImmediate(R2, 0); |
331 __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); | 299 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
332 | |
333 // Load Context pointer from Isolate structure into R2. | |
334 __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); | |
335 | |
336 // Reset Context pointer in Isolate structure. | |
337 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | |
338 __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); | |
339 | |
340 // Cache Context pointer into CTX while executing Dart code. | |
341 __ mov(CTX, Operand(R2)); | |
342 | 300 |
343 __ LeaveFrame((1 << FP) | (1 << LR)); | 301 __ LeaveFrame((1 << FP) | (1 << LR)); |
344 // Adjust SP for the empty PC marker. | 302 // Adjust SP for the empty PC marker. |
345 __ AddImmediate(SP, kWordSize); | 303 __ AddImmediate(SP, kWordSize); |
346 __ Ret(); | 304 __ Ret(); |
347 } | 305 } |
348 | 306 |
349 | 307 |
350 // Input parameters: | 308 // Input parameters: |
351 // R4: arguments descriptor array. | 309 // R4: arguments descriptor array. |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 // LR : points to return address. | 736 // LR : points to return address. |
779 // R0 : entrypoint of the Dart function to call. | 737 // R0 : entrypoint of the Dart function to call. |
780 // R1 : arguments descriptor array. | 738 // R1 : arguments descriptor array. |
781 // R2 : arguments array. | 739 // R2 : arguments array. |
782 // R3 : new context containing the current isolate pointer. | 740 // R3 : new context containing the current isolate pointer. |
783 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 741 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
784 // Save frame pointer coming in. | 742 // Save frame pointer coming in. |
785 __ EnterFrame((1 << FP) | (1 << LR), 0); | 743 __ EnterFrame((1 << FP) | (1 << LR), 0); |
786 | 744 |
787 // Save new context and C++ ABI callee-saved registers. | 745 // Save new context and C++ ABI callee-saved registers. |
788 __ PushList((1 << R3) | kAbiPreservedCpuRegs); | 746 __ PushList(kAbiPreservedCpuRegs); |
789 | 747 |
790 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg); | 748 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg); |
791 if (TargetCPUFeatures::vfp_supported()) { | 749 if (TargetCPUFeatures::vfp_supported()) { |
792 ASSERT(2 * kAbiPreservedFpuRegCount < 16); | 750 ASSERT(2 * kAbiPreservedFpuRegCount < 16); |
793 // Save FPU registers. 2 D registers per Q register. | 751 // Save FPU registers. 2 D registers per Q register. |
794 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); | 752 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
795 } else { | 753 } else { |
796 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); | 754 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); |
797 } | 755 } |
798 | 756 |
799 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 757 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
800 // could potentially invoke some intrinsic functions which need the PP to be | 758 // could potentially invoke some intrinsic functions which need the PP to be |
801 // set up. | 759 // set up. |
802 __ LoadPoolPointer(); | 760 __ LoadPoolPointer(); |
803 | 761 |
804 // The new Context structure contains a pointer to the current Isolate | |
805 // structure. Cache the Context pointer in the CTX register so that it is | |
806 // available in generated code and calls to Isolate::Current() need not be | |
807 // done. The assumption is that this register will never be clobbered by | |
808 // compiled or runtime stub code. | |
809 | |
810 // Cache the new Context pointer into CTX while executing Dart code. | |
811 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); | |
812 | |
813 __ LoadIsolate(R8); | 762 __ LoadIsolate(R8); |
814 | 763 |
815 // Save the current VMTag on the stack. | 764 // Save the current VMTag on the stack. |
816 ASSERT(kSavedVMTagSlotFromEntryFp == -25); | |
817 __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset()); | 765 __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset()); |
818 __ Push(R5); | 766 __ Push(R5); |
819 | 767 |
820 // Mark that the isolate is executing Dart code. | 768 // Mark that the isolate is executing Dart code. |
821 __ LoadImmediate(R5, VMTag::kDartTagId); | 769 __ LoadImmediate(R5, VMTag::kDartTagId); |
822 __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset()); | 770 __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset()); |
823 | 771 |
824 // Save the top exit frame info. Use R5 as a temporary register. | 772 // Save the top exit frame info. Use R5 as a temporary register. |
825 // StackFrameIterator reads the top exit frame info saved in this frame. | 773 // StackFrameIterator reads the top exit frame info saved in this frame. |
826 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); | 774 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); |
827 __ LoadImmediate(R6, 0); | 775 __ LoadImmediate(R6, 0); |
828 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); | 776 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); |
829 | 777 |
830 // Save the old Context pointer. Use R4 as a temporary register. | |
831 // Note that VisitObjectPointers will find this saved Context pointer during | |
832 // GC marking, since it traverses any information between SP and | |
833 // FP - kExitLinkSlotFromEntryFp. | |
834 // EntryFrame::SavedContext reads the context saved in this frame. | |
835 __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset()); | |
836 | |
837 // The constants kSavedContextSlotFromEntryFp and | |
838 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 778 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
839 ASSERT(kExitLinkSlotFromEntryFp == -26); | 779 ASSERT(kExitLinkSlotFromEntryFp == -25); |
840 ASSERT(kSavedContextSlotFromEntryFp == -27); | 780 __ Push(R5); |
841 __ PushList((1 << R4) | (1 << R5)); | |
842 | 781 |
843 // Load arguments descriptor array into R4, which is passed to Dart code. | 782 // Load arguments descriptor array into R4, which is passed to Dart code. |
844 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); | 783 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); |
845 | 784 |
846 // Load number of arguments into R5. | 785 // Load number of arguments into R5. |
847 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 786 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
848 __ SmiUntag(R5); | 787 __ SmiUntag(R5); |
849 | 788 |
850 // Compute address of 'arguments array' data area into R2. | 789 // Compute address of 'arguments array' data area into R2. |
851 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); | 790 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); |
(...skipping 11 matching lines...) Expand all Loading... |
863 __ AddImmediate(R2, kWordSize); | 802 __ AddImmediate(R2, kWordSize); |
864 __ AddImmediate(R1, 1); | 803 __ AddImmediate(R1, 1); |
865 __ cmp(R1, Operand(R5)); | 804 __ cmp(R1, Operand(R5)); |
866 __ b(&push_arguments, LT); | 805 __ b(&push_arguments, LT); |
867 __ Bind(&done_push_arguments); | 806 __ Bind(&done_push_arguments); |
868 | 807 |
869 // Call the Dart code entrypoint. | 808 // Call the Dart code entrypoint. |
870 __ blx(R0); // R4 is the arguments descriptor array. | 809 __ blx(R0); // R4 is the arguments descriptor array. |
871 | 810 |
872 // Get rid of arguments pushed on the stack. | 811 // Get rid of arguments pushed on the stack. |
873 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); | 812 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize); |
874 | 813 |
875 // Load Isolate pointer into CTX. | 814 __ LoadIsolate(R8); |
876 __ LoadIsolate(CTX); | |
877 | 815 |
878 // Restore the saved Context pointer into the Isolate structure. | |
879 // Uses R4 as a temporary register for this. | |
880 // Restore the saved top exit frame info back into the Isolate structure. | 816 // Restore the saved top exit frame info back into the Isolate structure. |
881 // Uses R5 as a temporary register for this. | 817 // Uses R5 as a temporary register for this. |
882 __ PopList((1 << R4) | (1 << R5)); | 818 __ Pop(R5); |
883 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset()); | 819 __ StoreToOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); |
884 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset()); | |
885 | 820 |
886 // Restore the current VMTag from the stack. | 821 // Restore the current VMTag from the stack. |
887 __ Pop(R4); | 822 __ Pop(R4); |
888 __ StoreToOffset(kWord, R4, CTX, Isolate::vm_tag_offset()); | 823 __ StoreToOffset(kWord, R4, R8, Isolate::vm_tag_offset()); |
889 | 824 |
890 // Restore C++ ABI callee-saved registers. | 825 // Restore C++ ABI callee-saved registers. |
891 if (TargetCPUFeatures::vfp_supported()) { | 826 if (TargetCPUFeatures::vfp_supported()) { |
892 // Restore FPU registers. 2 D registers per Q register. | 827 // Restore FPU registers. 2 D registers per Q register. |
893 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); | 828 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); |
894 } else { | 829 } else { |
895 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); | 830 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); |
896 } | 831 } |
897 // Restore CPU registers. | 832 // Restore CPU registers. |
898 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. | 833 __ PopList(kAbiPreservedCpuRegs); |
899 | 834 |
900 // Restore the frame pointer and return. | 835 // Restore the frame pointer and return. |
901 __ LeaveFrame((1 << FP) | (1 << LR)); | 836 __ LeaveFrame((1 << FP) | (1 << LR)); |
902 __ Ret(); | 837 __ Ret(); |
903 } | 838 } |
904 | 839 |
905 | 840 |
906 // Called for inline allocation of contexts. | 841 // Called for inline allocation of contexts. |
907 // Input: | 842 // Input: |
908 // R1: number of context variables. | 843 // R1: number of context variables. |
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 const Register right = R0; | 1987 const Register right = R0; |
2053 __ ldr(left, Address(SP, 1 * kWordSize)); | 1988 __ ldr(left, Address(SP, 1 * kWordSize)); |
2054 __ ldr(right, Address(SP, 0 * kWordSize)); | 1989 __ ldr(right, Address(SP, 0 * kWordSize)); |
2055 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1990 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2056 __ Ret(); | 1991 __ Ret(); |
2057 } | 1992 } |
2058 | 1993 |
2059 } // namespace dart | 1994 } // namespace dart |
2060 | 1995 |
2061 #endif // defined TARGET_ARCH_ARM | 1996 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |