| 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. | 154 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. |
| 155 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. | 155 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. |
| 156 __ testl(EBX, Immediate(kSmiTagMask)); | 156 __ testl(EBX, Immediate(kSmiTagMask)); |
| 157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 158 // Range check. | 158 // Range check. |
| 159 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); | 159 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); |
| 160 // Runtime throws exception. | 160 // Runtime throws exception. |
| 161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 162 // Note that EBX is Smi, i.e, times 2. | 162 // Note that EBX is Smi, i.e, times 2. |
| 163 ASSERT(kSmiTagShift == 1); | 163 ASSERT(kSmiTagShift == 1); |
| 164 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); | 164 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); |
| 165 __ ret(); | 165 __ ret(); |
| 166 __ Bind(&fall_through); | 166 __ Bind(&fall_through); |
| 167 return false; | 167 return false; |
| 168 } | 168 } |
| 169 | 169 |
| 170 | 170 |
| 171 bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { | 171 bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { |
| 172 return Array_getIndexed(assembler); | 172 return Array_getIndexed(assembler); |
| 173 } | 173 } |
| 174 | 174 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. | 231 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. |
| 232 // Range check. | 232 // Range check. |
| 233 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); | 233 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); |
| 234 // Runtime throws exception. | 234 // Runtime throws exception. |
| 235 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 235 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 236 // Note that EBX is Smi, i.e, times 2. | 236 // Note that EBX is Smi, i.e, times 2. |
| 237 ASSERT(kSmiTagShift == 1); | 237 ASSERT(kSmiTagShift == 1); |
| 238 // Destroy ECX as we will not continue in the function. | 238 // Destroy ECX as we will not continue in the function. |
| 239 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. | 239 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. |
| 240 __ StoreIntoObject(EAX, | 240 __ StoreIntoObject(EAX, |
| 241 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), | 241 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), |
| 242 ECX); | 242 ECX); |
| 243 // Caller is responsible of preserving the value if necessary. | 243 // Caller is responsible of preserving the value if necessary. |
| 244 __ ret(); | 244 __ ret(); |
| 245 __ Bind(&fall_through); | 245 __ Bind(&fall_through); |
| 246 return false; | 246 return false; |
| 247 } | 247 } |
| 248 | 248 |
| 249 | 249 |
| 250 // Allocate a GrowableObjectArray using the backing array specified. | 250 // Allocate a GrowableObjectArray using the backing array specified. |
| 251 // On stack: type argument (+2), data (+1), return-address (+0). | 251 // On stack: type argument (+2), data (+1), return-address (+0). |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 __ testl(EBX, Immediate(kSmiTagMask)); | 343 __ testl(EBX, Immediate(kSmiTagMask)); |
| 344 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 344 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 345 // Range check using _length field. | 345 // Range check using _length field. |
| 346 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); | 346 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 347 // Runtime throws exception. | 347 // Runtime throws exception. |
| 348 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 348 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 349 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. | 349 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. |
| 350 | 350 |
| 351 // Note that EBX is Smi, i.e, times 2. | 351 // Note that EBX is Smi, i.e, times 2. |
| 352 ASSERT(kSmiTagShift == 1); | 352 ASSERT(kSmiTagShift == 1); |
| 353 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); | 353 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); |
| 354 __ ret(); | 354 __ ret(); |
| 355 __ Bind(&fall_through); | 355 __ Bind(&fall_through); |
| 356 return false; | 356 return false; |
| 357 } | 357 } |
| 358 | 358 |
| 359 | 359 |
| 360 // Set value into growable object array at specified index. | 360 // Set value into growable object array at specified index. |
| 361 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). | 361 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). |
| 362 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { | 362 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { |
| 363 if (FLAG_enable_type_checks) { | 363 if (FLAG_enable_type_checks) { |
| 364 return false; | 364 return false; |
| 365 } | 365 } |
| 366 Label fall_through; | 366 Label fall_through; |
| 367 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. | 367 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. |
| 368 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. | 368 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. |
| 369 __ testl(EBX, Immediate(kSmiTagMask)); | 369 __ testl(EBX, Immediate(kSmiTagMask)); |
| 370 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 370 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 371 // Range check using _length field. | 371 // Range check using _length field. |
| 372 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); | 372 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 373 // Runtime throws exception. | 373 // Runtime throws exception. |
| 374 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 374 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 375 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. | 375 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. |
| 376 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. | 376 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. |
| 377 // Note that EBX is Smi, i.e, times 2. | 377 // Note that EBX is Smi, i.e, times 2. |
| 378 ASSERT(kSmiTagShift == 1); | 378 ASSERT(kSmiTagShift == 1); |
| 379 __ StoreIntoObject(EAX, | 379 __ StoreIntoObject(EAX, |
| 380 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), | 380 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), |
| 381 EDI); | 381 EDI); |
| 382 __ ret(); | 382 __ ret(); |
| 383 __ Bind(&fall_through); | 383 __ Bind(&fall_through); |
| 384 return false; | 384 return false; |
| 385 } | 385 } |
| 386 | 386 |
| 387 | 387 |
| 388 // Set length of growable object array. | 388 // Set length of growable object array. |
| 389 // On stack: growable array (+2), length (+1), return-address (+0). | 389 // On stack: growable array (+2), length (+1), return-address (+0). |
| 390 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) { | 390 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 // EDI: data. | 440 // EDI: data. |
| 441 // Compare length with capacity. | 441 // Compare length with capacity. |
| 442 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); | 442 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); |
| 443 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. | 443 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. |
| 444 const Immediate value_one = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); | 444 const Immediate value_one = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); |
| 445 // len = len + 1; | 445 // len = len + 1; |
| 446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one); | 446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one); |
| 447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value | 447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value |
| 448 ASSERT(kSmiTagShift == 1); | 448 ASSERT(kSmiTagShift == 1); |
| 449 __ StoreIntoObject(EDI, | 449 __ StoreIntoObject(EDI, |
| 450 FieldAddress(EDI, EBX, TIMES_2, sizeof(RawArray)), | 450 FieldAddress(EDI, EBX, TIMES_2, Array::data_offset()), |
| 451 EAX); | 451 EAX); |
| 452 const Immediate raw_null = | 452 const Immediate raw_null = |
| 453 Immediate(reinterpret_cast<int32_t>(Object::null())); | 453 Immediate(reinterpret_cast<int32_t>(Object::null())); |
| 454 __ movl(EAX, raw_null); | 454 __ movl(EAX, raw_null); |
| 455 __ ret(); | 455 __ ret(); |
| 456 __ Bind(&fall_through); | 456 __ Bind(&fall_through); |
| 457 return false; | 457 return false; |
| 458 } | 458 } |
| 459 | 459 |
| 460 | 460 |
| (...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1672 __ Bind(&is_true); | 1672 __ Bind(&is_true); |
| 1673 __ LoadObject(EAX, Bool::True()); | 1673 __ LoadObject(EAX, Bool::True()); |
| 1674 __ ret(); | 1674 __ ret(); |
| 1675 return true; | 1675 return true; |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 #undef __ | 1678 #undef __ |
| 1679 } // namespace dart | 1679 } // namespace dart |
| 1680 | 1680 |
| 1681 #endif // defined TARGET_ARCH_IA32 | 1681 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |