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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
9 | 9 |
10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
(...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); | 1588 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); |
1589 ASSERT(kSmiTagShift == 1); | 1589 ASSERT(kSmiTagShift == 1); |
1590 __ movzxw(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset())); | 1590 __ movzxw(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset())); |
1591 __ SmiTag(RAX); | 1591 __ SmiTag(RAX); |
1592 __ ret(); | 1592 __ ret(); |
1593 | 1593 |
1594 __ Bind(&fall_through); | 1594 __ Bind(&fall_through); |
1595 } | 1595 } |
1596 | 1596 |
1597 | 1597 |
| 1598 void GenerateSubstringMatchesSpecialization(Assembler* assembler, |
| 1599 intptr_t receiver_cid, |
| 1600 intptr_t other_cid, |
| 1601 Label* return_true, |
| 1602 Label* return_false) { |
| 1603 __ movq(R8, FieldAddress(RAX, String::length_offset())); |
| 1604 __ movq(R9, FieldAddress(RCX, String::length_offset())); |
| 1605 |
| 1606 // if (other.length == 0) return true; |
| 1607 __ testq(R9, R9); |
| 1608 __ j(ZERO, return_true); |
| 1609 |
| 1610 // if (start < 0) return false; |
| 1611 __ testq(RBX, RBX); |
| 1612 __ j(SIGN, return_false); |
| 1613 |
| 1614 // if (start + other.length > this.length) return false; |
| 1615 __ movq(R11, RBX); |
| 1616 __ addq(R11, R9); |
| 1617 __ cmpq(R11, R8); |
| 1618 __ j(GREATER, return_false); |
| 1619 |
| 1620 __ SmiUntag(RBX); // start |
| 1621 __ SmiUntag(R9); // other.length |
| 1622 __ movq(R11, Immediate(0)); // i = 0 |
| 1623 |
| 1624 // do |
| 1625 Label loop; |
| 1626 __ Bind(&loop); |
| 1627 |
| 1628 // this.codeUnitAt(i + start) |
| 1629 // clobbering this.length |
| 1630 __ movq(R8, R11); |
| 1631 __ addq(R8, RBX); |
| 1632 if (receiver_cid == kOneByteStringCid) { |
| 1633 __ movzxb(R12, |
| 1634 FieldAddress(RAX, R8, TIMES_1, OneByteString::data_offset())); |
| 1635 } else { |
| 1636 ASSERT(receiver_cid == kTwoByteStringCid); |
| 1637 __ movzxw(R12, |
| 1638 FieldAddress(RAX, R8, TIMES_2, TwoByteString::data_offset())); |
| 1639 } |
| 1640 // other.codeUnitAt(i) |
| 1641 if (other_cid == kOneByteStringCid) { |
| 1642 __ movzxb(R13, |
| 1643 FieldAddress(RCX, R11, TIMES_1, OneByteString::data_offset())); |
| 1644 } else { |
| 1645 ASSERT(other_cid == kTwoByteStringCid); |
| 1646 __ movzxw(R13, |
| 1647 FieldAddress(RCX, R11, TIMES_2, TwoByteString::data_offset())); |
| 1648 } |
| 1649 __ cmpq(R12, R13); |
| 1650 __ j(NOT_EQUAL, return_false); |
| 1651 |
| 1652 // i++, while (i < len) |
| 1653 __ addq(R11, Immediate(1)); |
| 1654 __ cmpq(R11, R9); |
| 1655 __ j(LESS, &loop, Assembler::kNearJump); |
| 1656 |
| 1657 __ jmp(return_true); |
| 1658 } |
| 1659 |
| 1660 |
| 1661 // bool _substringMatches(int start, String other) |
| 1662 // This intrinsic handles a OneByteString or TwoByteString receiver with a |
| 1663 // OneByteString other. |
| 1664 void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) { |
| 1665 Label fall_through, return_true, return_false, try_two_byte; |
| 1666 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // receiver |
| 1667 __ movq(RBX, Address(RSP, + 2 * kWordSize)); // start |
| 1668 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // other |
| 1669 |
| 1670 __ testq(RBX, Immediate(kSmiTagMask)); |
| 1671 __ j(NOT_ZERO, &fall_through); // 'start' is not Smi. |
| 1672 |
| 1673 __ CompareClassId(RCX, kOneByteStringCid); |
| 1674 __ j(NOT_EQUAL, &fall_through); |
| 1675 |
| 1676 __ CompareClassId(RAX, kOneByteStringCid); |
| 1677 __ j(NOT_EQUAL, &try_two_byte); |
| 1678 |
| 1679 GenerateSubstringMatchesSpecialization(assembler, |
| 1680 kOneByteStringCid, |
| 1681 kOneByteStringCid, |
| 1682 &return_true, |
| 1683 &return_false); |
| 1684 |
| 1685 __ Bind(&try_two_byte); |
| 1686 __ CompareClassId(RAX, kTwoByteStringCid); |
| 1687 __ j(NOT_EQUAL, &fall_through); |
| 1688 |
| 1689 GenerateSubstringMatchesSpecialization(assembler, |
| 1690 kTwoByteStringCid, |
| 1691 kOneByteStringCid, |
| 1692 &return_true, |
| 1693 &return_false); |
| 1694 |
| 1695 __ Bind(&return_true); |
| 1696 __ LoadObject(RAX, Bool::True()); |
| 1697 __ ret(); |
| 1698 |
| 1699 __ Bind(&return_false); |
| 1700 __ LoadObject(RAX, Bool::False()); |
| 1701 __ ret(); |
| 1702 |
| 1703 __ Bind(&fall_through); |
| 1704 } |
| 1705 |
| 1706 |
1598 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { | 1707 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { |
1599 Label fall_through, try_two_byte_string; | 1708 Label fall_through, try_two_byte_string; |
1600 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. | 1709 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. |
1601 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String. | 1710 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String. |
1602 __ testq(RCX, Immediate(kSmiTagMask)); | 1711 __ testq(RCX, Immediate(kSmiTagMask)); |
1603 __ j(NOT_ZERO, &fall_through); // Non-smi index. | 1712 __ j(NOT_ZERO, &fall_through); // Non-smi index. |
1604 // Range check. | 1713 // Range check. |
1605 __ cmpq(RCX, FieldAddress(RAX, String::length_offset())); | 1714 __ cmpq(RCX, FieldAddress(RAX, String::length_offset())); |
1606 // Runtime throws exception. | 1715 // Runtime throws exception. |
1607 __ j(ABOVE_EQUAL, &fall_through); | 1716 __ j(ABOVE_EQUAL, &fall_through); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1999 __ LoadIsolate(RAX); | 2108 __ LoadIsolate(RAX); |
2000 __ movq(RAX, Address(RAX, Isolate::current_tag_offset())); | 2109 __ movq(RAX, Address(RAX, Isolate::current_tag_offset())); |
2001 __ ret(); | 2110 __ ret(); |
2002 } | 2111 } |
2003 | 2112 |
2004 #undef __ | 2113 #undef __ |
2005 | 2114 |
2006 } // namespace dart | 2115 } // namespace dart |
2007 | 2116 |
2008 #endif // defined TARGET_ARCH_X64 | 2117 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |