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 __ cmpq(R9, Immediate(Smi::Value(0))); | |
Florian Schneider
2015/11/18 10:26:03
testq(R9, R9)
rmacnak
2015/11/18 22:33:32
Done.
| |
1608 __ j(EQUAL, return_true); | |
1609 | |
1610 // if (start < 0) return false; | |
1611 __ cmpq(RBX, Immediate(Smi::Value(0))); | |
Florian Schneider
2015/11/18 10:26:03
alternative - I saw gcc doing this:
__ testq(RBX,
rmacnak
2015/11/18 22:33:32
Neat.
| |
1612 __ j(LESS, 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 // while (i < len) | |
1625 Label loop; | |
Florian Schneider
2015/11/18 10:26:03
Applies to all archs:
Maybe you can move the cond
rmacnak
2015/11/18 22:33:32
We can even drop the first check as it is handled
| |
1626 __ Bind(&loop); | |
1627 __ cmpq(R11, R9); | |
1628 __ j(GREATER_EQUAL, return_true); | |
1629 | |
1630 // this.codeUnitAt(i + start) | |
1631 // clobbering this.length | |
1632 __ movq(R8, R11); | |
1633 __ addq(R8, RBX); | |
1634 if (receiver_cid == kOneByteStringCid) { | |
1635 __ movzxb(R12, | |
1636 FieldAddress(RAX, R8, TIMES_1, OneByteString::data_offset())); | |
1637 } else { | |
1638 ASSERT(receiver_cid == kTwoByteStringCid); | |
1639 __ movzxw(R12, | |
1640 FieldAddress(RAX, R8, TIMES_2, TwoByteString::data_offset())); | |
1641 } | |
1642 // other.codeUnitAt(i) | |
1643 if (other_cid == kOneByteStringCid) { | |
1644 __ movzxb(R13, | |
1645 FieldAddress(RCX, R11, TIMES_1, OneByteString::data_offset())); | |
1646 } else { | |
1647 ASSERT(other_cid == kTwoByteStringCid); | |
1648 __ movzxw(R13, | |
1649 FieldAddress(RCX, R11, TIMES_2, TwoByteString::data_offset())); | |
1650 } | |
1651 __ cmpq(R12, R13); | |
1652 __ j(NOT_EQUAL, return_false); | |
1653 | |
1654 // i++; | |
1655 __ addq(R11, Immediate(1)); | |
Florian Schneider
2015/11/18 10:26:03
Move condition to here:
__ Bind(&cond);
__ cmpq(R
rmacnak
2015/11/18 22:33:32
Done.
| |
1656 __ jmp(&loop, Assembler::kNearJump); | |
1657 } | |
1658 | |
1659 | |
1660 // bool _substringMatches(int start, String other) | |
1661 void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) { | |
1662 Label fall_through, return_true, return_false, try_two_byte; | |
1663 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // receiver | |
1664 __ movq(RBX, Address(RSP, + 2 * kWordSize)); // start | |
1665 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // other | |
1666 | |
1667 __ testq(RBX, Immediate(kSmiTagMask)); | |
1668 __ j(NOT_ZERO, &fall_through); // Non-smi index. | |
1669 | |
1670 __ CompareClassId(RCX, kOneByteStringCid); | |
1671 __ j(NOT_EQUAL, &fall_through); | |
1672 | |
1673 __ CompareClassId(RAX, kOneByteStringCid); | |
1674 __ j(NOT_EQUAL, &try_two_byte); | |
1675 | |
1676 GenerateSubstringMatchesSpecialization(assembler, | |
1677 kOneByteStringCid, | |
1678 kOneByteStringCid, | |
1679 &return_true, | |
1680 &return_false); | |
1681 | |
1682 __ Bind(&try_two_byte); | |
1683 __ CompareClassId(RAX, kTwoByteStringCid); | |
1684 __ j(NOT_EQUAL, &fall_through); | |
1685 | |
1686 GenerateSubstringMatchesSpecialization(assembler, | |
1687 kTwoByteStringCid, | |
1688 kOneByteStringCid, | |
1689 &return_true, | |
1690 &return_false); | |
1691 | |
1692 __ Bind(&return_true); | |
1693 __ LoadObject(RAX, Bool::True()); | |
1694 __ ret(); | |
1695 | |
1696 __ Bind(&return_false); | |
1697 __ LoadObject(RAX, Bool::False()); | |
1698 __ ret(); | |
1699 | |
1700 __ Bind(&fall_through); | |
1701 } | |
1702 | |
1703 | |
1598 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { | 1704 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { |
1599 Label fall_through, try_two_byte_string; | 1705 Label fall_through, try_two_byte_string; |
1600 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. | 1706 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. |
1601 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String. | 1707 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String. |
1602 __ testq(RCX, Immediate(kSmiTagMask)); | 1708 __ testq(RCX, Immediate(kSmiTagMask)); |
1603 __ j(NOT_ZERO, &fall_through); // Non-smi index. | 1709 __ j(NOT_ZERO, &fall_through); // Non-smi index. |
1604 // Range check. | 1710 // Range check. |
1605 __ cmpq(RCX, FieldAddress(RAX, String::length_offset())); | 1711 __ cmpq(RCX, FieldAddress(RAX, String::length_offset())); |
1606 // Runtime throws exception. | 1712 // Runtime throws exception. |
1607 __ j(ABOVE_EQUAL, &fall_through); | 1713 __ j(ABOVE_EQUAL, &fall_through); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1999 __ LoadIsolate(RAX); | 2105 __ LoadIsolate(RAX); |
2000 __ movq(RAX, Address(RAX, Isolate::current_tag_offset())); | 2106 __ movq(RAX, Address(RAX, Isolate::current_tag_offset())); |
2001 __ ret(); | 2107 __ ret(); |
2002 } | 2108 } |
2003 | 2109 |
2004 #undef __ | 2110 #undef __ |
2005 | 2111 |
2006 } // namespace dart | 2112 } // namespace dart |
2007 | 2113 |
2008 #endif // defined TARGET_ARCH_X64 | 2114 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |