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

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

Issue 678763004: Make CTX allocatable by the register allocator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: incorporated latest comments Created 6 years, 1 month 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) 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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698