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

Side by Side Diff: runtime/vm/intrinsifier_arm.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/intermediate_language.cc ('k') | runtime/vm/intrinsifier_arm64.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_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 1561 matching lines...) Expand 10 before | Expand all | Expand 10 after
1572 void Intrinsifier::ObjectEquals(Assembler* assembler) { 1572 void Intrinsifier::ObjectEquals(Assembler* assembler) {
1573 __ ldr(R0, Address(SP, 0 * kWordSize)); 1573 __ ldr(R0, Address(SP, 0 * kWordSize));
1574 __ ldr(R1, Address(SP, 1 * kWordSize)); 1574 __ ldr(R1, Address(SP, 1 * kWordSize));
1575 __ cmp(R0, Operand(R1)); 1575 __ cmp(R0, Operand(R1));
1576 __ LoadObject(R0, Bool::False(), NE); 1576 __ LoadObject(R0, Bool::False(), NE);
1577 __ LoadObject(R0, Bool::True(), EQ); 1577 __ LoadObject(R0, Bool::True(), EQ);
1578 __ Ret(); 1578 __ Ret();
1579 } 1579 }
1580 1580
1581 1581
1582 static void RangeCheck(Assembler* assembler,
1583 Register val,
1584 Register tmp,
1585 intptr_t low,
1586 intptr_t high,
1587 Condition cc,
1588 Label* target) {
1589 __ AddImmediate(tmp, val, -low);
1590 __ CompareImmediate(tmp, high - low);
1591 __ b(target, cc);
1592 }
1593
1594
1595 const Condition kIfNotInRange = HI;
1596 const Condition kIfInRange = LS;
1597
1598
1599 static void JumpIfInteger(Assembler* assembler,
1600 Register cid,
1601 Register tmp,
1602 Label* target) {
1603 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfInRange, target);
1604 }
1605
1606
1607 static void JumpIfNotInteger(Assembler* assembler,
1608 Register cid,
1609 Register tmp,
1610 Label* target) {
1611 RangeCheck(assembler, cid, tmp, kSmiCid, kBigintCid, kIfNotInRange, target);
1612 }
1613
1614
1615 static void JumpIfString(Assembler* assembler,
1616 Register cid,
1617 Register tmp,
1618 Label* target) {
1619 RangeCheck(assembler,
1620 cid,
1621 tmp,
1622 kOneByteStringCid,
1623 kExternalTwoByteStringCid,
1624 kIfInRange,
1625 target);
1626 }
1627
1628
1629 static void JumpIfNotString(Assembler* assembler,
1630 Register cid,
1631 Register tmp,
1632 Label* target) {
1633 RangeCheck(assembler,
1634 cid,
1635 tmp,
1636 kOneByteStringCid,
1637 kExternalTwoByteStringCid,
1638 kIfNotInRange,
1639 target);
1640 }
1641
1642
1582 // Return type quickly for simple types (not parameterized and not signature). 1643 // Return type quickly for simple types (not parameterized and not signature).
1583 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1644 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1584 Label fall_through; 1645 Label fall_through, use_canonical_type, not_double, not_integer;
1585 __ ldr(R0, Address(SP, 0 * kWordSize)); 1646 __ ldr(R0, Address(SP, 0 * kWordSize));
1586 __ LoadClassIdMayBeSmi(R1, R0); 1647 __ LoadClassIdMayBeSmi(R1, R0);
1648
1587 __ CompareImmediate(R1, kClosureCid); 1649 __ CompareImmediate(R1, kClosureCid);
1588 __ b(&fall_through, EQ); // Instance is a closure. 1650 __ b(&fall_through, EQ); // Instance is a closure.
1651
1652 __ CompareImmediate(R1, kNumPredefinedCids);
1653 __ b(&use_canonical_type, HI);
1654
1655 __ CompareImmediate(R1, kDoubleCid);
1656 __ b(&not_double, NE);
1657
1658 __ LoadIsolate(R0);
1659 __ LoadFromOffset(kWord, R0, R0, Isolate::object_store_offset());
1660 __ LoadFromOffset(kWord, R0, R0, ObjectStore::double_type_offset());
1661 __ Ret();
1662
1663 __ Bind(&not_double);
1664 JumpIfNotInteger(assembler, R1, R0, &not_integer);
1665 __ LoadIsolate(R0);
1666 __ LoadFromOffset(kWord, R0, R0, Isolate::object_store_offset());
1667 __ LoadFromOffset(kWord, R0, R0, ObjectStore::int_type_offset());
1668 __ Ret();
1669
1670 __ Bind(&not_integer);
1671 JumpIfNotString(assembler, R1, R0, &use_canonical_type);
1672 __ LoadIsolate(R0);
1673 __ LoadFromOffset(kWord, R0, R0, Isolate::object_store_offset());
1674 __ LoadFromOffset(kWord, R0, R0, ObjectStore::string_type_offset());
1675 __ Ret();
1676
1677 __ Bind(&use_canonical_type);
1589 __ LoadClassById(R2, R1); 1678 __ LoadClassById(R2, R1);
1590 // R2: class of instance (R0).
1591
1592 __ ldrh(R3, FieldAddress(R2, Class::num_type_arguments_offset())); 1679 __ ldrh(R3, FieldAddress(R2, Class::num_type_arguments_offset()));
1593 __ CompareImmediate(R3, 0); 1680 __ CompareImmediate(R3, 0);
1594 __ b(&fall_through, NE); 1681 __ b(&fall_through, NE);
1595 1682
1596 __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset())); 1683 __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset()));
1597 __ CompareObject(R0, Object::null_object()); 1684 __ CompareObject(R0, Object::null_object());
1598 __ b(&fall_through, EQ); 1685 __ b(&fall_through, EQ);
1599 __ Ret(); 1686 __ Ret();
1600 1687
1601 __ Bind(&fall_through); 1688 __ Bind(&fall_through);
1602 } 1689 }
1603 1690
1604 1691
1692 void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
1693 Label fall_through, different_cids, equal, not_equal, not_integer;
1694 __ ldr(R0, Address(SP, 0 * kWordSize));
1695 __ LoadClassIdMayBeSmi(R1, R0);
1696
1697 // Check if left hand size is a closure. Closures are handled in the runtime.
1698 __ CompareImmediate(R1, kClosureCid);
1699 __ b(&fall_through, EQ);
1700
1701 __ ldr(R0, Address(SP, 1 * kWordSize));
1702 __ LoadClassIdMayBeSmi(R2, R0);
1703
1704 // Check whether class ids match. If class ids don't match objects can still
1705 // have the same runtime type (e.g. multiple string implementation classes
1706 // map to a single String type).
1707 __ cmp(R1, Operand(R2));
1708 __ b(&different_cids, NE);
1709
1710 // Objects have the same class and neither is a closure.
1711 // Check if there are no type arguments. In this case we can return true.
1712 // Otherwise fall through into the runtime to handle comparison.
1713 __ LoadClassById(R3, R1);
1714 __ ldrh(R3, FieldAddress(R3, Class::num_type_arguments_offset()));
1715 __ CompareImmediate(R3, 0);
1716 __ b(&fall_through, NE);
1717
1718 __ Bind(&equal);
1719 __ LoadObject(R0, Bool::True());
1720 __ Ret();
1721
1722 // Class ids are different. Check if we are comparing runtime types of
1723 // two strings (with different representations) or two integers.
1724 __ Bind(&different_cids);
1725 __ CompareImmediate(R1, kNumPredefinedCids);
1726 __ b(&not_equal, HI);
1727
1728 // Check if both are integers.
1729 JumpIfNotInteger(assembler, R1, R0, &not_integer);
1730 JumpIfInteger(assembler, R2, R0, &equal);
1731 __ b(&not_equal);
1732
1733 __ Bind(&not_integer);
1734 // Check if both are strings.
1735 JumpIfNotString(assembler, R1, R0, &not_equal);
1736 JumpIfString(assembler, R2, R0, &equal);
1737
1738 // Neither strings nor integers and have different class ids.
1739 __ Bind(&not_equal);
1740 __ LoadObject(R0, Bool::False());
1741 __ Ret();
1742
1743 __ Bind(&fall_through);
1744 }
1745
1746
1605 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1747 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1606 __ ldr(R0, Address(SP, 0 * kWordSize)); 1748 __ ldr(R0, Address(SP, 0 * kWordSize));
1607 __ ldr(R0, FieldAddress(R0, String::hash_offset())); 1749 __ ldr(R0, FieldAddress(R0, String::hash_offset()));
1608 __ cmp(R0, Operand(0)); 1750 __ cmp(R0, Operand(0));
1609 __ bx(LR, NE); // Hash not yet computed. 1751 __ bx(LR, NE); // Hash not yet computed.
1610 } 1752 }
1611 1753
1612 1754
1613 void GenerateSubstringMatchesSpecialization(Assembler* assembler, 1755 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1614 intptr_t receiver_cid, 1756 intptr_t receiver_cid,
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 __ ldr(R0, Address(R0, TimelineStream::enabled_offset())); 2295 __ ldr(R0, Address(R0, TimelineStream::enabled_offset()));
2154 __ cmp(R0, Operand(0)); 2296 __ cmp(R0, Operand(0));
2155 __ LoadObject(R0, Bool::True(), NE); 2297 __ LoadObject(R0, Bool::True(), NE);
2156 __ LoadObject(R0, Bool::False(), EQ); 2298 __ LoadObject(R0, Bool::False(), EQ);
2157 __ Ret(); 2299 __ Ret();
2158 } 2300 }
2159 2301
2160 } // namespace dart 2302 } // namespace dart
2161 2303
2162 #endif // defined TARGET_ARCH_ARM 2304 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intrinsifier_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698