Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: runtime/vm/intrinsifier_mips.cc

Issue 1450663002: Intrinsify _StringBase._substringMatches to speedup indexOf/startsWith/endsWith under precompilatio… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 FieldAddress(V0, Double::value_offset() + kWordSize)); 1463 FieldAddress(V0, Double::value_offset() + kWordSize));
1464 __ Bind(&fall_through); 1464 __ Bind(&fall_through);
1465 } 1465 }
1466 1466
1467 1467
1468 void Intrinsifier::DoubleFromInteger(Assembler* assembler) { 1468 void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
1469 Label fall_through; 1469 Label fall_through;
1470 1470
1471 __ lw(T0, Address(SP, 0 * kWordSize)); 1471 __ lw(T0, Address(SP, 0 * kWordSize));
1472 __ andi(CMPRES1, T0, Immediate(kSmiTagMask)); 1472 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
1473 __ bne(T0, ZR, &fall_through); 1473 __ bne(CMPRES1, ZR, &fall_through);
1474 1474
1475 // Is Smi. 1475 // Is Smi.
1476 __ SmiUntag(T0); 1476 __ SmiUntag(T0);
1477 __ mtc1(T0, F4); 1477 __ mtc1(T0, F4);
1478 __ cvtdw(D0, F4); 1478 __ cvtdw(D0, F4);
1479 const Class& double_class = Class::Handle( 1479 const Class& double_class = Class::Handle(
1480 Isolate::Current()->object_store()->double_class()); 1480 Isolate::Current()->object_store()->double_class());
1481 __ TryAllocate(double_class, &fall_through, V0, T1); // Result register. 1481 __ TryAllocate(double_class, &fall_through, V0, T1); // Result register.
1482 __ swc1(F0, FieldAddress(V0, Double::value_offset())); 1482 __ swc1(F0, FieldAddress(V0, Double::value_offset()));
1483 __ Ret(); 1483 __ Ret();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 1674
1675 1675
1676 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) { 1676 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
1677 Label fall_through, try_two_byte_string; 1677 Label fall_through, try_two_byte_string;
1678 1678
1679 __ lw(T1, Address(SP, 0 * kWordSize)); // Index. 1679 __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
1680 __ lw(T0, Address(SP, 1 * kWordSize)); // String. 1680 __ lw(T0, Address(SP, 1 * kWordSize)); // String.
1681 1681
1682 // Checks. 1682 // Checks.
1683 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 1683 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
1684 __ bne(T1, ZR, &fall_through); // Index is not a Smi. 1684 __ bne(CMPRES1, ZR, &fall_through); // Index is not a Smi.
1685 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check. 1685 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
1686 // Runtime throws exception. 1686 // Runtime throws exception.
1687 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through); 1687 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
1688 __ LoadClassId(CMPRES1, T0); // Class ID check. 1688 __ LoadClassId(CMPRES1, T0); // Class ID check.
1689 __ BranchNotEqual( 1689 __ BranchNotEqual(
1690 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string); 1690 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string);
1691 1691
1692 // Grab byte and return. 1692 // Grab byte and return.
1693 __ SmiUntag(T1); 1693 __ SmiUntag(T1);
1694 __ addu(T2, T0, T1); 1694 __ addu(T2, T0, T1);
1695 __ lbu(V0, FieldAddress(T2, OneByteString::data_offset())); 1695 __ lbu(V0, FieldAddress(T2, OneByteString::data_offset()));
1696 __ Ret(); 1696 __ Ret();
1697 __ delay_slot()->SmiTag(V0); 1697 __ delay_slot()->SmiTag(V0);
1698 1698
1699 __ Bind(&try_two_byte_string); 1699 __ Bind(&try_two_byte_string);
1700 __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through); 1700 __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
1701 ASSERT(kSmiTagShift == 1); 1701 ASSERT(kSmiTagShift == 1);
1702 __ addu(T2, T0, T1); 1702 __ addu(T2, T0, T1);
1703 __ lhu(V0, FieldAddress(T2, TwoByteString::data_offset())); 1703 __ lhu(V0, FieldAddress(T2, TwoByteString::data_offset()));
1704 __ Ret(); 1704 __ Ret();
1705 __ delay_slot()->SmiTag(V0); 1705 __ delay_slot()->SmiTag(V0);
1706 1706
1707 __ Bind(&fall_through); 1707 __ Bind(&fall_through);
1708 } 1708 }
1709 1709
1710 1710
1711 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1712 intptr_t receiver_cid,
1713 intptr_t other_cid,
1714 Label* return_true,
1715 Label* return_false) {
1716 __ SmiUntag(A1);
1717 __ lw(T1, FieldAddress(A0, String::length_offset())); // this.length
1718 __ SmiUntag(T1);
1719 __ lw(T2, FieldAddress(A2, String::length_offset())); // other.length
1720 __ SmiUntag(T2);
1721
1722 // if (other.length == 0) return true;
1723 __ beq(T2, ZR, return_true);
1724
1725 // if (start < 0) return false;
1726 __ bltz(A1, return_false);
1727
1728 // if (start + other.length > this.length) return false;
1729 __ addu(T0, A1, T2);
1730 __ BranchSignedGreater(T0, T1, return_false);
1731
1732 if (receiver_cid == kOneByteStringCid) {
1733 __ AddImmediate(A0, A0, OneByteString::data_offset() - kHeapObjectTag);
1734 __ addu(A0, A0, A1);
1735 } else {
1736 ASSERT(receiver_cid == kTwoByteStringCid);
1737 __ AddImmediate(A0, A0, TwoByteString::data_offset() - kHeapObjectTag);
1738 __ addu(A0, A0, A1);
1739 __ addu(A0, A0, A1);
1740 }
1741 if (other_cid == kOneByteStringCid) {
1742 __ AddImmediate(A2, A2, OneByteString::data_offset() - kHeapObjectTag);
1743 } else {
1744 ASSERT(other_cid == kTwoByteStringCid);
1745 __ AddImmediate(A2, A2, TwoByteString::data_offset() - kHeapObjectTag);
1746 }
1747
1748 // i = 0
1749 __ LoadImmediate(T0, 0);
1750
1751 // while (i < len)
1752 Label loop;
1753 __ Bind(&loop);
1754 __ BranchSignedGreaterEqual(T0, T2, return_true);
1755
1756 if (receiver_cid == kOneByteStringCid) {
1757 __ lbu(T3, Address(A0, 0)); // this.codeUnitAt(i + start)
1758 } else {
1759 __ lhu(T3, Address(A0, 0)); // this.codeUnitAt(i + start)
1760 }
1761 if (other_cid == kOneByteStringCid) {
1762 __ lbu(T4, Address(A2, 0)); // other.codeUnitAt(i)
1763 } else {
1764 __ lhu(T4, Address(A2, 0)); // other.codeUnitAt(i)
1765 }
1766 __ bne(T3, T4, return_false);
1767
1768 // i++
1769 __ AddImmediate(T0, T0, 1);
1770 __ AddImmediate(A0, A0, receiver_cid == kOneByteStringCid ? 1 : 2);
1771 __ AddImmediate(A2, A2, other_cid == kOneByteStringCid ? 1 : 2);
1772 __ b(&loop);
1773 }
1774
1775
1776 // bool _substringMatches(int start, String other)
1777 void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
1778 Label fall_through, return_true, return_false, try_two_byte;
1779 __ lw(A0, Address(SP, 2 * kWordSize)); // this
1780 __ lw(A1, Address(SP, 1 * kWordSize)); // start
1781 __ lw(A2, Address(SP, 0 * kWordSize)); // other
1782
1783 __ andi(CMPRES1, A1, Immediate(kSmiTagMask));
1784 __ bne(CMPRES1, ZR, &fall_through); // Index is not a Smi.
1785
1786 __ LoadClassId(CMPRES1, A2);
1787 __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &fall_through);
1788
1789 __ LoadClassId(CMPRES1, A0);
1790 __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &try_two_byte);
1791
1792 GenerateSubstringMatchesSpecialization(assembler,
1793 kOneByteStringCid,
1794 kOneByteStringCid,
1795 &return_true,
1796 &return_false);
1797
1798 __ Bind(&try_two_byte);
1799 __ LoadClassId(CMPRES1, A0);
1800 __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
1801
1802 GenerateSubstringMatchesSpecialization(assembler,
1803 kTwoByteStringCid,
1804 kOneByteStringCid,
1805 &return_true,
1806 &return_false);
1807
1808 __ Bind(&return_true);
1809 __ LoadObject(V0, Bool::True());
1810 __ Ret();
1811
1812 __ Bind(&return_false);
1813 __ LoadObject(V0, Bool::False());
1814 __ Ret();
1815
1816 __ Bind(&fall_through);
1817 }
1818
1819
1711 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { 1820 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
1712 Label fall_through, try_two_byte_string; 1821 Label fall_through, try_two_byte_string;
1713 1822
1714 __ lw(T1, Address(SP, 0 * kWordSize)); // Index. 1823 __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
1715 __ lw(T0, Address(SP, 1 * kWordSize)); // String. 1824 __ lw(T0, Address(SP, 1 * kWordSize)); // String.
1716 1825
1717 // Checks. 1826 // Checks.
1718 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 1827 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
1719 __ bne(T1, ZR, &fall_through); // Index is not a Smi. 1828 __ bne(CMPRES1, ZR, &fall_through); // Index is not a Smi.
1720 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check. 1829 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
1721 // Runtime throws exception. 1830 // Runtime throws exception.
1722 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through); 1831 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
1723 __ LoadClassId(CMPRES1, T0); // Class ID check. 1832 __ LoadClassId(CMPRES1, T0); // Class ID check.
1724 __ BranchNotEqual( 1833 __ BranchNotEqual(
1725 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string); 1834 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string);
1726 1835
1727 // Grab byte and return. 1836 // Grab byte and return.
1728 __ SmiUntag(T1); 1837 __ SmiUntag(T1);
1729 __ addu(T2, T0, T1); 1838 __ addu(T2, T0, T1);
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 2229
2121 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { 2230 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
2122 __ LoadIsolate(V0); 2231 __ LoadIsolate(V0);
2123 __ Ret(); 2232 __ Ret();
2124 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); 2233 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset()));
2125 } 2234 }
2126 2235
2127 } // namespace dart 2236 } // namespace dart
2128 2237
2129 #endif // defined TARGET_ARCH_MIPS 2238 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698