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

Side by Side Diff: runtime/vm/intrinsifier_mips.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) 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 1650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1661 __ lw(T1, Address(SP, 1 * kWordSize)); 1661 __ lw(T1, Address(SP, 1 * kWordSize));
1662 __ beq(T0, T1, &is_true); 1662 __ beq(T0, T1, &is_true);
1663 __ LoadObject(V0, Bool::False()); 1663 __ LoadObject(V0, Bool::False());
1664 __ Ret(); 1664 __ Ret();
1665 __ Bind(&is_true); 1665 __ Bind(&is_true);
1666 __ LoadObject(V0, Bool::True()); 1666 __ LoadObject(V0, Bool::True());
1667 __ Ret(); 1667 __ Ret();
1668 } 1668 }
1669 1669
1670 1670
1671 enum RangeCheckCondition {
1672 kIfNotInRange, kIfInRange
1673 };
1674
1675
1676 static void RangeCheck(Assembler* assembler,
1677 Register val,
1678 Register tmp,
1679 intptr_t low,
1680 intptr_t high,
1681 RangeCheckCondition cc,
1682 Label* target) {
1683 __ AddImmediate(tmp, val, -low);
1684 if (cc == kIfInRange) {
1685 __ BranchUnsignedLessEqual(tmp, Immediate(high - low), target);
1686 } else {
1687 ASSERT(cc == kIfNotInRange);
1688 __ BranchUnsignedGreater(tmp, Immediate(high - low), target);
1689 }
1690 }
1691
1692
1693 static void JumpIfInteger(Assembler* assembler,
1694 Register cid,
1695 Register tmp,
1696 Label* target) {
1697 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfInRange, target);
1698 }
1699
1700
1701 static void JumpIfNotInteger(Assembler* assembler,
1702 Register cid,
1703 Register tmp,
1704 Label* target) {
1705 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfNotInRange, target);
1706 }
1707
1708
1709 static void JumpIfString(Assembler* assembler,
1710 Register cid,
1711 Register tmp,
1712 Label* target) {
1713 RangeCheck(assembler,
1714 cid,
1715 tmp,
1716 kOneByteStringCid,
1717 kExternalTwoByteStringCid,
1718 kIfInRange,
1719 target);
1720 }
1721
1722
1723 static void JumpIfNotString(Assembler* assembler,
1724 Register cid,
1725 Register tmp,
1726 Label* target) {
1727 RangeCheck(assembler,
1728 cid,
1729 tmp,
1730 kOneByteStringCid,
1731 kExternalTwoByteStringCid,
1732 kIfNotInRange,
1733 target);
1734 }
1735
1736
1671 // Return type quickly for simple types (not parameterized and not signature). 1737 // Return type quickly for simple types (not parameterized and not signature).
1672 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1738 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1673 Label fall_through; 1739 Label fall_through, use_canonical_type, not_integer, not_double;
1674 __ lw(T0, Address(SP, 0 * kWordSize)); 1740 __ lw(T0, Address(SP, 0 * kWordSize));
1675 __ LoadClassIdMayBeSmi(T1, T0); 1741 __ LoadClassIdMayBeSmi(T1, T0);
1742
1743 // Closures are handled in the runtime.
1676 __ BranchEqual(T1, Immediate(kClosureCid), &fall_through); 1744 __ BranchEqual(T1, Immediate(kClosureCid), &fall_through);
1745
1746 __ BranchUnsignedGreaterEqual(
1747 T1, Immediate(kNumPredefinedCids), &use_canonical_type);
1748
1749 __ BranchNotEqual(T1, Immediate(kDoubleCid), &not_double);
1750 // Object is a double.
1751 __ LoadIsolate(T1);
1752 __ LoadFromOffset(T1, T1, Isolate::object_store_offset());
1753 __ LoadFromOffset(V0, T1, ObjectStore::double_type_offset());
1754 __ Ret();
1755
1756 __ Bind(&not_double);
1757 JumpIfNotInteger(assembler, T1, T2, &not_integer);
1758 // Object is an integer.
1759 __ LoadIsolate(T1);
1760 __ LoadFromOffset(T1, T1, Isolate::object_store_offset());
1761 __ LoadFromOffset(V0, T1, ObjectStore::int_type_offset());
1762 __ Ret();
1763
1764 __ Bind(&not_integer);
1765 JumpIfNotString(assembler, T1, T2, &use_canonical_type);
1766 // Object is a string.
1767 __ LoadIsolate(T1);
1768 __ LoadFromOffset(T1, T1, Isolate::object_store_offset());
1769 __ LoadFromOffset(V0, T1, ObjectStore::string_type_offset());
1770 __ Ret();
1771
1772 __ Bind(&use_canonical_type);
1677 __ LoadClassById(T2, T1); 1773 __ LoadClassById(T2, T1);
1678 // T2: class of instance (T0).
1679
1680 __ lhu(T1, FieldAddress(T2, Class::num_type_arguments_offset())); 1774 __ lhu(T1, FieldAddress(T2, Class::num_type_arguments_offset()));
1681 __ BranchNotEqual(T1, Immediate(0), &fall_through); 1775 __ BranchNotEqual(T1, Immediate(0), &fall_through);
1682 1776
1683 __ lw(V0, FieldAddress(T2, Class::canonical_type_offset())); 1777 __ lw(V0, FieldAddress(T2, Class::canonical_type_offset()));
1684 __ BranchEqual(V0, Object::null_object(), &fall_through); 1778 __ BranchEqual(V0, Object::null_object(), &fall_through);
1685 __ Ret(); 1779 __ Ret();
1686 1780
1687 __ Bind(&fall_through); 1781 __ Bind(&fall_through);
1688 } 1782 }
1689 1783
1690 1784
1785 void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
1786 Label fall_through, different_cids, equal, not_equal, not_integer;
1787
1788 __ lw(T0, Address(SP, 0 * kWordSize));
1789 __ LoadClassIdMayBeSmi(T1, T0);
1790
1791 // Closures are handled in the runtime.
1792 __ BranchEqual(T1, Immediate(kClosureCid), &fall_through);
1793
1794 __ lw(T0, Address(SP, 1 * kWordSize));
1795 __ LoadClassIdMayBeSmi(T2, T0);
1796
1797 // Check whether class ids match. If class ids don't match objects can still
1798 // have the same runtime type (e.g. multiple string implementation classes
1799 // map to a single String type).
1800 __ BranchNotEqual(T1, T2, &different_cids);
1801
1802 // Objects have the same class and neither is a closure.
1803 // Check if there are no type arguments. In this case we can return true.
1804 // Otherwise fall through into the runtime to handle comparison.
1805 __ LoadClassById(T2, T1);
1806 __ lhu(T1, FieldAddress(T2, Class::num_type_arguments_offset()));
regis 2016/10/08 09:10:37 ditto
Vyacheslav Egorov (Google) 2016/10/24 20:23:03 Acknowledged.
1807 __ BranchNotEqual(T1, Immediate(0), &fall_through);
1808
1809 __ Bind(&equal);
1810 __ LoadObject(V0, Bool::True());
1811 __ Ret();
1812
1813 // Class ids are different. Check if we are comparing runtime types of
1814 // two strings (with different representations) or two integers.
1815 __ Bind(&different_cids);
1816 __ BranchUnsignedGreaterEqual(
1817 T1, Immediate(kNumPredefinedCids), &not_equal);
1818
1819 // Check if both are integers.
1820 JumpIfNotInteger(assembler, T1, T0, &not_integer);
1821 JumpIfInteger(assembler, T2, T0, &equal);
1822 __ b(&not_equal);
1823
1824 __ Bind(&not_integer);
1825 // Check if both are strings.
1826 JumpIfNotString(assembler, T1, T0, &not_equal);
1827 JumpIfString(assembler, T2, T0, &equal);
1828
1829 // Neither strings nor integers and have different class ids.
1830 __ Bind(&not_equal);
1831 __ LoadObject(V0, Bool::False());
1832 __ Ret();
1833
1834 __ Bind(&fall_through);
1835 }
1836
1837
1691 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1838 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1692 Label fall_through; 1839 Label fall_through;
1693 __ lw(T0, Address(SP, 0 * kWordSize)); 1840 __ lw(T0, Address(SP, 0 * kWordSize));
1694 __ lw(V0, FieldAddress(T0, String::hash_offset())); 1841 __ lw(V0, FieldAddress(T0, String::hash_offset()));
1695 __ beq(V0, ZR, &fall_through); 1842 __ beq(V0, ZR, &fall_through);
1696 __ Ret(); 1843 __ Ret();
1697 __ Bind(&fall_through); // Hash not yet computed. 1844 __ Bind(&fall_through); // Hash not yet computed.
1698 } 1845 }
1699 1846
1700 1847
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 __ lw(T0, Address(V0, TimelineStream::enabled_offset())); 2384 __ lw(T0, Address(V0, TimelineStream::enabled_offset()));
2238 __ LoadObject(V0, Bool::True()); 2385 __ LoadObject(V0, Bool::True());
2239 __ LoadObject(V1, Bool::False()); 2386 __ LoadObject(V1, Bool::False());
2240 __ Ret(); 2387 __ Ret();
2241 __ delay_slot()->movz(V0, V1, T0); // V0 = (T0 == 0) ? V1 : V0. 2388 __ delay_slot()->movz(V0, V1, T0); // V0 = (T0 == 0) ? V1 : V0.
2242 } 2389 }
2243 2390
2244 } // namespace dart 2391 } // namespace dart
2245 2392
2246 #endif // defined TARGET_ARCH_MIPS 2393 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698