| 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 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 | 1568 |
| 1569 | 1569 |
| 1570 // Arg0: Onebyte String | 1570 // Arg0: Onebyte String |
| 1571 // Arg1: Start index as Smi. | 1571 // Arg1: Start index as Smi. |
| 1572 // Arg2: End index as Smi. | 1572 // Arg2: End index as Smi. |
| 1573 // The indexes must be valid. | 1573 // The indexes must be valid. |
| 1574 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) { | 1574 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) { |
| 1575 const intptr_t kStringOffset = 3 * kWordSize; | 1575 const intptr_t kStringOffset = 3 * kWordSize; |
| 1576 const intptr_t kStartIndexOffset = 2 * kWordSize; | 1576 const intptr_t kStartIndexOffset = 2 * kWordSize; |
| 1577 const intptr_t kEndIndexOffset = 1 * kWordSize; | 1577 const intptr_t kEndIndexOffset = 1 * kWordSize; |
| 1578 Label fall_through, done; | 1578 Label fall_through; |
| 1579 TryAllocateOnebyteString( | 1579 TryAllocateOnebyteString( |
| 1580 assembler, &fall_through, kStartIndexOffset, kEndIndexOffset); | 1580 assembler, &fall_through, kStartIndexOffset, kEndIndexOffset); |
| 1581 // EAX: new string as tagged pointer. | 1581 // EAX: new string as tagged pointer. |
| 1582 // Copy string. | 1582 // Copy string. |
| 1583 __ movl(EDI, Address(ESP, + kStringOffset)); | 1583 __ movl(EDI, Address(ESP, + kStringOffset)); |
| 1584 __ movl(EBX, Address(ESP, + kStartIndexOffset)); | 1584 __ movl(EBX, Address(ESP, + kStartIndexOffset)); |
| 1585 __ SmiUntag(EBX); | 1585 __ SmiUntag(EBX); |
| 1586 __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1, OneByteString::data_offset())); | 1586 __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1, OneByteString::data_offset())); |
| 1587 // EDI: Start address to copy from (untagged). | 1587 // EDI: Start address to copy from (untagged). |
| 1588 __ movl(EDX, Address(ESP, + kEndIndexOffset)); | 1588 // EBX: Untagged start index. |
| 1589 __ SmiUntag(EDX); | 1589 __ movl(ECX, Address(ESP, + kEndIndexOffset)); |
| 1590 __ subl(EDX, EBX); | 1590 __ SmiUntag(ECX); |
| 1591 __ xorl(ECX, ECX); | 1591 __ subl(ECX, EBX); |
| 1592 // EDX: Number of bytes to copy. | 1592 // ECX: Untagged number of bytes to copy. |
| 1593 // ECX: Loop counter. | 1593 ASSERT(CTX == ESI); |
| 1594 // TODO(srdjan): For large substrings it could be better if we would group | 1594 __ pushl(ESI); // Preserve CTX. |
| 1595 // the byte copies into word copies or even call memcpy. | 1595 __ movl(ESI, EDI); // from. |
| 1596 Label loop, check; | 1596 __ leal(EDI, FieldAddress(EAX, OneByteString::data_offset())); // to. |
| 1597 // TODO(srdjan): Use rep movsb instead. | 1597 __ rep_movsb(); |
| 1598 __ jmp(&check, Assembler::kNearJump); | 1598 __ popl(ESI); // Restore CTX. |
| 1599 __ Bind(&loop); | |
| 1600 __ movzxb(EBX, Address(EDI, ECX, TIMES_1, 0)); | |
| 1601 __ movb(FieldAddress(EAX, ECX, TIMES_1, OneByteString::data_offset()), BL); | |
| 1602 __ incl(ECX); | |
| 1603 __ Bind(&check); | |
| 1604 __ cmpl(ECX, EDX); | |
| 1605 __ j(LESS, &loop, Assembler::kNearJump); | |
| 1606 | 1599 |
| 1607 __ Bind(&done); | |
| 1608 __ ret(); | 1600 __ ret(); |
| 1609 __ Bind(&fall_through); | 1601 __ Bind(&fall_through); |
| 1610 return false; | 1602 return false; |
| 1611 } | 1603 } |
| 1612 | 1604 |
| 1613 #undef __ | 1605 #undef __ |
| 1614 } // namespace dart | 1606 } // namespace dart |
| 1615 | 1607 |
| 1616 #endif // defined TARGET_ARCH_IA32 | 1608 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |