| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 23 matching lines...) Expand all Loading... |
| 34 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; | 34 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; |
| 35 const intptr_t kArrayLengthOffset = 1 * kWordSize; | 35 const intptr_t kArrayLengthOffset = 1 * kWordSize; |
| 36 Label fall_through; | 36 Label fall_through; |
| 37 | 37 |
| 38 // Compute the size to be allocated, it is based on the array length | 38 // Compute the size to be allocated, it is based on the array length |
| 39 // and it computed as: | 39 // and it computed as: |
| 40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
| 41 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. | 41 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. |
| 42 // Assert that length is a Smi. | 42 // Assert that length is a Smi. |
| 43 __ testl(EDI, Immediate(kSmiTagSize)); | 43 __ testl(EDI, Immediate(kSmiTagSize)); |
| 44 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 44 __ j(NOT_ZERO, &fall_through); |
| 45 __ cmpl(EDI, Immediate(0)); | 45 __ cmpl(EDI, Immediate(0)); |
| 46 __ j(LESS, &fall_through, Assembler::kNearJump); | 46 __ j(LESS, &fall_through); |
| 47 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 47 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
| 48 __ leal(EDI, Address(EDI, TIMES_2, fixed_size)); // EDI is a Smi. | 48 __ leal(EDI, Address(EDI, TIMES_2, fixed_size)); // EDI is a Smi. |
| 49 ASSERT(kSmiTagShift == 1); | 49 ASSERT(kSmiTagShift == 1); |
| 50 __ andl(EDI, Immediate(-kObjectAlignment)); | 50 __ andl(EDI, Immediate(-kObjectAlignment)); |
| 51 | 51 |
| 52 Isolate* isolate = Isolate::Current(); | 52 Isolate* isolate = Isolate::Current(); |
| 53 Heap* heap = isolate->heap(); | 53 Heap* heap = isolate->heap(); |
| 54 | 54 |
| 55 // EDI: allocation size. | 55 // EDI: allocation size. |
| 56 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 56 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| 57 __ leal(EBX, Address(EAX, EDI, TIMES_1, 0)); | 57 __ leal(EBX, Address(EAX, EDI, TIMES_1, 0)); |
| 58 | 58 |
| 59 // Check if the allocation fits into the remaining space. | 59 // Check if the allocation fits into the remaining space. |
| 60 // EAX: potential new object start. | 60 // EAX: potential new object start. |
| 61 // EBX: potential next object start. | 61 // EBX: potential next object start. |
| 62 // EDI: allocation size. | 62 // EDI: allocation size. |
| 63 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 63 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
| 64 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 64 __ j(ABOVE_EQUAL, &fall_through); |
| 65 | 65 |
| 66 // Successfully allocated the object(s), now update top to point to | 66 // Successfully allocated the object(s), now update top to point to |
| 67 // next object start and initialize the object. | 67 // next object start and initialize the object. |
| 68 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 68 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 69 __ addl(EAX, Immediate(kHeapObjectTag)); | 69 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 70 | 70 |
| 71 // Initialize the tags. | 71 // Initialize the tags. |
| 72 // EAX: new object start as a tagged pointer. | 72 // EAX: new object start as a tagged pointer. |
| 73 // EBX: new object end address. | 73 // EBX: new object end address. |
| 74 // EDI: allocation size. | 74 // EDI: allocation size. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 86 // Get the class index and insert it into the tags. | 86 // Get the class index and insert it into the tags. |
| 87 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 87 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
| 88 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); | 88 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); |
| 89 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. | 89 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. |
| 90 } | 90 } |
| 91 | 91 |
| 92 // EAX: new object start as a tagged pointer. | 92 // EAX: new object start as a tagged pointer. |
| 93 // EBX: new object end address. | 93 // EBX: new object end address. |
| 94 // Store the type argument field. | 94 // Store the type argument field. |
| 95 __ movl(EDI, Address(ESP, kTypeArgumentsOffset)); // type argument. | 95 __ movl(EDI, Address(ESP, kTypeArgumentsOffset)); // type argument. |
| 96 __ StoreIntoObject(EAX, | 96 __ StoreIntoObjectNoBarrier(EAX, |
| 97 FieldAddress(EAX, Array::type_arguments_offset()), | 97 FieldAddress(EAX, Array::type_arguments_offset()), |
| 98 EDI); | 98 EDI); |
| 99 | 99 |
| 100 // Set the length field. | 100 // Set the length field. |
| 101 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. | 101 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. |
| 102 __ StoreIntoObject(EAX, FieldAddress(EAX, Array::length_offset()), EDI); | 102 __ StoreIntoObjectNoBarrier(EAX, |
| 103 FieldAddress(EAX, Array::length_offset()), |
| 104 EDI); |
| 103 | 105 |
| 104 // Initialize all array elements to raw_null. | 106 // Initialize all array elements to raw_null. |
| 105 // EAX: new object start as a tagged pointer. | 107 // EAX: new object start as a tagged pointer. |
| 106 // EBX: new object end address. | 108 // EBX: new object end address. |
| 107 // EDI: iterator which initially points to the start of the variable | 109 // EDI: iterator which initially points to the start of the variable |
| 108 // data area to be initialized. | 110 // data area to be initialized. |
| 109 const Immediate raw_null = | 111 const Immediate raw_null = |
| 110 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 112 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 111 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); | 113 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); |
| 112 Label done; | 114 Label done; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 | 295 |
| 294 // Store backing array object in growable array object. | 296 // Store backing array object in growable array object. |
| 295 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. | 297 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. |
| 296 __ StoreIntoObject(EAX, | 298 __ StoreIntoObject(EAX, |
| 297 FieldAddress(EAX, GrowableObjectArray::data_offset()), | 299 FieldAddress(EAX, GrowableObjectArray::data_offset()), |
| 298 EBX); | 300 EBX); |
| 299 | 301 |
| 300 // EAX: new growable array object start as a tagged pointer. | 302 // EAX: new growable array object start as a tagged pointer. |
| 301 // Store the type argument field in the growable array object. | 303 // Store the type argument field in the growable array object. |
| 302 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. | 304 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. |
| 303 __ StoreIntoObject(EAX, | 305 __ StoreIntoObjectNoBarrier( |
| 304 FieldAddress(EAX, | 306 EAX, |
| 305 GrowableObjectArray::type_arguments_offset()), | 307 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()), |
| 306 EBX); | 308 EBX); |
| 307 | 309 |
| 308 // Set the length field in the growable array object to 0. | 310 // Set the length field in the growable array object to 0. |
| 309 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), | 311 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), |
| 310 Immediate(0)); | 312 Immediate(0)); |
| 311 __ ret(); // returns the newly allocated object in EAX. | 313 __ ret(); // returns the newly allocated object in EAX. |
| 312 | 314 |
| 313 __ Bind(&fall_through); | 315 __ Bind(&fall_through); |
| 314 return false; | 316 return false; |
| 315 } | 317 } |
| 316 | 318 |
| (...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1248 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); // Range check. | 1250 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); // Range check. |
| 1249 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 1251 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 1250 | 1252 |
| 1251 // EBX is Smi, i.e, times 2. | 1253 // EBX is Smi, i.e, times 2. |
| 1252 ASSERT(kSmiTagShift == 1); | 1254 ASSERT(kSmiTagShift == 1); |
| 1253 __ movl(EDI, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); // Result. | 1255 __ movl(EDI, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); // Result. |
| 1254 const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); | 1256 const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); |
| 1255 __ addl(EBX, value); // _pos++. | 1257 __ addl(EBX, value); // _pos++. |
| 1256 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); | 1258 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); |
| 1257 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver. | 1259 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver. |
| 1258 __ StoreIntoObject(EAX, FieldAddress(EAX, pos_offset), EBX); // Store _pos. | 1260 __ StoreIntoObjectNoBarrier(EAX, |
| 1261 FieldAddress(EAX, pos_offset), |
| 1262 EBX); // Store _pos. |
| 1259 __ movl(EAX, EDI); | 1263 __ movl(EAX, EDI); |
| 1260 __ ret(); | 1264 __ ret(); |
| 1261 __ Bind(&fall_through); | 1265 __ Bind(&fall_through); |
| 1262 return false; | 1266 return false; |
| 1263 } | 1267 } |
| 1264 | 1268 |
| 1265 | 1269 |
| 1266 // Class 'FixedSizeArrayIterator': | 1270 // Class 'FixedSizeArrayIterator': |
| 1267 // bool hasNext() { | 1271 // bool hasNext() { |
| 1268 // return _length > _pos; | 1272 // return _length > _pos; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1351 __ Bind(&is_true); | 1355 __ Bind(&is_true); |
| 1352 __ LoadObject(EAX, bool_true); | 1356 __ LoadObject(EAX, bool_true); |
| 1353 __ ret(); | 1357 __ ret(); |
| 1354 return true; | 1358 return true; |
| 1355 } | 1359 } |
| 1356 | 1360 |
| 1357 #undef __ | 1361 #undef __ |
| 1358 } // namespace dart | 1362 } // namespace dart |
| 1359 | 1363 |
| 1360 #endif // defined TARGET_ARCH_IA32 | 1364 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |