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

Side by Side Diff: runtime/vm/intrinsifier_x64.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_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
1576 // Return type quickly for simple types (not parameterized and not signature). 1630 // Return type quickly for simple types (not parameterized and not signature).
1577 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1631 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1578 Label fall_through; 1632 Label fall_through, use_canonical_type, not_integer, not_double;
1579 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1633 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1580 __ LoadClassIdMayBeSmi(RCX, RAX); 1634 __ LoadClassIdMayBeSmi(RCX, RAX);
1581 1635
1582 // RCX: untagged cid of instance (RAX). 1636 // RCX: untagged cid of instance (RAX).
1583 __ cmpq(RCX, Immediate(kClosureCid)); 1637 __ cmpq(RCX, Immediate(kClosureCid));
1584 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Instance is a closure. 1638 __ j(EQUAL, &fall_through); // Instance is a closure.
1585 1639
1640 __ cmpl(RCX, Immediate(kNumPredefinedCids));
1641 __ j(ABOVE, &use_canonical_type);
1642
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);
1586 __ LoadClassById(RDI, RCX); 1675 __ LoadClassById(RDI, RCX);
1587 // RDI: class of instance (RAX).
1588
1589 __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset())); 1676 __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
1590 __ cmpq(RCX, Immediate(0)); 1677 __ cmpq(RCX, Immediate(0));
1591 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1678 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1592 __ movq(RAX, FieldAddress(RDI, Class::canonical_type_offset())); 1679 __ movq(RAX, FieldAddress(RDI, Class::canonical_type_offset()));
1593 __ CompareObject(RAX, Object::null_object()); 1680 __ CompareObject(RAX, Object::null_object());
1594 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Not yet set. 1681 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Not yet set.
1595 __ ret(); 1682 __ ret();
1596 1683
1597 __ Bind(&fall_through); 1684 __ Bind(&fall_through);
1598 } 1685 }
1599 1686
1600 1687
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
1601 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1752 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1602 Label fall_through; 1753 Label fall_through;
1603 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1754 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1604 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); 1755 __ movq(RAX, FieldAddress(RAX, String::hash_offset()));
1605 __ cmpq(RAX, Immediate(0)); 1756 __ cmpq(RAX, Immediate(0));
1606 __ j(EQUAL, &fall_through, Assembler::kNearJump); 1757 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1607 __ ret(); 1758 __ ret();
1608 __ Bind(&fall_through); 1759 __ Bind(&fall_through);
1609 // Hash not yet computed. 1760 // Hash not yet computed.
1610 } 1761 }
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 __ Bind(&true_label); 2295 __ Bind(&true_label);
2145 __ LoadObject(RAX, Bool::True()); 2296 __ LoadObject(RAX, Bool::True());
2146 __ ret(); 2297 __ ret();
2147 } 2298 }
2148 2299
2149 #undef __ 2300 #undef __
2150 2301
2151 } // namespace dart 2302 } // namespace dart
2152 2303
2153 #endif // defined TARGET_ARCH_X64 2304 #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