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

Side by Side Diff: runtime/vm/intrinsifier_arm.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 | « no previous file | runtime/vm/intrinsifier_arm64.cc » ('j') | runtime/vm/intrinsifier_ia32.cc » ('J')
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 1579 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 ASSERT(kSmiTagShift == 1); 1590 ASSERT(kSmiTagShift == 1);
1591 __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag); 1591 __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
1592 __ ldrh(R0, Address(R0, R1)); 1592 __ ldrh(R0, Address(R0, R1));
1593 __ SmiTag(R0); 1593 __ SmiTag(R0);
1594 __ Ret(); 1594 __ Ret();
1595 1595
1596 __ Bind(&fall_through); 1596 __ Bind(&fall_through);
1597 } 1597 }
1598 1598
1599 1599
1600 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1601 intptr_t receiver_cid,
1602 intptr_t other_cid,
1603 Label* return_true,
1604 Label* return_false) {
1605 __ SmiUntag(R1);
1606 __ ldr(R8, FieldAddress(R0, String::length_offset())); // this.length
1607 __ SmiUntag(R8);
1608 __ ldr(R9, FieldAddress(R2, String::length_offset())); // other.length
1609 __ SmiUntag(R9);
1610
1611 // if (other.length == 0) return true;
1612 __ cmp(R9, Operand(0));
1613 __ b(return_true, EQ);
1614
1615 // if (start < 0) return false;
1616 __ cmp(R1, Operand(0));
1617 __ b(return_false, LT);
1618
1619 // if (start + other.length > this.length) return false;
1620 __ add(R3, R1, Operand(R9));
1621 __ cmp(R3, Operand(R8));
1622 __ b(return_false, GT);
1623
1624 if (receiver_cid == kOneByteStringCid) {
1625 __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag);
1626 __ add(R0, R0, Operand(R1));
1627 } else {
1628 ASSERT(receiver_cid == kTwoByteStringCid);
1629 __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag);
1630 __ add(R0, R0, Operand(R1));
1631 __ add(R0, R0, Operand(R1));
1632 }
1633 if (other_cid == kOneByteStringCid) {
1634 __ AddImmediate(R2, R2, OneByteString::data_offset() - kHeapObjectTag);
1635 } else {
1636 ASSERT(other_cid == kTwoByteStringCid);
1637 __ AddImmediate(R2, R2, TwoByteString::data_offset() - kHeapObjectTag);
1638 }
1639
1640 // i = 0
1641 __ LoadImmediate(R3, 0);
1642
1643 // while (i < len)
1644 Label loop;
1645 __ Bind(&loop);
1646 __ cmp(R3, Operand(R9/*otherlength*/));
Florian Schneider 2015/11/18 10:26:03 s/otherlength/other.length/
1647 __ b(return_true, GE);
1648
1649 if (receiver_cid == kOneByteStringCid) {
1650 __ ldrb(R4, Address(R0, 0)); // this.codeUnitAt(i + start)
1651 } else {
1652 __ ldrh(R4, Address(R0, 0)); // this.codeUnitAt(i + start)
1653 }
1654 if (other_cid == kOneByteStringCid) {
1655 __ ldrb(NOTFP, Address(R2, 0)); // other.codeUnitAt(i)
1656 } else {
1657 __ ldrh(NOTFP, Address(R2, 0)); // other.codeUnitAt(i)
1658 }
1659 __ cmp(R4, Operand(NOTFP));
1660 __ b(return_false, NE);
1661
1662 // i++
1663 __ AddImmediate(R3, R3, 1);
1664 __ AddImmediate(R0, R0, receiver_cid == kOneByteStringCid ? 1 : 2);
1665 __ AddImmediate(R2, R2, other_cid == kOneByteStringCid ? 1 : 2);
1666 __ b(&loop);
1667 }
1668
1669
1670 // bool _substringMatches(int start, String other)
1671 // Clobbers ARGS_DESCRIPTOR_REG. Safe because this method has no optional
srdjan 2015/11/18 17:52:54 s/ARGS_DESCRIPTOR_REG/ARGS_DESC_REG/
1672 // parameters.
1673 void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
srdjan 2015/11/18 17:52:54 You could push R4 (arg_desc) and restore it when r
rmacnak 2015/11/18 22:33:32 Done.
1674 Label fall_through, return_true, return_false, try_two_byte;
1675 __ ldr(R0, Address(SP, 2 * kWordSize)); // this
1676 __ ldr(R1, Address(SP, 1 * kWordSize)); // start
1677 __ ldr(R2, Address(SP, 0 * kWordSize)); // other
1678
1679 __ tst(R1, Operand(kSmiTagMask));
1680 __ b(&fall_through, NE); // Index is not a Smi.
srdjan 2015/11/18 17:52:54 'start' is not a smi
rmacnak 2015/11/18 22:33:32 Done.
1681
1682 __ CompareClassId(R2, kOneByteStringCid, R3);
srdjan 2015/11/18 17:52:54 Add somewhere (top of function?): Supports one-
rmacnak 2015/11/18 22:33:32 Done.
1683 __ b(&fall_through, NE);
1684
1685 __ CompareClassId(R0, kOneByteStringCid, R3);
1686 __ b(&try_two_byte, NE);
1687
1688 GenerateSubstringMatchesSpecialization(assembler,
1689 kOneByteStringCid,
1690 kOneByteStringCid,
1691 &return_true,
1692 &return_false);
1693
1694 __ Bind(&try_two_byte);
srdjan 2015/11/18 17:52:54 s/try_two_byte/try_two_byte_this/
1695 __ CompareClassId(R0, kTwoByteStringCid, R3);
1696 __ b(&fall_through, NE);
1697
1698 GenerateSubstringMatchesSpecialization(assembler,
1699 kTwoByteStringCid,
1700 kOneByteStringCid,
1701 &return_true,
1702 &return_false);
1703
1704 __ Bind(&return_true);
1705 __ LoadObject(R0, Bool::True());
1706 __ Ret();
1707
1708 __ Bind(&return_false);
1709 __ LoadObject(R0, Bool::False());
1710 __ Ret();
1711
1712 __ Bind(&fall_through);
1713 }
1714
1715
1600 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { 1716 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
1601 Label fall_through, try_two_byte_string; 1717 Label fall_through, try_two_byte_string;
1602 1718
1603 __ ldr(R1, Address(SP, 0 * kWordSize)); // Index. 1719 __ ldr(R1, Address(SP, 0 * kWordSize)); // Index.
1604 __ ldr(R0, Address(SP, 1 * kWordSize)); // String. 1720 __ ldr(R0, Address(SP, 1 * kWordSize)); // String.
1605 __ tst(R1, Operand(kSmiTagMask)); 1721 __ tst(R1, Operand(kSmiTagMask));
1606 __ b(&fall_through, NE); // Index is not a Smi. 1722 __ b(&fall_through, NE); // Index is not a Smi.
1607 // Range check. 1723 // Range check.
1608 __ ldr(R2, FieldAddress(R0, String::length_offset())); 1724 __ ldr(R2, FieldAddress(R0, String::length_offset()));
1609 __ cmp(R1, Operand(R2)); 1725 __ cmp(R1, Operand(R2));
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
2003 2119
2004 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { 2120 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
2005 __ LoadIsolate(R0); 2121 __ LoadIsolate(R0);
2006 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); 2122 __ ldr(R0, Address(R0, Isolate::current_tag_offset()));
2007 __ Ret(); 2123 __ Ret();
2008 } 2124 }
2009 2125
2010 } // namespace dart 2126 } // namespace dart
2011 2127
2012 #endif // defined TARGET_ARCH_ARM 2128 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intrinsifier_arm64.cc » ('j') | runtime/vm/intrinsifier_ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698