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

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

Issue 2379733002: Recognize and optimize a.runtimeType == b.runtimeType pattern. (Closed)
Patch Set: fix lint 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_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 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 __ lw(T1, Address(SP, 1 * kWordSize)); 1682 __ lw(T1, Address(SP, 1 * kWordSize));
1683 __ beq(T0, T1, &is_true); 1683 __ beq(T0, T1, &is_true);
1684 __ LoadObject(V0, Bool::False()); 1684 __ LoadObject(V0, Bool::False());
1685 __ Ret(); 1685 __ Ret();
1686 __ Bind(&is_true); 1686 __ Bind(&is_true);
1687 __ LoadObject(V0, Bool::True()); 1687 __ LoadObject(V0, Bool::True());
1688 __ Ret(); 1688 __ Ret();
1689 } 1689 }
1690 1690
1691 1691
1692 enum RangeCheckCondition {
1693 kIfNotInRange, kIfInRange
1694 };
1695
1696
1697 static void RangeCheck(Assembler* assembler,
1698 Register val,
1699 Register tmp,
1700 intptr_t low,
1701 intptr_t high,
1702 RangeCheckCondition cc,
1703 Label* target) {
1704 __ AddImmediate(tmp, val, -low);
1705 if (cc == kIfInRange) {
1706 __ BranchUnsignedLessEqual(tmp, Immediate(high - low), target);
1707 } else {
1708 ASSERT(cc == kIfNotInRange);
1709 __ BranchUnsignedGreater(tmp, Immediate(high - low), target);
1710 }
1711 }
1712
1713
1714 static void JumpIfInteger(Assembler* assembler,
1715 Register cid,
1716 Register tmp,
1717 Label* target) {
1718 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfInRange, target);
1719 }
1720
1721
1722 static void JumpIfNotInteger(Assembler* assembler,
1723 Register cid,
1724 Register tmp,
1725 Label* target) {
1726 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfNotInRange, target);
1727 }
1728
1729
1730 static void JumpIfString(Assembler* assembler,
1731 Register cid,
1732 Register tmp,
1733 Label* target) {
1734 RangeCheck(assembler,
1735 cid,
1736 tmp,
1737 kOneByteStringCid,
1738 kExternalTwoByteStringCid,
1739 kIfInRange,
1740 target);
1741 }
1742
1743
1744 static void JumpIfNotString(Assembler* assembler,
1745 Register cid,
1746 Register tmp,
1747 Label* target) {
1748 RangeCheck(assembler,
1749 cid,
1750 tmp,
1751 kOneByteStringCid,
1752 kExternalTwoByteStringCid,
1753 kIfNotInRange,
1754 target);
1755 }
1756
1757
1692 // Return type quickly for simple types (not parameterized and not signature). 1758 // Return type quickly for simple types (not parameterized and not signature).
1693 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1759 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1694 Label fall_through; 1760 Label fall_through, use_canonical_type, not_integer, not_double;
1695 __ lw(T0, Address(SP, 0 * kWordSize)); 1761 __ lw(T0, Address(SP, 0 * kWordSize));
1696 __ LoadClassIdMayBeSmi(T1, T0); 1762 __ LoadClassIdMayBeSmi(T1, T0);
1763
1764 // Closures are handled in the runtime.
1697 __ BranchEqual(T1, Immediate(kClosureCid), &fall_through); 1765 __ BranchEqual(T1, Immediate(kClosureCid), &fall_through);
1766
1767 __ BranchUnsignedGreaterEqual(
1768 T1, Immediate(kNumPredefinedCids), &use_canonical_type);
1769
1770 __ BranchNotEqual(T1, Immediate(kDoubleCid), &not_double);
1771 // Object is a double.
1772 __ LoadIsolate(T1);
1773 __ LoadFromOffset(T1, T1, Isolate::object_store_offset());
1774 __ LoadFromOffset(V0, T1, ObjectStore::double_type_offset());
1775 __ Ret();
1776
1777 __ Bind(&not_double);
1778 JumpIfNotInteger(assembler, T1, T2, &not_integer);
1779 // Object is an integer.
1780 __ LoadIsolate(T1);
1781 __ LoadFromOffset(T1, T1, Isolate::object_store_offset());
1782 __ LoadFromOffset(V0, T1, ObjectStore::int_type_offset());
1783 __ Ret();
1784
1785 __ Bind(&not_integer);
1786 JumpIfNotString(assembler, T1, T2, &use_canonical_type);
1787 // Object is a string.
1788 __ LoadIsolate(T1);
1789 __ LoadFromOffset(T1, T1, Isolate::object_store_offset());
1790 __ LoadFromOffset(V0, T1, ObjectStore::string_type_offset());
1791 __ Ret();
1792
1793 __ Bind(&use_canonical_type);
1698 __ LoadClassById(T2, T1); 1794 __ LoadClassById(T2, T1);
1699 // T2: class of instance (T0).
1700
1701 __ lhu(T1, FieldAddress(T2, Class::num_type_arguments_offset())); 1795 __ lhu(T1, FieldAddress(T2, Class::num_type_arguments_offset()));
1702 __ BranchNotEqual(T1, Immediate(0), &fall_through); 1796 __ BranchNotEqual(T1, Immediate(0), &fall_through);
1703 1797
1704 __ lw(V0, FieldAddress(T2, Class::canonical_type_offset())); 1798 __ lw(V0, FieldAddress(T2, Class::canonical_type_offset()));
1705 __ BranchEqual(V0, Object::null_object(), &fall_through); 1799 __ BranchEqual(V0, Object::null_object(), &fall_through);
1706 __ Ret(); 1800 __ Ret();
1707 1801
1708 __ Bind(&fall_through); 1802 __ Bind(&fall_through);
1709 } 1803 }
1710 1804
1711 1805
1806 void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
1807 Label fall_through, different_cids, equal, not_equal, not_integer;
1808
1809 __ lw(T0, Address(SP, 0 * kWordSize));
1810 __ LoadClassIdMayBeSmi(T1, T0);
1811
1812 // Closures are handled in the runtime.
1813 __ BranchEqual(T1, Immediate(kClosureCid), &fall_through);
1814
1815 __ lw(T0, Address(SP, 1 * kWordSize));
1816 __ LoadClassIdMayBeSmi(T2, T0);
1817
1818 // Check whether class ids match. If class ids don't match objects can still
1819 // have the same runtime type (e.g. multiple string implementation classes
1820 // map to a single String type).
1821 __ BranchNotEqual(T1, T2, &different_cids);
1822
1823 // Objects have the same class and neither is a closure.
1824 // Check if there are no type arguments. In this case we can return true.
1825 // Otherwise fall through into the runtime to handle comparison.
1826 __ LoadClassById(T2, T1);
1827 __ lhu(T1, FieldAddress(T2, Class::num_type_arguments_offset()));
1828 __ BranchNotEqual(T1, Immediate(0), &fall_through);
1829
1830 __ Bind(&equal);
1831 __ LoadObject(V0, Bool::True());
1832 __ Ret();
1833
1834 // Class ids are different. Check if we are comparing runtime types of
1835 // two strings (with different representations) or two integers.
1836 __ Bind(&different_cids);
1837 __ BranchUnsignedGreaterEqual(
1838 T1, Immediate(kNumPredefinedCids), &not_equal);
1839
1840 // Check if both are integers.
1841 JumpIfNotInteger(assembler, T1, T0, &not_integer);
1842 JumpIfInteger(assembler, T2, T0, &equal);
1843 __ b(&not_equal);
1844
1845 __ Bind(&not_integer);
1846 // Check if both are strings.
1847 JumpIfNotString(assembler, T1, T0, &not_equal);
1848 JumpIfString(assembler, T2, T0, &equal);
1849
1850 // Neither strings nor integers and have different class ids.
1851 __ Bind(&not_equal);
1852 __ LoadObject(V0, Bool::False());
1853 __ Ret();
1854
1855 __ Bind(&fall_through);
1856 }
1857
1858
1712 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1859 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1713 Label fall_through; 1860 Label fall_through;
1714 __ lw(T0, Address(SP, 0 * kWordSize)); 1861 __ lw(T0, Address(SP, 0 * kWordSize));
1715 __ lw(V0, FieldAddress(T0, String::hash_offset())); 1862 __ lw(V0, FieldAddress(T0, String::hash_offset()));
1716 __ beq(V0, ZR, &fall_through); 1863 __ beq(V0, ZR, &fall_through);
1717 __ Ret(); 1864 __ Ret();
1718 __ Bind(&fall_through); // Hash not yet computed. 1865 __ Bind(&fall_through); // Hash not yet computed.
1719 } 1866 }
1720 1867
1721 1868
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2258 __ lw(T0, Address(V0, TimelineStream::enabled_offset())); 2405 __ lw(T0, Address(V0, TimelineStream::enabled_offset()));
2259 __ LoadObject(V0, Bool::True()); 2406 __ LoadObject(V0, Bool::True());
2260 __ LoadObject(V1, Bool::False()); 2407 __ LoadObject(V1, Bool::False());
2261 __ Ret(); 2408 __ Ret();
2262 __ delay_slot()->movz(V0, V1, T0); // V0 = (T0 == 0) ? V1 : V0. 2409 __ delay_slot()->movz(V0, V1, T0); // V0 = (T0 == 0) ? V1 : V0.
2263 } 2410 }
2264 2411
2265 } // namespace dart 2412 } // namespace dart
2266 2413
2267 #endif // defined TARGET_ARCH_MIPS 2414 #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