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

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
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | runtime/vm/intrinsifier_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // do
1752 Label loop;
1753 __ Bind(&loop);
1754
1755 if (receiver_cid == kOneByteStringCid) {
1756 __ lbu(T3, Address(A0, 0)); // this.codeUnitAt(i + start)
1757 } else {
1758 __ lhu(T3, Address(A0, 0)); // this.codeUnitAt(i + start)
1759 }
1760 if (other_cid == kOneByteStringCid) {
1761 __ lbu(T4, Address(A2, 0)); // other.codeUnitAt(i)
1762 } else {
1763 __ lhu(T4, Address(A2, 0)); // other.codeUnitAt(i)
1764 }
1765 __ bne(T3, T4, return_false);
1766
1767 // i++, while (i < len)
1768 __ AddImmediate(T0, T0, 1);
1769 __ AddImmediate(A0, A0, receiver_cid == kOneByteStringCid ? 1 : 2);
1770 __ AddImmediate(A2, A2, other_cid == kOneByteStringCid ? 1 : 2);
1771 __ BranchSignedLess(T0, T2, &loop);
1772
1773 __ b(return_true);
1774 }
1775
1776
1777 // bool _substringMatches(int start, String other)
1778 // This intrinsic handles a OneByteString or TwoByteString receiver with a
1779 // OneByteString other.
1780 void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
1781 Label fall_through, return_true, return_false, try_two_byte;
1782 __ lw(A0, Address(SP, 2 * kWordSize)); // this
1783 __ lw(A1, Address(SP, 1 * kWordSize)); // start
1784 __ lw(A2, Address(SP, 0 * kWordSize)); // other
1785
1786 __ andi(CMPRES1, A1, Immediate(kSmiTagMask));
1787 __ bne(CMPRES1, ZR, &fall_through); // 'start' is not a Smi.
1788
1789 __ LoadClassId(CMPRES1, A2);
1790 __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &fall_through);
1791
1792 __ LoadClassId(CMPRES1, A0);
1793 __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &try_two_byte);
1794
1795 GenerateSubstringMatchesSpecialization(assembler,
1796 kOneByteStringCid,
1797 kOneByteStringCid,
1798 &return_true,
1799 &return_false);
1800
1801 __ Bind(&try_two_byte);
1802 __ LoadClassId(CMPRES1, A0);
1803 __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
1804
1805 GenerateSubstringMatchesSpecialization(assembler,
1806 kTwoByteStringCid,
1807 kOneByteStringCid,
1808 &return_true,
1809 &return_false);
1810
1811 __ Bind(&return_true);
1812 __ LoadObject(V0, Bool::True());
1813 __ Ret();
1814
1815 __ Bind(&return_false);
1816 __ LoadObject(V0, Bool::False());
1817 __ Ret();
1818
1819 __ Bind(&fall_through);
1820 }
1821
1822
1711 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { 1823 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
1712 Label fall_through, try_two_byte_string; 1824 Label fall_through, try_two_byte_string;
1713 1825
1714 __ lw(T1, Address(SP, 0 * kWordSize)); // Index. 1826 __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
1715 __ lw(T0, Address(SP, 1 * kWordSize)); // String. 1827 __ lw(T0, Address(SP, 1 * kWordSize)); // String.
1716 1828
1717 // Checks. 1829 // Checks.
1718 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 1830 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
1719 __ bne(T1, ZR, &fall_through); // Index is not a Smi. 1831 __ bne(CMPRES1, ZR, &fall_through); // Index is not a Smi.
1720 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check. 1832 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
1721 // Runtime throws exception. 1833 // Runtime throws exception.
1722 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through); 1834 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
1723 __ LoadClassId(CMPRES1, T0); // Class ID check. 1835 __ LoadClassId(CMPRES1, T0); // Class ID check.
1724 __ BranchNotEqual( 1836 __ BranchNotEqual(
1725 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string); 1837 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string);
1726 1838
1727 // Grab byte and return. 1839 // Grab byte and return.
1728 __ SmiUntag(T1); 1840 __ SmiUntag(T1);
1729 __ addu(T2, T0, T1); 1841 __ addu(T2, T0, T1);
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 2232
2121 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { 2233 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
2122 __ LoadIsolate(V0); 2234 __ LoadIsolate(V0);
2123 __ Ret(); 2235 __ Ret();
2124 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); 2236 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset()));
2125 } 2237 }
2126 2238
2127 } // namespace dart 2239 } // namespace dart
2128 2240
2129 #endif // defined TARGET_ARCH_MIPS 2241 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | runtime/vm/intrinsifier_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698