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

Side by Side Diff: runtime/vm/intrinsifier_ia32.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 // The intrinsic code below is executed before a method has built its frame. 5 // The intrinsic code below is executed before a method has built its frame.
6 // The return address is on the stack and the arguments below it. 6 // The return address is on the stack and the arguments below it.
7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved.
8 // Each intrinsification method returns true if the corresponding 8 // Each intrinsification method returns true if the corresponding
9 // Dart method was intrinsified. 9 // Dart method was intrinsified.
10 10
(...skipping 10 matching lines...) Expand all
21 #include "vm/stub_code.h" 21 #include "vm/stub_code.h"
22 #include "vm/symbols.h" 22 #include "vm/symbols.h"
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DECLARE_FLAG(bool, enable_type_checks); 26 DECLARE_FLAG(bool, enable_type_checks);
27 27
28 28
29 #define __ assembler-> 29 #define __ assembler->
30 30
31 void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) { 31 void Intrinsifier::List_Allocate(Assembler* assembler) {
32 // This snippet of inlined code uses the following registers: 32 // This snippet of inlined code uses the following registers:
33 // EAX, EBX, EDI 33 // EAX, EBX, EDI
34 // and the newly allocated object is returned in EAX. 34 // and the newly allocated object is returned in EAX.
35 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 35 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
36 const intptr_t kArrayLengthOffset = 1 * kWordSize; 36 const intptr_t kArrayLengthOffset = 1 * kWordSize;
37 Label fall_through; 37 Label fall_through;
38 38
39 // Compute the size to be allocated, it is based on the array length 39 // Compute the size to be allocated, it is based on the array length
40 // and is computed as: 40 // and is computed as:
41 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 41 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 135 }
136 136
137 137
138 void Intrinsifier::Array_getLength(Assembler* assembler) { 138 void Intrinsifier::Array_getLength(Assembler* assembler) {
139 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 139 __ movl(EAX, Address(ESP, + 1 * kWordSize));
140 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); 140 __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
141 __ ret(); 141 __ ret();
142 } 142 }
143 143
144 144
145 void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) { 145 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
146 return Array_getLength(assembler); 146 return Array_getLength(assembler);
147 } 147 }
148 148
149 149
150 void Intrinsifier::Array_getIndexed(Assembler* assembler) { 150 void Intrinsifier::Array_getIndexed(Assembler* assembler) {
151 Label fall_through; 151 Label fall_through;
152 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 152 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
153 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 153 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
154 __ testl(EBX, Immediate(kSmiTagMask)); 154 __ testl(EBX, Immediate(kSmiTagMask));
155 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 155 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
156 // Range check. 156 // Range check.
157 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); 157 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
158 // Runtime throws exception. 158 // Runtime throws exception.
159 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 159 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
160 // Note that EBX is Smi, i.e, times 2. 160 // Note that EBX is Smi, i.e, times 2.
161 ASSERT(kSmiTagShift == 1); 161 ASSERT(kSmiTagShift == 1);
162 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); 162 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()));
163 __ ret(); 163 __ ret();
164 __ Bind(&fall_through); 164 __ Bind(&fall_through);
165 } 165 }
166 166
167 167
168 void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { 168 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
169 return Array_getIndexed(assembler); 169 return Array_getIndexed(assembler);
170 } 170 }
171 171
172 172
173 static intptr_t ComputeObjectArrayTypeArgumentsOffset() { 173 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
174 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 174 const Library& core_lib = Library::Handle(Library::CoreLibrary());
175 const Class& cls = Class::Handle( 175 const Class& cls = Class::Handle(
176 core_lib.LookupClassAllowPrivate(Symbols::ObjectArray())); 176 core_lib.LookupClassAllowPrivate(Symbols::_List()));
177 ASSERT(!cls.IsNull()); 177 ASSERT(!cls.IsNull());
178 ASSERT(cls.HasTypeArguments()); 178 ASSERT(cls.HasTypeArguments());
179 ASSERT(cls.NumTypeArguments() == 1); 179 ASSERT(cls.NumTypeArguments() == 1);
180 const intptr_t field_offset = cls.type_arguments_field_offset(); 180 const intptr_t field_offset = cls.type_arguments_field_offset();
181 ASSERT(field_offset != Class::kNoTypeArguments); 181 ASSERT(field_offset != Class::kNoTypeArguments);
182 return field_offset; 182 return field_offset;
183 } 183 }
184 184
185 185
186 // Intrinsify only for Smi value and index. Non-smi values need a store buffer 186 // Intrinsify only for Smi value and index. Non-smi values need a store buffer
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), 238 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()),
239 ECX); 239 ECX);
240 // Caller is responsible of preserving the value if necessary. 240 // Caller is responsible of preserving the value if necessary.
241 __ ret(); 241 __ ret();
242 __ Bind(&fall_through); 242 __ Bind(&fall_through);
243 } 243 }
244 244
245 245
246 // Allocate a GrowableObjectArray using the backing array specified. 246 // Allocate a GrowableObjectArray using the backing array specified.
247 // On stack: type argument (+2), data (+1), return-address (+0). 247 // On stack: type argument (+2), data (+1), return-address (+0).
248 void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) { 248 void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
249 // This snippet of inlined code uses the following registers: 249 // This snippet of inlined code uses the following registers:
250 // EAX, EBX 250 // EAX, EBX
251 // and the newly allocated object is returned in EAX. 251 // and the newly allocated object is returned in EAX.
252 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 252 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
253 const intptr_t kArrayOffset = 1 * kWordSize; 253 const intptr_t kArrayOffset = 1 * 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)) +
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), 305 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()),
306 Immediate(0)); 306 Immediate(0));
307 __ ret(); // returns the newly allocated object in EAX. 307 __ ret(); // returns the newly allocated object in EAX.
308 308
309 __ Bind(&fall_through); 309 __ Bind(&fall_through);
310 } 310 }
311 311
312 312
313 // Get length of growable object array. 313 // Get length of growable object array.
314 // On stack: growable array (+1), return-address (+0). 314 // On stack: growable array (+1), return-address (+0).
315 void Intrinsifier::GrowableArray_getLength(Assembler* assembler) { 315 void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
316 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 316 __ movl(EAX, Address(ESP, + 1 * kWordSize));
317 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 317 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
318 __ ret(); 318 __ ret();
319 } 319 }
320 320
321 321
322 // Get capacity of growable object array. 322 // Get capacity of growable object array.
323 // On stack: growable array (+1), return-address (+0). 323 // On stack: growable array (+1), return-address (+0).
324 void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { 324 void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
325 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 325 __ movl(EAX, Address(ESP, + 1 * kWordSize));
326 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); 326 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
327 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); 327 __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
328 __ ret(); 328 __ ret();
329 } 329 }
330 330
331 331
332 // Access growable object array at specified index. 332 // Access growable object array at specified index.
333 // On stack: growable array (+2), index (+1), return-address (+0). 333 // On stack: growable array (+2), index (+1), return-address (+0).
334 void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) { 334 void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
335 Label fall_through; 335 Label fall_through;
336 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 336 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
337 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray. 337 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray.
338 __ testl(EBX, Immediate(kSmiTagMask)); 338 __ testl(EBX, Immediate(kSmiTagMask));
339 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 339 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
340 // Range check using _length field. 340 // Range check using _length field.
341 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 341 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
342 // Runtime throws exception. 342 // Runtime throws exception.
343 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 343 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
344 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. 344 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data.
345 345
346 // Note that EBX is Smi, i.e, times 2. 346 // Note that EBX is Smi, i.e, times 2.
347 ASSERT(kSmiTagShift == 1); 347 ASSERT(kSmiTagShift == 1);
348 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); 348 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()));
349 __ ret(); 349 __ ret();
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 (+3), index (+2), value (+1), return-address (+0). 355 // On stack: growable array (+3), index (+2), value (+1), return-address (+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 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. 361 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
362 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. 362 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray.
363 __ testl(EBX, Immediate(kSmiTagMask)); 363 __ testl(EBX, Immediate(kSmiTagMask));
364 __ j(NOT_ZERO, &fall_through); // Non-smi index. 364 __ j(NOT_ZERO, &fall_through); // Non-smi index.
365 // Range check using _length field. 365 // Range check using _length field.
366 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 366 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
367 // Runtime throws exception. 367 // Runtime throws exception.
368 __ j(ABOVE_EQUAL, &fall_through); 368 __ j(ABOVE_EQUAL, &fall_through);
369 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. 369 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data.
370 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. 370 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value.
371 // Note that EBX is Smi, i.e, times 2. 371 // Note that EBX is Smi, i.e, times 2.
372 ASSERT(kSmiTagShift == 1); 372 ASSERT(kSmiTagShift == 1);
373 __ StoreIntoObject(EAX, 373 __ StoreIntoObject(EAX,
374 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), 374 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()),
375 EDI); 375 EDI);
376 __ ret(); 376 __ ret();
377 __ Bind(&fall_through); 377 __ Bind(&fall_through);
378 } 378 }
379 379
380 380
381 // Set length of growable object array. The length cannot 381 // Set length of growable object array. The length cannot
382 // be greater than the length of the data container. 382 // be greater than the length of the data container.
383 // On stack: growable array (+2), length (+1), return-address (+0). 383 // On stack: growable array (+2), length (+1), return-address (+0).
384 void Intrinsifier::GrowableArray_setLength(Assembler* assembler) { 384 void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
385 Label fall_through; 385 Label fall_through;
386 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. 386 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array.
387 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Length value. 387 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Length value.
388 __ testl(EBX, Immediate(kSmiTagMask)); 388 __ testl(EBX, Immediate(kSmiTagMask));
389 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. 389 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length.
390 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX); 390 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX);
391 __ ret(); 391 __ ret();
392 __ Bind(&fall_through); 392 __ Bind(&fall_through);
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 (+2), data (+1), return-address (+0). 397 // On stack: growable array (+2), data (+1), return-address (+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 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data. 403 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data.
404 // Check that data is an ObjectArray. 404 // Check that data is an ObjectArray.
405 __ testl(EBX, Immediate(kSmiTagMask)); 405 __ testl(EBX, Immediate(kSmiTagMask));
406 __ j(ZERO, &fall_through); // Data is Smi. 406 __ j(ZERO, &fall_through); // Data is Smi.
407 __ CompareClassId(EBX, kArrayCid, EAX); 407 __ CompareClassId(EBX, kArrayCid, EAX);
408 __ j(NOT_EQUAL, &fall_through); 408 __ j(NOT_EQUAL, &fall_through);
409 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. 409 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array.
410 __ StoreIntoObject(EAX, 410 __ StoreIntoObject(EAX,
411 FieldAddress(EAX, GrowableObjectArray::data_offset()), 411 FieldAddress(EAX, GrowableObjectArray::data_offset()),
412 EBX); 412 EBX);
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 (+2), value (+1), return-address (+0). 420 // On stack: growable array (+2), value (+1), return-address (+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 424
425 Label fall_through; 425 Label fall_through;
426 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. 426 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
427 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 427 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
428 // EBX: length. 428 // EBX: length.
429 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset())); 429 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset()));
430 // EDI: data. 430 // EDI: data.
431 // Compare length with capacity. 431 // Compare length with capacity.
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 __ Bind(&ok); 1733 __ Bind(&ok);
1734 __ ret(); 1734 __ ret();
1735 1735
1736 __ Bind(&fall_through); 1736 __ Bind(&fall_through);
1737 } 1737 }
1738 1738
1739 #undef __ 1739 #undef __
1740 } // namespace dart 1740 } // namespace dart
1741 1741
1742 #endif // defined TARGET_ARCH_IA32 1742 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698