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

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

Issue 25813002: - Rename arrays to lists: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DECLARE_FLAG(bool, enable_type_checks); 18 DECLARE_FLAG(bool, enable_type_checks);
19 19
20 20
21 #define __ assembler-> 21 #define __ assembler->
22 22
23 void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) { 23 void Intrinsifier::List_Allocate(Assembler* assembler) {
24 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; 24 const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
25 const intptr_t kArrayLengthOffset = 0 * kWordSize; 25 const intptr_t kArrayLengthOffset = 0 * kWordSize;
26 Label fall_through; 26 Label fall_through;
27 27
28 // Compute the size to be allocated, it is based on the array length 28 // Compute the size to be allocated, it is based on the array length
29 // and is computed as: 29 // and is computed as:
30 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 30 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
31 __ ldr(R3, Address(SP, kArrayLengthOffset)); // Array length. 31 __ ldr(R3, Address(SP, kArrayLengthOffset)); // Array length.
32 32
33 // Check that length is a positive Smi. 33 // Check that length is a positive Smi.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 } 126 }
127 127
128 128
129 void Intrinsifier::Array_getLength(Assembler* assembler) { 129 void Intrinsifier::Array_getLength(Assembler* assembler) {
130 __ ldr(R0, Address(SP, 0 * kWordSize)); 130 __ ldr(R0, Address(SP, 0 * kWordSize));
131 __ ldr(R0, FieldAddress(R0, Array::length_offset())); 131 __ ldr(R0, FieldAddress(R0, Array::length_offset()));
132 __ Ret(); 132 __ Ret();
133 } 133 }
134 134
135 135
136 void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) { 136 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
137 return Array_getLength(assembler); 137 return Array_getLength(assembler);
138 } 138 }
139 139
140 140
141 void Intrinsifier::Array_getIndexed(Assembler* assembler) { 141 void Intrinsifier::Array_getIndexed(Assembler* assembler) {
142 Label fall_through; 142 Label fall_through;
143 143
144 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index 144 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index
145 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array 145 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array
146 146
147 __ tst(R0, ShifterOperand(kSmiTagMask)); 147 __ tst(R0, ShifterOperand(kSmiTagMask));
148 __ b(&fall_through, NE); // Index is not an smi, fall through 148 __ b(&fall_through, NE); // Index is not an smi, fall through
149 149
150 // range check 150 // range check
151 __ ldr(R6, FieldAddress(R1, Array::length_offset())); 151 __ ldr(R6, FieldAddress(R1, Array::length_offset()));
152 __ cmp(R0, ShifterOperand(R6)); 152 __ cmp(R0, ShifterOperand(R6));
153 153
154 ASSERT(kSmiTagShift == 1); 154 ASSERT(kSmiTagShift == 1);
155 // array element at R1 + R0*2 + Array::data_offset - 1 155 // array element at R1 + R0*2 + Array::data_offset - 1
156 __ add(R6, R1, ShifterOperand(R0, LSL, 1), CC); 156 __ add(R6, R1, ShifterOperand(R0, LSL, 1), CC);
157 __ ldr(R0, FieldAddress(R6, Array::data_offset()), CC); 157 __ ldr(R0, FieldAddress(R6, Array::data_offset()), CC);
158 __ bx(LR, CC); 158 __ bx(LR, CC);
159 __ Bind(&fall_through); 159 __ Bind(&fall_through);
160 } 160 }
161 161
162 162
163 void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { 163 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
164 return Array_getIndexed(assembler); 164 return Array_getIndexed(assembler);
165 } 165 }
166 166
167 167
168 static intptr_t ComputeObjectArrayTypeArgumentsOffset() { 168 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
169 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 169 const Library& core_lib = Library::Handle(Library::CoreLibrary());
170 const Class& cls = Class::Handle( 170 const Class& cls = Class::Handle(
171 core_lib.LookupClassAllowPrivate(Symbols::ObjectArray())); 171 core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
172 ASSERT(!cls.IsNull()); 172 ASSERT(!cls.IsNull());
173 ASSERT(cls.HasTypeArguments()); 173 ASSERT(cls.HasTypeArguments());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 FieldAddress(R1, Array::data_offset()), 240 FieldAddress(R1, Array::data_offset()),
241 R2); 241 R2);
242 // Caller is responsible for preserving the value if necessary. 242 // Caller is responsible for preserving the value if necessary.
243 __ Ret(); 243 __ Ret();
244 __ Bind(&fall_through); 244 __ Bind(&fall_through);
245 } 245 }
246 246
247 247
248 // Allocate a GrowableObjectArray using the backing array specified. 248 // Allocate a GrowableObjectArray using the backing array specified.
249 // On stack: type argument (+1), data (+0). 249 // On stack: type argument (+1), data (+0).
250 void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) { 250 void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
251 // The newly allocated object is returned in R0. 251 // The newly allocated object is returned in R0.
252 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; 252 const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
253 const intptr_t kArrayOffset = 0 * kWordSize; 253 const intptr_t kArrayOffset = 0 * kWordSize;
254 Label fall_through; 254 Label fall_through;
255 255
256 // Compute the size to be allocated, it is based on the array length 256 // Compute the size to be allocated, it is based on the array length
257 // and is computed as: 257 // and is computed as:
258 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) + 258 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) +
259 intptr_t fixed_size = GrowableObjectArray::InstanceSize(); 259 intptr_t fixed_size = GrowableObjectArray::InstanceSize();
260 260
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 306
307 // Set the length field in the growable array object to 0. 307 // Set the length field in the growable array object to 0.
308 __ LoadImmediate(R1, 0); 308 __ LoadImmediate(R1, 0);
309 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); 309 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()));
310 __ Ret(); // Returns the newly allocated object in R0. 310 __ Ret(); // Returns the newly allocated object in R0.
311 311
312 __ Bind(&fall_through); 312 __ Bind(&fall_through);
313 } 313 }
314 314
315 315
316 void Intrinsifier::GrowableArray_getLength(Assembler* assembler) { 316 void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
317 __ ldr(R0, Address(SP, 0 * kWordSize)); 317 __ ldr(R0, Address(SP, 0 * kWordSize));
318 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset())); 318 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset()));
319 __ Ret(); 319 __ Ret();
320 } 320 }
321 321
322 322
323 void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { 323 void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
324 __ ldr(R0, Address(SP, 0 * kWordSize)); 324 __ ldr(R0, Address(SP, 0 * kWordSize));
325 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset())); 325 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset()));
326 __ ldr(R0, FieldAddress(R0, Array::length_offset())); 326 __ ldr(R0, FieldAddress(R0, Array::length_offset()));
327 __ Ret(); 327 __ Ret();
328 } 328 }
329 329
330 330
331 void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) { 331 void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
332 Label fall_through; 332 Label fall_through;
333 333
334 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index 334 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index
335 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array 335 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array
336 336
337 __ tst(R0, ShifterOperand(kSmiTagMask)); 337 __ tst(R0, ShifterOperand(kSmiTagMask));
338 __ b(&fall_through, NE); // Index is not an smi, fall through 338 __ b(&fall_through, NE); // Index is not an smi, fall through
339 339
340 // range check 340 // range check
341 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::length_offset())); 341 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::length_offset()));
342 __ cmp(R0, ShifterOperand(R6)); 342 __ cmp(R0, ShifterOperand(R6));
343 343
344 ASSERT(kSmiTagShift == 1); 344 ASSERT(kSmiTagShift == 1);
345 // array element at R6 + R0 * 2 + Array::data_offset - 1 345 // array element at R6 + R0 * 2 + Array::data_offset - 1
346 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::data_offset()), CC); // data 346 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::data_offset()), CC); // data
347 __ add(R6, R6, ShifterOperand(R0, LSL, 1), CC); 347 __ add(R6, R6, ShifterOperand(R0, LSL, 1), CC);
348 __ ldr(R0, FieldAddress(R6, Array::data_offset()), CC); 348 __ ldr(R0, FieldAddress(R6, Array::data_offset()), CC);
349 __ bx(LR, CC); 349 __ bx(LR, CC);
350 __ Bind(&fall_through); 350 __ Bind(&fall_through);
351 } 351 }
352 352
353 353
354 // Set value into growable object array at specified index. 354 // Set value into growable object array at specified index.
355 // On stack: growable array (+2), index (+1), value (+0). 355 // On stack: growable array (+2), index (+1), value (+0).
356 void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { 356 void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
357 if (FLAG_enable_type_checks) { 357 if (FLAG_enable_type_checks) {
358 return; 358 return;
359 } 359 }
360 Label fall_through; 360 Label fall_through;
361 __ ldr(R1, Address(SP, 1 * kWordSize)); // Index. 361 __ ldr(R1, Address(SP, 1 * kWordSize)); // Index.
362 __ ldr(R0, Address(SP, 2 * kWordSize)); // GrowableArray. 362 __ ldr(R0, Address(SP, 2 * kWordSize)); // GrowableArray.
363 __ tst(R1, ShifterOperand(kSmiTagMask)); 363 __ tst(R1, ShifterOperand(kSmiTagMask));
364 __ b(&fall_through, NE); // Non-smi index. 364 __ b(&fall_through, NE); // Non-smi index.
365 // Range check using _length field. 365 // Range check using _length field.
366 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::length_offset())); 366 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::length_offset()));
367 __ cmp(R1, ShifterOperand(R2)); 367 __ cmp(R1, ShifterOperand(R2));
368 // Runtime throws exception. 368 // Runtime throws exception.
369 __ b(&fall_through, CS); 369 __ b(&fall_through, CS);
370 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset())); // data. 370 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset())); // data.
371 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value. 371 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value.
372 // Note that R1 is Smi, i.e, times 2. 372 // Note that R1 is Smi, i.e, times 2.
373 ASSERT(kSmiTagShift == 1); 373 ASSERT(kSmiTagShift == 1);
374 __ add(R1, R0, ShifterOperand(R1, LSL, 1)); 374 __ add(R1, R0, ShifterOperand(R1, LSL, 1));
375 __ StoreIntoObject(R0, 375 __ StoreIntoObject(R0,
376 FieldAddress(R1, Array::data_offset()), 376 FieldAddress(R1, Array::data_offset()),
377 R2); 377 R2);
378 __ Ret(); 378 __ Ret();
379 __ Bind(&fall_through); 379 __ Bind(&fall_through);
380 } 380 }
381 381
382 382
383 // Set length of growable object array. The length cannot 383 // Set length of growable object array. The length cannot
384 // be greater than the length of the data container. 384 // be greater than the length of the data container.
385 // On stack: growable array (+1), length (+0). 385 // On stack: growable array (+1), length (+0).
386 void Intrinsifier::GrowableArray_setLength(Assembler* assembler) { 386 void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
387 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array. 387 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array.
388 __ ldr(R1, Address(SP, 0 * kWordSize)); // Length value. 388 __ ldr(R1, Address(SP, 0 * kWordSize)); // Length value.
389 __ tst(R1, ShifterOperand(kSmiTagMask)); // Check for Smi. 389 __ tst(R1, ShifterOperand(kSmiTagMask)); // Check for Smi.
390 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()), EQ); 390 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()), EQ);
391 __ bx(LR, EQ); 391 __ bx(LR, EQ);
392 // Fall through on non-Smi. 392 // Fall through on non-Smi.
393 } 393 }
394 394
395 395
396 // Set data of growable object array. 396 // Set data of growable object array.
397 // On stack: growable array (+1), data (+0). 397 // On stack: growable array (+1), data (+0).
398 void Intrinsifier::GrowableArray_setData(Assembler* assembler) { 398 void Intrinsifier::GrowableList_setData(Assembler* assembler) {
399 if (FLAG_enable_type_checks) { 399 if (FLAG_enable_type_checks) {
400 return; 400 return;
401 } 401 }
402 Label fall_through; 402 Label fall_through;
403 __ ldr(R1, Address(SP, 0 * kWordSize)); // Data. 403 __ ldr(R1, Address(SP, 0 * kWordSize)); // Data.
404 // Check that data is an ObjectArray. 404 // Check that data is an ObjectArray.
405 __ tst(R1, ShifterOperand(kSmiTagMask)); 405 __ tst(R1, ShifterOperand(kSmiTagMask));
406 __ b(&fall_through, EQ); // Data is Smi. 406 __ b(&fall_through, EQ); // Data is Smi.
407 __ CompareClassId(R1, kArrayCid, R0); 407 __ CompareClassId(R1, kArrayCid, R0);
408 __ b(&fall_through, NE); 408 __ b(&fall_through, NE);
409 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array. 409 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array.
410 __ StoreIntoObject(R0, 410 __ StoreIntoObject(R0,
411 FieldAddress(R0, GrowableObjectArray::data_offset()), 411 FieldAddress(R0, GrowableObjectArray::data_offset()),
412 R1); 412 R1);
413 __ Ret(); 413 __ Ret();
414 __ Bind(&fall_through); 414 __ Bind(&fall_through);
415 } 415 }
416 416
417 417
418 // Add an element to growable array if it doesn't need to grow, otherwise 418 // Add an element to growable array if it doesn't need to grow, otherwise
419 // call into regular code. 419 // call into regular code.
420 // On stack: growable array (+1), value (+0). 420 // On stack: growable array (+1), value (+0).
421 void Intrinsifier::GrowableArray_add(Assembler* assembler) { 421 void Intrinsifier::GrowableList_add(Assembler* assembler) {
422 // In checked mode we need to type-check the incoming argument. 422 // In checked mode we need to type-check the incoming argument.
423 if (FLAG_enable_type_checks) return; 423 if (FLAG_enable_type_checks) return;
424 Label fall_through; 424 Label fall_through;
425 // R0: Array. 425 // R0: Array.
426 __ ldr(R0, Address(SP, 1 * kWordSize)); 426 __ ldr(R0, Address(SP, 1 * kWordSize));
427 // R1: length. 427 // R1: length.
428 __ ldr(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); 428 __ ldr(R1, FieldAddress(R0, GrowableObjectArray::length_offset()));
429 // R2: data. 429 // R2: data.
430 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::data_offset())); 430 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::data_offset()));
431 // R3: capacity. 431 // R3: capacity.
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 1651
1652 __ Bind(&ok); 1652 __ Bind(&ok);
1653 __ Ret(); 1653 __ Ret();
1654 1654
1655 __ Bind(&fall_through); 1655 __ Bind(&fall_through);
1656 } 1656 }
1657 1657
1658 } // namespace dart 1658 } // namespace dart
1659 1659
1660 #endif // defined TARGET_ARCH_ARM 1660 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698