| OLD | NEW |
| 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 __ addl(EDI, Immediate(kWordSize)); | 129 __ addl(EDI, Immediate(kWordSize)); |
| 130 __ jmp(&init_loop, Assembler::kNearJump); | 130 __ jmp(&init_loop, Assembler::kNearJump); |
| 131 __ Bind(&done); | 131 __ Bind(&done); |
| 132 __ ret(); // returns the newly allocated object in EAX. | 132 __ ret(); // returns the newly allocated object in EAX. |
| 133 | 133 |
| 134 __ Bind(&fall_through); | 134 __ Bind(&fall_through); |
| 135 return false; | 135 return false; |
| 136 } | 136 } |
| 137 | 137 |
| 138 | 138 |
| 139 bool Intrinsifier::Array_getLength(Assembler* assembler) { | |
| 140 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | |
| 141 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); | |
| 142 __ ret(); | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 | |
| 147 bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) { | |
| 148 return Array_getLength(assembler); | |
| 149 } | |
| 150 | |
| 151 | |
| 152 bool Intrinsifier::Array_getIndexed(Assembler* assembler) { | 139 bool Intrinsifier::Array_getIndexed(Assembler* assembler) { |
| 153 Label fall_through; | 140 Label fall_through; |
| 154 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. | 141 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. |
| 155 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. | 142 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. |
| 156 __ testl(EBX, Immediate(kSmiTagMask)); | 143 __ testl(EBX, Immediate(kSmiTagMask)); |
| 157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 144 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 158 // Range check. | 145 // Range check. |
| 159 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); | 146 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); |
| 160 // Runtime throws exception. | 147 // Runtime throws exception. |
| 161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 148 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 // Set the length field in the growable array object to 0. | 295 // Set the length field in the growable array object to 0. |
| 309 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), | 296 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), |
| 310 Immediate(0)); | 297 Immediate(0)); |
| 311 __ ret(); // returns the newly allocated object in EAX. | 298 __ ret(); // returns the newly allocated object in EAX. |
| 312 | 299 |
| 313 __ Bind(&fall_through); | 300 __ Bind(&fall_through); |
| 314 return false; | 301 return false; |
| 315 } | 302 } |
| 316 | 303 |
| 317 | 304 |
| 318 // Get length of growable object array. | |
| 319 // On stack: growable array (+1), return-address (+0). | |
| 320 bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) { | |
| 321 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | |
| 322 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset())); | |
| 323 __ ret(); | |
| 324 return true; | |
| 325 } | |
| 326 | |
| 327 | |
| 328 // Get capacity of growable object array. | 305 // Get capacity of growable object array. |
| 329 // On stack: growable array (+1), return-address (+0). | 306 // On stack: growable array (+1), return-address (+0). |
| 330 bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { | 307 bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { |
| 331 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 308 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 332 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); | 309 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); |
| 333 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); | 310 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); |
| 334 __ ret(); | 311 __ ret(); |
| 335 return true; | 312 return true; |
| 336 } | 313 } |
| 337 | 314 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ | 522 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ |
| 546 __ movl(Address(EDI, 0), ECX); \ | 523 __ movl(Address(EDI, 0), ECX); \ |
| 547 __ addl(EDI, Immediate(kWordSize)); \ | 524 __ addl(EDI, Immediate(kWordSize)); \ |
| 548 __ jmp(&init_loop, Assembler::kNearJump); \ | 525 __ jmp(&init_loop, Assembler::kNearJump); \ |
| 549 __ Bind(&done); \ | 526 __ Bind(&done); \ |
| 550 \ | 527 \ |
| 551 __ ret(); \ | 528 __ ret(); \ |
| 552 __ Bind(&fall_through); \ | 529 __ Bind(&fall_through); \ |
| 553 | 530 |
| 554 | 531 |
| 555 | |
| 556 // Gets the length of a TypedData. | |
| 557 bool Intrinsifier::TypedData_getLength(Assembler* assembler) { | |
| 558 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | |
| 559 __ movl(EAX, FieldAddress(EAX, TypedData::length_offset())); | |
| 560 __ ret(); | |
| 561 return true; | |
| 562 } | |
| 563 | |
| 564 | |
| 565 static ScaleFactor GetScaleFactor(intptr_t size) { | 532 static ScaleFactor GetScaleFactor(intptr_t size) { |
| 566 switch (size) { | 533 switch (size) { |
| 567 case 1: return TIMES_1; | 534 case 1: return TIMES_1; |
| 568 case 2: return TIMES_2; | 535 case 2: return TIMES_2; |
| 569 case 4: return TIMES_4; | 536 case 4: return TIMES_4; |
| 570 case 8: return TIMES_8; | 537 case 8: return TIMES_8; |
| 571 case 16: return TIMES_16; | 538 case 16: return TIMES_16; |
| 572 } | 539 } |
| 573 UNREACHABLE(); | 540 UNREACHABLE(); |
| 574 return static_cast<ScaleFactor>(0); | 541 return static_cast<ScaleFactor>(0); |
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); | 1462 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); |
| 1496 __ cmpl(EAX, Immediate(0)); | 1463 __ cmpl(EAX, Immediate(0)); |
| 1497 __ j(EQUAL, &fall_through, Assembler::kNearJump); | 1464 __ j(EQUAL, &fall_through, Assembler::kNearJump); |
| 1498 __ ret(); | 1465 __ ret(); |
| 1499 __ Bind(&fall_through); | 1466 __ Bind(&fall_through); |
| 1500 // Hash not yet computed. | 1467 // Hash not yet computed. |
| 1501 return false; | 1468 return false; |
| 1502 } | 1469 } |
| 1503 | 1470 |
| 1504 | 1471 |
| 1505 bool Intrinsifier::String_getLength(Assembler* assembler) { | |
| 1506 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. | |
| 1507 __ movl(EAX, FieldAddress(EAX, String::length_offset())); | |
| 1508 __ ret(); | |
| 1509 return true; | |
| 1510 } | |
| 1511 | |
| 1512 | |
| 1513 bool Intrinsifier::String_codeUnitAt(Assembler* assembler) { | 1472 bool Intrinsifier::String_codeUnitAt(Assembler* assembler) { |
| 1514 Label fall_through, try_two_byte_string; | 1473 Label fall_through, try_two_byte_string; |
| 1515 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. | 1474 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. |
| 1516 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String. | 1475 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String. |
| 1517 __ testl(EBX, Immediate(kSmiTagMask)); | 1476 __ testl(EBX, Immediate(kSmiTagMask)); |
| 1518 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 1477 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 1519 // Range check. | 1478 // Range check. |
| 1520 __ cmpl(EBX, FieldAddress(EAX, String::length_offset())); | 1479 __ cmpl(EBX, FieldAddress(EAX, String::length_offset())); |
| 1521 // Runtime throws exception. | 1480 // Runtime throws exception. |
| 1522 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 1481 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1769 __ ret(); | 1728 __ ret(); |
| 1770 | 1729 |
| 1771 __ Bind(&fall_through); | 1730 __ Bind(&fall_through); |
| 1772 return false; | 1731 return false; |
| 1773 } | 1732 } |
| 1774 | 1733 |
| 1775 #undef __ | 1734 #undef __ |
| 1776 } // namespace dart | 1735 } // namespace dart |
| 1777 | 1736 |
| 1778 #endif // defined TARGET_ARCH_IA32 | 1737 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |