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

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

Issue 2451893002: 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_mips.cc ('k') | runtime/vm/isolate.h » ('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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize)); 1566 __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize));
1567 __ j(EQUAL, &is_true, Assembler::kNearJump); 1567 __ j(EQUAL, &is_true, Assembler::kNearJump);
1568 __ LoadObject(RAX, Bool::False()); 1568 __ LoadObject(RAX, Bool::False());
1569 __ ret(); 1569 __ ret();
1570 __ Bind(&is_true); 1570 __ Bind(&is_true);
1571 __ LoadObject(RAX, Bool::True()); 1571 __ LoadObject(RAX, Bool::True());
1572 __ ret(); 1572 __ ret();
1573 } 1573 }
1574 1574
1575 1575
1576 static void RangeCheck(Assembler* assembler,
1577 Register reg,
1578 intptr_t low,
1579 intptr_t high,
1580 Condition cc,
1581 Label* target) {
1582 __ subq(reg, Immediate(low));
1583 __ cmpq(reg, Immediate(high - low));
1584 __ j(cc, target);
1585 }
1586
1587
1588 const Condition kIfNotInRange = ABOVE;
1589 const Condition kIfInRange = BELOW_EQUAL;
1590
1591
1592 static void JumpIfInteger(Assembler* assembler,
1593 Register cid,
1594 Label* target) {
1595 RangeCheck(assembler, cid, kSmiCid, kBigintCid, kIfInRange, target);
1596 }
1597
1598
1599 static void JumpIfNotInteger(Assembler* assembler,
1600 Register cid,
1601 Label* target) {
1602 RangeCheck(assembler, cid, kSmiCid, kBigintCid, kIfNotInRange, target);
1603 }
1604
1605
1606 static void JumpIfString(Assembler* assembler,
1607 Register cid,
1608 Label* target) {
1609 RangeCheck(assembler,
1610 cid,
1611 kOneByteStringCid,
1612 kExternalTwoByteStringCid,
1613 kIfInRange,
1614 target);
1615 }
1616
1617
1618 static void JumpIfNotString(Assembler* assembler,
1619 Register cid,
1620 Label* target) {
1621 RangeCheck(assembler,
1622 cid,
1623 kOneByteStringCid,
1624 kExternalTwoByteStringCid,
1625 kIfNotInRange,
1626 target);
1627 }
1628
1629
1630 // Return type quickly for simple types (not parameterized and not signature). 1576 // Return type quickly for simple types (not parameterized and not signature).
1631 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1577 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1632 Label fall_through, use_canonical_type, not_integer, not_double; 1578 Label fall_through;
1633 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1579 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1634 __ LoadClassIdMayBeSmi(RCX, RAX); 1580 __ LoadClassIdMayBeSmi(RCX, RAX);
1635 1581
1636 // RCX: untagged cid of instance (RAX). 1582 // RCX: untagged cid of instance (RAX).
1637 __ cmpq(RCX, Immediate(kClosureCid)); 1583 __ cmpq(RCX, Immediate(kClosureCid));
1638 __ j(EQUAL, &fall_through); // Instance is a closure. 1584 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Instance is a closure.
1639 1585
1640 __ cmpl(RCX, Immediate(kNumPredefinedCids)); 1586 __ LoadClassById(RDI, RCX);
1641 __ j(ABOVE, &use_canonical_type); 1587 // RDI: class of instance (RAX).
1642 1588
1643 // If object is a instance of _Double return double type.
1644 __ cmpl(RCX, Immediate(kDoubleCid));
1645 __ j(NOT_EQUAL, &not_double);
1646
1647 __ LoadIsolate(RAX);
1648 __ movq(RAX, Address(RAX, Isolate::object_store_offset()));
1649 __ movq(RAX, Address(RAX, ObjectStore::double_type_offset()));
1650 __ ret();
1651
1652 __ Bind(&not_double);
1653 // If object is an integer (smi, mint or bigint) return int type.
1654 __ movl(RAX, RCX);
1655 JumpIfNotInteger(assembler, RAX, &not_integer);
1656
1657 __ LoadIsolate(RAX);
1658 __ movq(RAX, Address(RAX, Isolate::object_store_offset()));
1659 __ movq(RAX, Address(RAX, ObjectStore::int_type_offset()));
1660 __ ret();
1661
1662 __ Bind(&not_integer);
1663 // If object is a string (one byte, two byte or external variants) return
1664 // string type.
1665 __ movq(RAX, RCX);
1666 JumpIfNotString(assembler, RAX, &use_canonical_type);
1667
1668 __ LoadIsolate(RAX);
1669 __ movq(RAX, Address(RAX, Isolate::object_store_offset()));
1670 __ movq(RAX, Address(RAX, ObjectStore::string_type_offset()));
1671 __ ret();
1672
1673 // Object is neither double, nor integer, nor string.
1674 __ Bind(&use_canonical_type);
1675 __ LoadClassById(RDI, RCX);
1676 __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset())); 1589 __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
1677 __ cmpq(RCX, Immediate(0)); 1590 __ cmpq(RCX, Immediate(0));
1678 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1591 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1679 __ movq(RAX, FieldAddress(RDI, Class::canonical_type_offset())); 1592 __ movq(RAX, FieldAddress(RDI, Class::canonical_type_offset()));
1680 __ CompareObject(RAX, Object::null_object()); 1593 __ CompareObject(RAX, Object::null_object());
1681 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Not yet set. 1594 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Not yet set.
1682 __ ret(); 1595 __ ret();
1683 1596
1684 __ Bind(&fall_through); 1597 __ Bind(&fall_through);
1685 } 1598 }
1686 1599
1687 1600
1688 void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
1689 Label fall_through, different_cids, equal, not_equal, not_integer;
1690
1691 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1692 __ LoadClassIdMayBeSmi(RCX, RAX);
1693
1694 // Check if left hand size is a closure. Closures are handled in the runtime.
1695 __ cmpq(RCX, Immediate(kClosureCid));
1696 __ j(EQUAL, &fall_through);
1697
1698 __ movq(RAX, Address(RSP, + 2 * kWordSize));
1699 __ LoadClassIdMayBeSmi(RDX, RAX);
1700
1701 // Check whether class ids match. If class ids don't match objects can still
1702 // have the same runtime type (e.g. multiple string implementation classes
1703 // map to a single String type).
1704 __ cmpq(RCX, RDX);
1705 __ j(NOT_EQUAL, &different_cids);
1706
1707 // Objects have the same class and neither is a closure.
1708 // Check if there are no type arguments. In this case we can return true.
1709 // Otherwise fall through into the runtime to handle comparison.
1710 __ LoadClassById(RDI, RCX);
1711 __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
1712 __ cmpq(RCX, Immediate(0));
1713 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1714
1715 __ Bind(&equal);
1716 __ LoadObject(RAX, Bool::True());
1717 __ ret();
1718
1719 // Class ids are different. Check if we are comparing runtime types of
1720 // two strings (with different representations) or two integers.
1721 __ Bind(&different_cids);
1722 __ cmpq(RCX, Immediate(kNumPredefinedCids));
1723 __ j(ABOVE_EQUAL, &not_equal);
1724
1725 __ movq(RAX, RCX);
1726 JumpIfNotInteger(assembler, RAX, &not_integer);
1727
1728 // First object is an integer. Check if the second is an integer too.
1729 // Otherwise types are unequal because only integers have the same runtime
1730 // type as other integers.
1731 JumpIfInteger(assembler, RDX, &equal);
1732 __ jmp(&not_equal);
1733
1734 __ Bind(&not_integer);
1735 // Check if the first object is a string. If it is not then
1736 // objects don't have the same runtime type because they have
1737 // different class ids and they are not strings or integers.
1738 JumpIfNotString(assembler, RCX, &not_equal);
1739 // First object is a string. Check if the second is a string too.
1740 JumpIfString(assembler, RDX, &equal);
1741 // Strings only have the same runtime type as other strings.
1742 // Fall-through to the not equal case.
1743
1744 __ Bind(&not_equal);
1745 __ LoadObject(RAX, Bool::False());
1746 __ ret();
1747
1748 __ Bind(&fall_through);
1749 }
1750
1751
1752 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1601 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1753 Label fall_through; 1602 Label fall_through;
1754 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1603 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1755 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); 1604 __ movq(RAX, FieldAddress(RAX, String::hash_offset()));
1756 __ cmpq(RAX, Immediate(0)); 1605 __ cmpq(RAX, Immediate(0));
1757 __ j(EQUAL, &fall_through, Assembler::kNearJump); 1606 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1758 __ ret(); 1607 __ ret();
1759 __ Bind(&fall_through); 1608 __ Bind(&fall_through);
1760 // Hash not yet computed. 1609 // Hash not yet computed.
1761 } 1610 }
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 __ Bind(&true_label); 2144 __ Bind(&true_label);
2296 __ LoadObject(RAX, Bool::True()); 2145 __ LoadObject(RAX, Bool::True());
2297 __ ret(); 2146 __ ret();
2298 } 2147 }
2299 2148
2300 #undef __ 2149 #undef __
2301 2150
2302 } // namespace dart 2151 } // namespace dart
2303 2152
2304 #endif // defined TARGET_ARCH_X64 2153 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698