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

Side by Side Diff: runtime/vm/intrinsifier_mips.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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 __ lw(T3, Address(SP, kArrayLengthOffset)); // Array length. 31 __ lw(T3, Address(SP, kArrayLengthOffset)); // Array length.
32 32
33 // Check that length is a positive Smi. 33 // Check that length is a positive Smi.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 } 133 }
134 134
135 135
136 void Intrinsifier::Array_getLength(Assembler* assembler) { 136 void Intrinsifier::Array_getLength(Assembler* assembler) {
137 __ lw(V0, Address(SP, 0 * kWordSize)); 137 __ lw(V0, Address(SP, 0 * kWordSize));
138 __ Ret(); 138 __ Ret();
139 __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset())); 139 __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset()));
140 } 140 }
141 141
142 142
143 void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) { 143 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
144 return Array_getLength(assembler); 144 return Array_getLength(assembler);
145 } 145 }
146 146
147 147
148 void Intrinsifier::Array_getIndexed(Assembler* assembler) { 148 void Intrinsifier::Array_getIndexed(Assembler* assembler) {
149 Label fall_through; 149 Label fall_through;
150 150
151 __ lw(T0, Address(SP, + 0 * kWordSize)); // Index 151 __ lw(T0, Address(SP, + 0 * kWordSize)); // Index
152 152
153 __ andi(CMPRES, T0, Immediate(kSmiTagMask)); 153 __ andi(CMPRES, T0, Immediate(kSmiTagMask));
154 __ bne(CMPRES, ZR, &fall_through); // Index is not an smi, fall through 154 __ bne(CMPRES, ZR, &fall_through); // Index is not an smi, fall through
155 __ delay_slot()->lw(T1, Address(SP, + 1 * kWordSize)); // Array 155 __ delay_slot()->lw(T1, Address(SP, + 1 * kWordSize)); // Array
156 156
157 // range check 157 // range check
158 __ lw(T2, FieldAddress(T1, Array::length_offset())); 158 __ lw(T2, FieldAddress(T1, Array::length_offset()));
159 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through); 159 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through);
160 160
161 ASSERT(kSmiTagShift == 1); 161 ASSERT(kSmiTagShift == 1);
162 // array element at T1 + T0*2 + Array::data_offset - 1 162 // array element at T1 + T0*2 + Array::data_offset - 1
163 __ sll(T2, T0, 1); 163 __ sll(T2, T0, 1);
164 __ addu(T2, T1, T2); 164 __ addu(T2, T1, T2);
165 __ Ret(); 165 __ Ret();
166 __ delay_slot()->lw(V0, FieldAddress(T2, Array::data_offset())); 166 __ delay_slot()->lw(V0, FieldAddress(T2, Array::data_offset()));
167 __ Bind(&fall_through); 167 __ Bind(&fall_through);
168 } 168 }
169 169
170 170
171 void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { 171 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
172 return Array_getIndexed(assembler); 172 return Array_getIndexed(assembler);
173 } 173 }
174 174
175 175
176 static intptr_t ComputeObjectArrayTypeArgumentsOffset() { 176 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
177 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 177 const Library& core_lib = Library::Handle(Library::CoreLibrary());
178 const Class& cls = Class::Handle( 178 const Class& cls = Class::Handle(
179 core_lib.LookupClassAllowPrivate(Symbols::ObjectArray())); 179 core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
180 ASSERT(!cls.IsNull()); 180 ASSERT(!cls.IsNull());
181 ASSERT(cls.HasTypeArguments()); 181 ASSERT(cls.HasTypeArguments());
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 FieldAddress(T1, Array::data_offset()), 245 FieldAddress(T1, Array::data_offset()),
246 T2); 246 T2);
247 // Caller is responsible for preserving the value if necessary. 247 // Caller is responsible for preserving the value if necessary.
248 __ Ret(); 248 __ Ret();
249 __ Bind(&fall_through); 249 __ Bind(&fall_through);
250 } 250 }
251 251
252 252
253 // Allocate a GrowableObjectArray using the backing array specified. 253 // Allocate a GrowableObjectArray using the backing array specified.
254 // On stack: type argument (+1), data (+0). 254 // On stack: type argument (+1), data (+0).
255 void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) { 255 void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
256 // The newly allocated object is returned in V0. 256 // The newly allocated object is returned in V0.
257 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; 257 const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
258 const intptr_t kArrayOffset = 0 * kWordSize; 258 const intptr_t kArrayOffset = 0 * kWordSize;
259 Label fall_through; 259 Label fall_through;
260 260
261 // Compute the size to be allocated, it is based on the array length 261 // Compute the size to be allocated, it is based on the array length
262 // and is computed as: 262 // and is computed as:
263 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) + 263 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) +
264 intptr_t fixed_size = GrowableObjectArray::InstanceSize(); 264 intptr_t fixed_size = GrowableObjectArray::InstanceSize();
265 265
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 310
311 // Set the length field in the growable array object to 0. 311 // Set the length field in the growable array object to 0.
312 __ Ret(); // Returns the newly allocated object in V0. 312 __ Ret(); // Returns the newly allocated object in V0.
313 __ delay_slot()->sw(ZR, 313 __ delay_slot()->sw(ZR,
314 FieldAddress(V0, GrowableObjectArray::length_offset())); 314 FieldAddress(V0, GrowableObjectArray::length_offset()));
315 315
316 __ Bind(&fall_through); 316 __ Bind(&fall_through);
317 } 317 }
318 318
319 319
320 void Intrinsifier::GrowableArray_getLength(Assembler* assembler) { 320 void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
321 __ lw(V0, Address(SP, 0 * kWordSize)); 321 __ lw(V0, Address(SP, 0 * kWordSize));
322 __ Ret(); 322 __ Ret();
323 __ delay_slot()->lw(V0, 323 __ delay_slot()->lw(V0,
324 FieldAddress(V0, GrowableObjectArray::length_offset())); 324 FieldAddress(V0, GrowableObjectArray::length_offset()));
325 } 325 }
326 326
327 327
328 void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { 328 void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
329 __ lw(V0, Address(SP, 0 * kWordSize)); 329 __ lw(V0, Address(SP, 0 * kWordSize));
330 __ lw(V0, FieldAddress(V0, GrowableObjectArray::data_offset())); 330 __ lw(V0, FieldAddress(V0, GrowableObjectArray::data_offset()));
331 __ Ret(); 331 __ Ret();
332 __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset())); 332 __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset()));
333 } 333 }
334 334
335 335
336 void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) { 336 void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
337 Label fall_through; 337 Label fall_through;
338 338
339 __ lw(T0, Address(SP, 0 * kWordSize)); // Index 339 __ lw(T0, Address(SP, 0 * kWordSize)); // Index
340 340
341 __ andi(CMPRES, T0, Immediate(kSmiTagMask)); 341 __ andi(CMPRES, T0, Immediate(kSmiTagMask));
342 __ bne(CMPRES, ZR, &fall_through); // Index is not an smi, fall through 342 __ bne(CMPRES, ZR, &fall_through); // Index is not an smi, fall through
343 __ delay_slot()->lw(T1, Address(SP, 1 * kWordSize)); // Array 343 __ delay_slot()->lw(T1, Address(SP, 1 * kWordSize)); // Array
344 344
345 // range check 345 // range check
346 __ lw(T2, FieldAddress(T1, GrowableObjectArray::length_offset())); 346 __ lw(T2, FieldAddress(T1, GrowableObjectArray::length_offset()));
347 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through); 347 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through);
348 348
349 __ lw(T2, FieldAddress(T1, GrowableObjectArray::data_offset())); // data 349 __ lw(T2, FieldAddress(T1, GrowableObjectArray::data_offset())); // data
350 350
351 ASSERT(kSmiTagShift == 1); 351 ASSERT(kSmiTagShift == 1);
352 // array element at T2 + T0 * 2 + Array::data_offset - 1 352 // array element at T2 + T0 * 2 + Array::data_offset - 1
353 __ sll(T3, T0, 1); 353 __ sll(T3, T0, 1);
354 __ addu(T2, T2, T3); 354 __ addu(T2, T2, T3);
355 __ Ret(); 355 __ Ret();
356 __ delay_slot()->lw(V0, FieldAddress(T2, Array::data_offset())); 356 __ delay_slot()->lw(V0, FieldAddress(T2, Array::data_offset()));
357 __ Bind(&fall_through); 357 __ Bind(&fall_through);
358 } 358 }
359 359
360 360
361 // Set value into growable object array at specified index. 361 // Set value into growable object array at specified index.
362 // On stack: growable array (+2), index (+1), value (+0). 362 // On stack: growable array (+2), index (+1), value (+0).
363 void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { 363 void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
364 if (FLAG_enable_type_checks) { 364 if (FLAG_enable_type_checks) {
365 return; 365 return;
366 } 366 }
367 Label fall_through; 367 Label fall_through;
368 __ lw(T1, Address(SP, 1 * kWordSize)); // Index. 368 __ lw(T1, Address(SP, 1 * kWordSize)); // Index.
369 __ andi(CMPRES, T1, Immediate(kSmiTagMask)); 369 __ andi(CMPRES, T1, Immediate(kSmiTagMask));
370 __ bne(CMPRES, ZR, &fall_through); // Non-smi index. 370 __ bne(CMPRES, ZR, &fall_through); // Non-smi index.
371 __ delay_slot()->lw(T0, Address(SP, 2 * kWordSize)); // GrowableArray. 371 __ delay_slot()->lw(T0, Address(SP, 2 * kWordSize)); // GrowableArray.
372 // Range check using _length field. 372 // Range check using _length field.
373 __ lw(T2, FieldAddress(T0, GrowableObjectArray::length_offset())); 373 __ lw(T2, FieldAddress(T0, GrowableObjectArray::length_offset()));
374 // Runtime throws exception. 374 // Runtime throws exception.
375 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through); 375 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
376 __ lw(T0, FieldAddress(T0, GrowableObjectArray::data_offset())); // data. 376 __ lw(T0, FieldAddress(T0, GrowableObjectArray::data_offset())); // data.
377 __ lw(T2, Address(SP, 0 * kWordSize)); // Value. 377 __ lw(T2, Address(SP, 0 * kWordSize)); // Value.
378 // Note that T1 is Smi, i.e, times 2. 378 // Note that T1 is Smi, i.e, times 2.
379 ASSERT(kSmiTagShift == 1); 379 ASSERT(kSmiTagShift == 1);
380 __ sll(T1, T1, 1); 380 __ sll(T1, T1, 1);
381 __ addu(T1, T0, T1); 381 __ addu(T1, T0, T1);
382 __ StoreIntoObject(T0, 382 __ StoreIntoObject(T0,
383 FieldAddress(T1, Array::data_offset()), 383 FieldAddress(T1, Array::data_offset()),
384 T2); 384 T2);
385 __ Ret(); 385 __ Ret();
386 __ Bind(&fall_through); 386 __ Bind(&fall_through);
387 } 387 }
388 388
389 389
390 // Set length of growable object array. The length cannot 390 // Set length of growable object array. The length cannot
391 // be greater than the length of the data container. 391 // be greater than the length of the data container.
392 // On stack: growable array (+1), length (+0). 392 // On stack: growable array (+1), length (+0).
393 void Intrinsifier::GrowableArray_setLength(Assembler* assembler) { 393 void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
394 Label fall_through; 394 Label fall_through;
395 __ lw(T1, Address(SP, 0 * kWordSize)); // Length value. 395 __ lw(T1, Address(SP, 0 * kWordSize)); // Length value.
396 __ andi(CMPRES, T1, Immediate(kSmiTagMask)); 396 __ andi(CMPRES, T1, Immediate(kSmiTagMask));
397 __ bne(CMPRES, ZR, &fall_through); // Non-smi length. 397 __ bne(CMPRES, ZR, &fall_through); // Non-smi length.
398 __ delay_slot()->lw(T0, Address(SP, 1 * kWordSize)); // Growable array. 398 __ delay_slot()->lw(T0, Address(SP, 1 * kWordSize)); // Growable array.
399 __ Ret(); 399 __ Ret();
400 __ delay_slot()->sw(T1, 400 __ delay_slot()->sw(T1,
401 FieldAddress(T0, GrowableObjectArray::length_offset())); 401 FieldAddress(T0, GrowableObjectArray::length_offset()));
402 __ Bind(&fall_through); 402 __ Bind(&fall_through);
403 } 403 }
404 404
405 405
406 // Set data of growable object array. 406 // Set data of growable object array.
407 // On stack: growable array (+1), data (+0). 407 // On stack: growable array (+1), data (+0).
408 void Intrinsifier::GrowableArray_setData(Assembler* assembler) { 408 void Intrinsifier::GrowableList_setData(Assembler* assembler) {
409 if (FLAG_enable_type_checks) { 409 if (FLAG_enable_type_checks) {
410 return; 410 return;
411 } 411 }
412 Label fall_through; 412 Label fall_through;
413 __ lw(T1, Address(SP, 0 * kWordSize)); // Data. 413 __ lw(T1, Address(SP, 0 * kWordSize)); // Data.
414 // Check that data is an ObjectArray. 414 // Check that data is an ObjectArray.
415 __ andi(CMPRES, T1, Immediate(kSmiTagMask)); 415 __ andi(CMPRES, T1, Immediate(kSmiTagMask));
416 __ beq(CMPRES, ZR, &fall_through); // Data is Smi. 416 __ beq(CMPRES, ZR, &fall_through); // Data is Smi.
417 __ LoadClassId(CMPRES1, T1); 417 __ LoadClassId(CMPRES1, T1);
418 __ BranchNotEqual(CMPRES1, kArrayCid, &fall_through); 418 __ BranchNotEqual(CMPRES1, kArrayCid, &fall_through);
419 __ lw(T0, Address(SP, 1 * kWordSize)); // Growable array. 419 __ lw(T0, Address(SP, 1 * kWordSize)); // Growable array.
420 __ StoreIntoObject(T0, 420 __ StoreIntoObject(T0,
421 FieldAddress(T0, GrowableObjectArray::data_offset()), 421 FieldAddress(T0, GrowableObjectArray::data_offset()),
422 T1); 422 T1);
423 __ Ret(); 423 __ Ret();
424 __ Bind(&fall_through); 424 __ Bind(&fall_through);
425 } 425 }
426 426
427 427
428 // Add an element to growable array if it doesn't need to grow, otherwise 428 // Add an element to growable array if it doesn't need to grow, otherwise
429 // call into regular code. 429 // call into regular code.
430 // On stack: growable array (+1), value (+0). 430 // On stack: growable array (+1), value (+0).
431 void Intrinsifier::GrowableArray_add(Assembler* assembler) { 431 void Intrinsifier::GrowableList_add(Assembler* assembler) {
432 // In checked mode we need to type-check the incoming argument. 432 // In checked mode we need to type-check the incoming argument.
433 if (FLAG_enable_type_checks) return; 433 if (FLAG_enable_type_checks) return;
434 Label fall_through; 434 Label fall_through;
435 __ lw(T0, Address(SP, 1 * kWordSize)); // Array. 435 __ lw(T0, Address(SP, 1 * kWordSize)); // Array.
436 __ lw(T1, FieldAddress(T0, GrowableObjectArray::length_offset())); 436 __ lw(T1, FieldAddress(T0, GrowableObjectArray::length_offset()));
437 // T1: length. 437 // T1: length.
438 __ lw(T2, FieldAddress(T0, GrowableObjectArray::data_offset())); 438 __ lw(T2, FieldAddress(T0, GrowableObjectArray::data_offset()));
439 // T2: data. 439 // T2: data.
440 __ lw(T3, FieldAddress(T2, Array::length_offset())); 440 __ lw(T3, FieldAddress(T2, Array::length_offset()));
441 // Compare length with capacity. 441 // Compare length with capacity.
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 1734
1735 __ Bind(&ok); 1735 __ Bind(&ok);
1736 __ Ret(); 1736 __ Ret();
1737 1737
1738 __ Bind(&fall_through); 1738 __ Bind(&fall_through);
1739 } 1739 }
1740 1740
1741 } // namespace dart 1741 } // namespace dart
1742 1742
1743 #endif // defined TARGET_ARCH_MIPS 1743 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698