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

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

Issue 2379733002: Recognize and optimize a.runtimeType == b.runtimeType pattern. (Closed)
Patch Set: port to all arch, make AOT opt non-speculative Created 4 years, 2 months 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 __ ldr(R0, Address(SP, 0 * kWordSize)); 1633 __ ldr(R0, Address(SP, 0 * kWordSize));
1634 __ ldr(R1, Address(SP, 1 * kWordSize)); 1634 __ ldr(R1, Address(SP, 1 * kWordSize));
1635 __ cmp(R0, Operand(R1)); 1635 __ cmp(R0, Operand(R1));
1636 __ LoadObject(R0, Bool::False()); 1636 __ LoadObject(R0, Bool::False());
1637 __ LoadObject(TMP, Bool::True()); 1637 __ LoadObject(TMP, Bool::True());
1638 __ csel(R0, TMP, R0, EQ); 1638 __ csel(R0, TMP, R0, EQ);
1639 __ ret(); 1639 __ ret();
1640 } 1640 }
1641 1641
1642 1642
1643 static void RangeCheck(Assembler* assembler,
1644 Register val,
1645 Register tmp,
1646 intptr_t low,
1647 intptr_t high,
1648 Condition cc,
1649 Label* target) {
1650 __ SubImmediate(tmp, val, low);
1651 __ CompareImmediate(tmp, high - low);
1652 __ b(target, cc);
1653 }
1654
1655
1656 const Condition kIfNotInRange = HI;
1657 const Condition kIfInRange = LS;
1658
1659
1660 static void JumpIfInteger(Assembler* assembler,
1661 Register cid,
1662 Register tmp,
1663 Label* target) {
1664 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfInRange, target);
1665 }
1666
1667
1668 static void JumpIfNotInteger(Assembler* assembler,
1669 Register cid,
1670 Register tmp,
1671 Label* target) {
1672 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfNotInRange, target);
1673 }
1674
1675
1676 static void JumpIfString(Assembler* assembler,
1677 Register cid,
1678 Register tmp,
1679 Label* target) {
1680 RangeCheck(assembler,
1681 cid,
1682 tmp,
1683 kOneByteStringCid,
1684 kExternalTwoByteStringCid,
1685 kIfInRange,
1686 target);
1687 }
1688
1689
1690 static void JumpIfNotString(Assembler* assembler,
1691 Register cid,
1692 Register tmp,
1693 Label* target) {
1694 RangeCheck(assembler,
1695 cid,
1696 tmp,
1697 kOneByteStringCid,
1698 kExternalTwoByteStringCid,
1699 kIfNotInRange,
1700 target);
1701 }
1702
1703
1643 // Return type quickly for simple types (not parameterized and not signature). 1704 // Return type quickly for simple types (not parameterized and not signature).
1644 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1705 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1645 Label fall_through; 1706 Label fall_through, use_canonical_type, not_double, not_integer;
1646 __ ldr(R0, Address(SP, 0 * kWordSize)); 1707 __ ldr(R0, Address(SP, 0 * kWordSize));
1647 __ LoadClassIdMayBeSmi(R1, R0); 1708 __ LoadClassIdMayBeSmi(R1, R0);
1709
1648 __ CompareImmediate(R1, kClosureCid); 1710 __ CompareImmediate(R1, kClosureCid);
1649 __ b(&fall_through, EQ); // Instance is a closure. 1711 __ b(&fall_through, EQ); // Instance is a closure.
1712
1713 __ CompareImmediate(R1, kNumPredefinedCids);
1714 __ b(&use_canonical_type, HI);
1715
1716 __ CompareImmediate(R1, kDoubleCid);
1717 __ b(&not_double, NE);
1718
1719 __ LoadIsolate(R0);
1720 __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
1721 __ LoadFromOffset(R0, R0, ObjectStore::double_type_offset());
1722 __ ret();
1723
1724 __ Bind(&not_double);
1725 JumpIfNotInteger(assembler, R1, R0, &not_integer);
1726 __ LoadIsolate(R0);
1727 __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
1728 __ LoadFromOffset(R0, R0, ObjectStore::int_type_offset());
1729 __ ret();
1730
1731 __ Bind(&not_integer);
1732 JumpIfNotString(assembler, R1, R0, &use_canonical_type);
1733 __ LoadIsolate(R0);
1734 __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
1735 __ LoadFromOffset(R0, R0, ObjectStore::string_type_offset());
1736 __ ret();
1737
1738 __ Bind(&use_canonical_type);
1650 __ LoadClassById(R2, R1); 1739 __ LoadClassById(R2, R1);
1651 // R2: class of instance (R0).
1652
1653 __ ldr(R3, FieldAddress(R2, Class::num_type_arguments_offset()), kHalfword); 1740 __ ldr(R3, FieldAddress(R2, Class::num_type_arguments_offset()), kHalfword);
1654 __ CompareImmediate(R3, 0); 1741 __ CompareImmediate(R3, 0);
1655 __ b(&fall_through, NE); 1742 __ b(&fall_through, NE);
1656 1743
1657 __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset())); 1744 __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset()));
1658 __ CompareObject(R0, Object::null_object()); 1745 __ CompareObject(R0, Object::null_object());
1659 __ b(&fall_through, EQ); 1746 __ b(&fall_through, EQ);
1660 __ ret(); 1747 __ ret();
1661 1748
1662 __ Bind(&fall_through); 1749 __ Bind(&fall_through);
1663 } 1750 }
1664 1751
1665 1752
1753 void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
1754 Label fall_through, different_cids, equal, not_equal, not_integer;
1755 __ ldr(R0, Address(SP, 0 * kWordSize));
1756 __ LoadClassIdMayBeSmi(R1, R0);
1757
1758 // Check if left hand size is a closure. Closures are handled in the runtime.
1759 __ CompareImmediate(R1, kClosureCid);
1760 __ b(&fall_through, EQ);
1761
1762 __ ldr(R0, Address(SP, 1 * kWordSize));
1763 __ LoadClassIdMayBeSmi(R2, R0);
1764
1765 // Check whether class ids match. If class ids don't match objects can still
1766 // have the same runtime type (e.g. multiple string implementation classes
1767 // map to a single String type).
1768 __ cmp(R1, Operand(R2));
1769 __ b(&different_cids, NE);
1770
1771 // Objects have the same class and neither is a closure.
1772 // Check if there are no type arguments. In this case we can return true.
1773 // Otherwise fall through into the runtime to handle comparison.
1774 __ LoadClassById(R3, R1);
1775 __ ldr(R3, FieldAddress(R3, Class::num_type_arguments_offset()), kHalfword);
regis 2016/10/08 09:10:37 ditto
Vyacheslav Egorov (Google) 2016/10/24 20:23:03 Acknowledged.
1776 __ CompareImmediate(R3, 0);
1777 __ b(&fall_through, NE);
1778
1779 __ Bind(&equal);
1780 __ LoadObject(R0, Bool::True());
1781 __ ret();
1782
1783 // Class ids are different. Check if we are comparing runtime types of
1784 // two strings (with different representations) or two integers.
1785 __ Bind(&different_cids);
1786 __ CompareImmediate(R1, kNumPredefinedCids);
1787 __ b(&not_equal, HI);
1788
1789 // Check if both are integers.
1790 JumpIfNotInteger(assembler, R1, R0, &not_integer);
1791 JumpIfInteger(assembler, R2, R0, &equal);
1792 __ b(&not_equal);
1793
1794 __ Bind(&not_integer);
1795 // Check if both are strings.
1796 JumpIfNotString(assembler, R1, R0, &not_equal);
1797 JumpIfString(assembler, R2, R0, &equal);
1798
1799 // Neither strings nor integers and have different class ids.
1800 __ Bind(&not_equal);
1801 __ LoadObject(R0, Bool::False());
1802 __ ret();
1803
1804 __ Bind(&fall_through);
1805 }
1806
1807
1666 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1808 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1667 Label fall_through; 1809 Label fall_through;
1668 __ ldr(R0, Address(SP, 0 * kWordSize)); 1810 __ ldr(R0, Address(SP, 0 * kWordSize));
1669 __ ldr(R0, FieldAddress(R0, String::hash_offset())); 1811 __ ldr(R0, FieldAddress(R0, String::hash_offset()));
1670 __ CompareRegisters(R0, ZR); 1812 __ CompareRegisters(R0, ZR);
1671 __ b(&fall_through, EQ); 1813 __ b(&fall_through, EQ);
1672 __ ret(); 1814 __ ret();
1673 // Hash not yet computed. 1815 // Hash not yet computed.
1674 __ Bind(&fall_through); 1816 __ Bind(&fall_through);
1675 } 1817 }
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 __ cmp(R0, Operand(0)); 2354 __ cmp(R0, Operand(0));
2213 __ LoadObject(R0, Bool::False()); 2355 __ LoadObject(R0, Bool::False());
2214 __ LoadObject(TMP, Bool::True()); 2356 __ LoadObject(TMP, Bool::True());
2215 __ csel(R0, TMP, R0, NE); 2357 __ csel(R0, TMP, R0, NE);
2216 __ ret(); 2358 __ ret();
2217 } 2359 }
2218 2360
2219 } // namespace dart 2361 } // namespace dart
2220 2362
2221 #endif // defined TARGET_ARCH_ARM64 2363 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698