Chromium Code Reviews| 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 |