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

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

Issue 2453463006: Revert "Revert "Recognize and optimize a.runtimeType == b.runtimeType pattern."" (Closed)
Patch Set: Created 4 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_arm.cc ('k') | runtime/vm/intrinsifier_ia32.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) 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 1635 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 __ ldr(R0, Address(SP, 0 * kWordSize)); 1646 __ ldr(R0, Address(SP, 0 * kWordSize));
1647 __ ldr(R1, Address(SP, 1 * kWordSize)); 1647 __ ldr(R1, Address(SP, 1 * kWordSize));
1648 __ cmp(R0, Operand(R1)); 1648 __ cmp(R0, Operand(R1));
1649 __ LoadObject(R0, Bool::False()); 1649 __ LoadObject(R0, Bool::False());
1650 __ LoadObject(TMP, Bool::True()); 1650 __ LoadObject(TMP, Bool::True());
1651 __ csel(R0, TMP, R0, EQ); 1651 __ csel(R0, TMP, R0, EQ);
1652 __ ret(); 1652 __ ret();
1653 } 1653 }
1654 1654
1655 1655
1656 static void RangeCheck(Assembler* assembler,
1657 Register val,
1658 Register tmp,
1659 intptr_t low,
1660 intptr_t high,
1661 Condition cc,
1662 Label* target) {
1663 __ AddImmediate(tmp, val, -low);
1664 __ CompareImmediate(tmp, high - low);
1665 __ b(target, cc);
1666 }
1667
1668
1669 const Condition kIfNotInRange = HI;
1670 const Condition kIfInRange = LS;
1671
1672
1673 static void JumpIfInteger(Assembler* assembler,
1674 Register cid,
1675 Register tmp,
1676 Label* target) {
1677 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfInRange, target);
1678 }
1679
1680
1681 static void JumpIfNotInteger(Assembler* assembler,
1682 Register cid,
1683 Register tmp,
1684 Label* target) {
1685 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfNotInRange, target);
1686 }
1687
1688
1689 static void JumpIfString(Assembler* assembler,
1690 Register cid,
1691 Register tmp,
1692 Label* target) {
1693 RangeCheck(assembler,
1694 cid,
1695 tmp,
1696 kOneByteStringCid,
1697 kExternalTwoByteStringCid,
1698 kIfInRange,
1699 target);
1700 }
1701
1702
1703 static void JumpIfNotString(Assembler* assembler,
1704 Register cid,
1705 Register tmp,
1706 Label* target) {
1707 RangeCheck(assembler,
1708 cid,
1709 tmp,
1710 kOneByteStringCid,
1711 kExternalTwoByteStringCid,
1712 kIfNotInRange,
1713 target);
1714 }
1715
1716
1656 // Return type quickly for simple types (not parameterized and not signature). 1717 // Return type quickly for simple types (not parameterized and not signature).
1657 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1718 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1658 Label fall_through; 1719 Label fall_through, use_canonical_type, not_double, not_integer;
1659 __ ldr(R0, Address(SP, 0 * kWordSize)); 1720 __ ldr(R0, Address(SP, 0 * kWordSize));
1660 __ LoadClassIdMayBeSmi(R1, R0); 1721 __ LoadClassIdMayBeSmi(R1, R0);
1722
1661 __ CompareImmediate(R1, kClosureCid); 1723 __ CompareImmediate(R1, kClosureCid);
1662 __ b(&fall_through, EQ); // Instance is a closure. 1724 __ b(&fall_through, EQ); // Instance is a closure.
1725
1726 __ CompareImmediate(R1, kNumPredefinedCids);
1727 __ b(&use_canonical_type, HI);
1728
1729 __ CompareImmediate(R1, kDoubleCid);
1730 __ b(&not_double, NE);
1731
1732 __ LoadIsolate(R0);
1733 __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
1734 __ LoadFromOffset(R0, R0, ObjectStore::double_type_offset());
1735 __ ret();
1736
1737 __ Bind(&not_double);
1738 JumpIfNotInteger(assembler, R1, R0, &not_integer);
1739 __ LoadIsolate(R0);
1740 __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
1741 __ LoadFromOffset(R0, R0, ObjectStore::int_type_offset());
1742 __ ret();
1743
1744 __ Bind(&not_integer);
1745 JumpIfNotString(assembler, R1, R0, &use_canonical_type);
1746 __ LoadIsolate(R0);
1747 __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
1748 __ LoadFromOffset(R0, R0, ObjectStore::string_type_offset());
1749 __ ret();
1750
1751 __ Bind(&use_canonical_type);
1663 __ LoadClassById(R2, R1); 1752 __ LoadClassById(R2, R1);
1664 // R2: class of instance (R0).
1665
1666 __ ldr(R3, FieldAddress(R2, Class::num_type_arguments_offset()), kHalfword); 1753 __ ldr(R3, FieldAddress(R2, Class::num_type_arguments_offset()), kHalfword);
1667 __ CompareImmediate(R3, 0); 1754 __ CompareImmediate(R3, 0);
1668 __ b(&fall_through, NE); 1755 __ b(&fall_through, NE);
1669 1756
1670 __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset())); 1757 __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset()));
1671 __ CompareObject(R0, Object::null_object()); 1758 __ CompareObject(R0, Object::null_object());
1672 __ b(&fall_through, EQ); 1759 __ b(&fall_through, EQ);
1673 __ ret(); 1760 __ ret();
1674 1761
1675 __ Bind(&fall_through); 1762 __ Bind(&fall_through);
1676 } 1763 }
1677 1764
1678 1765
1766 void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
1767 Label fall_through, different_cids, equal, not_equal, not_integer;
1768 __ ldr(R0, Address(SP, 0 * kWordSize));
1769 __ LoadClassIdMayBeSmi(R1, R0);
1770
1771 // Check if left hand size is a closure. Closures are handled in the runtime.
1772 __ CompareImmediate(R1, kClosureCid);
1773 __ b(&fall_through, EQ);
1774
1775 __ ldr(R0, Address(SP, 1 * kWordSize));
1776 __ LoadClassIdMayBeSmi(R2, R0);
1777
1778 // Check whether class ids match. If class ids don't match objects can still
1779 // have the same runtime type (e.g. multiple string implementation classes
1780 // map to a single String type).
1781 __ cmp(R1, Operand(R2));
1782 __ b(&different_cids, NE);
1783
1784 // Objects have the same class and neither is a closure.
1785 // Check if there are no type arguments. In this case we can return true.
1786 // Otherwise fall through into the runtime to handle comparison.
1787 __ LoadClassById(R3, R1);
1788 __ ldr(R3, FieldAddress(R3, Class::num_type_arguments_offset()), kHalfword);
1789 __ CompareImmediate(R3, 0);
1790 __ b(&fall_through, NE);
1791
1792 __ Bind(&equal);
1793 __ LoadObject(R0, Bool::True());
1794 __ ret();
1795
1796 // Class ids are different. Check if we are comparing runtime types of
1797 // two strings (with different representations) or two integers.
1798 __ Bind(&different_cids);
1799 __ CompareImmediate(R1, kNumPredefinedCids);
1800 __ b(&not_equal, HI);
1801
1802 // Check if both are integers.
1803 JumpIfNotInteger(assembler, R1, R0, &not_integer);
1804 JumpIfInteger(assembler, R2, R0, &equal);
1805 __ b(&not_equal);
1806
1807 __ Bind(&not_integer);
1808 // Check if both are strings.
1809 JumpIfNotString(assembler, R1, R0, &not_equal);
1810 JumpIfString(assembler, R2, R0, &equal);
1811
1812 // Neither strings nor integers and have different class ids.
1813 __ Bind(&not_equal);
1814 __ LoadObject(R0, Bool::False());
1815 __ ret();
1816
1817 __ Bind(&fall_through);
1818 }
1819
1820
1679 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1821 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1680 Label fall_through; 1822 Label fall_through;
1681 __ ldr(R0, Address(SP, 0 * kWordSize)); 1823 __ ldr(R0, Address(SP, 0 * kWordSize));
1682 __ ldr(R0, FieldAddress(R0, String::hash_offset())); 1824 __ ldr(R0, FieldAddress(R0, String::hash_offset()));
1683 __ CompareRegisters(R0, ZR); 1825 __ CompareRegisters(R0, ZR);
1684 __ b(&fall_through, EQ); 1826 __ b(&fall_through, EQ);
1685 __ ret(); 1827 __ ret();
1686 // Hash not yet computed. 1828 // Hash not yet computed.
1687 __ Bind(&fall_through); 1829 __ Bind(&fall_through);
1688 } 1830 }
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 __ cmp(R0, Operand(0)); 2367 __ cmp(R0, Operand(0));
2226 __ LoadObject(R0, Bool::False()); 2368 __ LoadObject(R0, Bool::False());
2227 __ LoadObject(TMP, Bool::True()); 2369 __ LoadObject(TMP, Bool::True());
2228 __ csel(R0, TMP, R0, NE); 2370 __ csel(R0, TMP, R0, NE);
2229 __ ret(); 2371 __ ret();
2230 } 2372 }
2231 2373
2232 } // namespace dart 2374 } // namespace dart
2233 2375
2234 #endif // defined TARGET_ARCH_ARM64 2376 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/intrinsifier_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698