| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <utility> | 6 #include <utility> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| 11 #include "src/compilation-cache.h" | 11 #include "src/compilation-cache.h" |
| 12 #include "src/execution.h" | 12 #include "src/execution.h" |
| 13 #include "src/factory.h" | 13 #include "src/factory.h" |
| 14 #include "src/global-handles.h" | 14 #include "src/global-handles.h" |
| 15 #include "src/ic/stub-cache.h" | 15 #include "src/ic/stub-cache.h" |
| 16 #include "src/macro-assembler.h" | 16 #include "src/macro-assembler.h" |
| 17 #include "src/smart-pointers.h" | 17 #include "src/smart-pointers.h" |
| 18 #include "test/cctest/cctest.h" | 18 #include "test/cctest/cctest.h" |
| 19 | 19 |
| 20 using namespace v8::internal; | 20 using namespace v8::internal; |
| 21 | 21 |
| 22 | 22 |
| 23 // TODO(ishell): fix this once ReconfigureProperty supports "non equivalent" | |
| 24 // transitions. | |
| 25 const bool IS_NON_EQUIVALENT_TRANSITION_SUPPORTED = false; | |
| 26 | |
| 27 | |
| 28 // TODO(ishell): fix this once TransitionToPrototype stops generalizing | 23 // TODO(ishell): fix this once TransitionToPrototype stops generalizing |
| 29 // all field representations (similar to crbug/448711 where elements kind | 24 // all field representations (similar to crbug/448711 where elements kind |
| 30 // and observed transitions caused generalization of all field representations). | 25 // and observed transitions caused generalization of all field representations). |
| 31 const bool IS_PROTO_TRANS_ISSUE_FIXED = false; | 26 const bool IS_PROTO_TRANS_ISSUE_FIXED = false; |
| 32 | 27 |
| 33 | 28 |
| 34 // TODO(ishell): fix this once TransitionToAccessorProperty is able to always | 29 // TODO(ishell): fix this once TransitionToAccessorProperty is able to always |
| 35 // keep map in fast mode. | 30 // keep map in fast mode. |
| 36 const bool IS_ACCESSOR_FIELD_SUPPORTED = false; | 31 const bool IS_ACCESSOR_FIELD_SUPPORTED = false; |
| 37 | 32 |
| (...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 | 1579 |
| 1585 CHECK(map->is_deprecated()); | 1580 CHECK(map->is_deprecated()); |
| 1586 CHECK_NE(*map, *new_map); | 1581 CHECK_NE(*map, *new_map); |
| 1587 CHECK(i == 0 || maps[i - 1]->is_deprecated()); | 1582 CHECK(i == 0 || maps[i - 1]->is_deprecated()); |
| 1588 CHECK(expectations.Check(*new_map)); | 1583 CHECK(expectations.Check(*new_map)); |
| 1589 | 1584 |
| 1590 Handle<Map> new_map2 = Map::Update(map2); | 1585 Handle<Map> new_map2 = Map::Update(map2); |
| 1591 CHECK(!new_map2->is_deprecated()); | 1586 CHECK(!new_map2->is_deprecated()); |
| 1592 CHECK(!new_map2->is_dictionary_map()); | 1587 CHECK(!new_map2->is_dictionary_map()); |
| 1593 | 1588 |
| 1594 if (!IS_NON_EQUIVALENT_TRANSITION_SUPPORTED) { | 1589 Handle<Map> tmp_map; |
| 1590 if (Map::TryUpdate(map2).ToHandle(&tmp_map)) { |
| 1591 // If Map::TryUpdate() manages to succeed the result must match the result |
| 1592 // of Map::Update(). |
| 1593 CHECK_EQ(*new_map2, *tmp_map); |
| 1594 } |
| 1595 |
| 1596 if (config.is_non_equevalent_transition()) { |
| 1595 // In case of non-equivalent transition currently we generalize all | 1597 // In case of non-equivalent transition currently we generalize all |
| 1596 // representations. | 1598 // representations. |
| 1597 for (int i = 0; i < kPropCount; i++) { | 1599 for (int i = 0; i < kPropCount; i++) { |
| 1598 expectations2.GeneralizeRepresentation(i); | 1600 expectations2.GeneralizeRepresentation(i); |
| 1599 } | 1601 } |
| 1600 CHECK(new_map2->GetBackPointer()->IsUndefined()); | 1602 CHECK(new_map2->GetBackPointer()->IsUndefined()); |
| 1601 CHECK(expectations2.Check(*new_map2)); | 1603 CHECK(expectations2.Check(*new_map2)); |
| 1602 } else { | 1604 } else { |
| 1603 CHECK(expectations.Check(*new_map2)); | 1605 CHECK(!new_map2->GetBackPointer()->IsUndefined()); |
| 1606 CHECK(expectations2.Check(*new_map2)); |
| 1604 } | 1607 } |
| 1605 } | 1608 } |
| 1606 | 1609 |
| 1607 Handle<Map> active_map = maps[kPropCount - 1]; | 1610 Handle<Map> active_map = maps[kPropCount - 1]; |
| 1608 CHECK(!active_map->is_deprecated()); | 1611 CHECK(!active_map->is_deprecated()); |
| 1609 | 1612 |
| 1610 // Update all deprecated maps and check that they are now the same. | 1613 // Update all deprecated maps and check that they are now the same. |
| 1611 Handle<Map> updated_map = Map::Update(map); | 1614 Handle<Map> updated_map = Map::Update(map); |
| 1612 CHECK_EQ(*active_map, *updated_map); | 1615 CHECK_EQ(*active_map, *updated_map); |
| 1613 for (int i = 0; i < kPropCount; i++) { | 1616 for (int i = 0; i < kPropCount; i++) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1625 Handle<HeapType> value_type = | 1628 Handle<HeapType> value_type = |
| 1626 HeapType::Class(Map::Create(isolate, 0), isolate); | 1629 HeapType::Class(Map::Create(isolate, 0), isolate); |
| 1627 | 1630 |
| 1628 struct TestConfig { | 1631 struct TestConfig { |
| 1629 Handle<Map> Transition(Handle<Map> map) { | 1632 Handle<Map> Transition(Handle<Map> map) { |
| 1630 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 1633 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, |
| 1631 INSERT_TRANSITION); | 1634 INSERT_TRANSITION); |
| 1632 } | 1635 } |
| 1633 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1636 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1634 bool generalizes_representations() const { return false; } | 1637 bool generalizes_representations() const { return false; } |
| 1638 bool is_non_equevalent_transition() const { return false; } |
| 1635 }; | 1639 }; |
| 1636 TestConfig config; | 1640 TestConfig config; |
| 1637 TestGeneralizeRepresentationWithSpecialTransition( | 1641 TestGeneralizeRepresentationWithSpecialTransition( |
| 1638 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1642 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1639 value_type, Representation::Tagged(), any_type); | 1643 value_type, Representation::Tagged(), any_type); |
| 1640 } | 1644 } |
| 1641 | 1645 |
| 1642 | 1646 |
| 1643 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { | 1647 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { |
| 1644 CcTest::InitializeVM(); | 1648 CcTest::InitializeVM(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1659 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 1663 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
| 1660 Representation::Smi(), | 1664 Representation::Smi(), |
| 1661 INSERT_TRANSITION).ToHandleChecked(); | 1665 INSERT_TRANSITION).ToHandleChecked(); |
| 1662 CHECK(!map->owns_descriptors()); | 1666 CHECK(!map->owns_descriptors()); |
| 1663 | 1667 |
| 1664 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 1668 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, |
| 1665 INSERT_TRANSITION); | 1669 INSERT_TRANSITION); |
| 1666 } | 1670 } |
| 1667 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1671 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1668 bool generalizes_representations() const { return false; } | 1672 bool generalizes_representations() const { return false; } |
| 1673 bool is_non_equevalent_transition() const { return false; } |
| 1669 }; | 1674 }; |
| 1670 TestConfig config; | 1675 TestConfig config; |
| 1671 TestGeneralizeRepresentationWithSpecialTransition( | 1676 TestGeneralizeRepresentationWithSpecialTransition( |
| 1672 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1677 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1673 value_type, Representation::Tagged(), any_type); | 1678 value_type, Representation::Tagged(), any_type); |
| 1674 } | 1679 } |
| 1675 | 1680 |
| 1676 | 1681 |
| 1677 TEST(ForObservedTransitionFromMapOwningDescriptor) { | 1682 TEST(ForObservedTransitionFromMapOwningDescriptor) { |
| 1678 CcTest::InitializeVM(); | 1683 CcTest::InitializeVM(); |
| 1679 v8::HandleScope scope(CcTest::isolate()); | 1684 v8::HandleScope scope(CcTest::isolate()); |
| 1680 Isolate* isolate = CcTest::i_isolate(); | 1685 Isolate* isolate = CcTest::i_isolate(); |
| 1681 Handle<HeapType> any_type = HeapType::Any(isolate); | 1686 Handle<HeapType> any_type = HeapType::Any(isolate); |
| 1682 Handle<HeapType> value_type = | 1687 Handle<HeapType> value_type = |
| 1683 HeapType::Class(Map::Create(isolate, 0), isolate); | 1688 HeapType::Class(Map::Create(isolate, 0), isolate); |
| 1684 | 1689 |
| 1685 struct TestConfig { | 1690 struct TestConfig { |
| 1686 Handle<Map> Transition(Handle<Map> map) { | 1691 Handle<Map> Transition(Handle<Map> map) { |
| 1687 return Map::CopyForObserved(map); | 1692 return Map::CopyForObserved(map); |
| 1688 } | 1693 } |
| 1689 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1694 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1690 bool generalizes_representations() const { return false; } | 1695 bool generalizes_representations() const { return false; } |
| 1696 bool is_non_equevalent_transition() const { return true; } |
| 1691 }; | 1697 }; |
| 1692 TestConfig config; | 1698 TestConfig config; |
| 1693 TestGeneralizeRepresentationWithSpecialTransition( | 1699 TestGeneralizeRepresentationWithSpecialTransition( |
| 1694 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1700 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1695 value_type, Representation::Tagged(), any_type); | 1701 value_type, Representation::Tagged(), any_type); |
| 1696 } | 1702 } |
| 1697 | 1703 |
| 1698 | 1704 |
| 1699 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { | 1705 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { |
| 1700 CcTest::InitializeVM(); | 1706 CcTest::InitializeVM(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1714 CHECK(map->owns_descriptors()); | 1720 CHECK(map->owns_descriptors()); |
| 1715 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 1721 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
| 1716 Representation::Smi(), | 1722 Representation::Smi(), |
| 1717 INSERT_TRANSITION).ToHandleChecked(); | 1723 INSERT_TRANSITION).ToHandleChecked(); |
| 1718 CHECK(!map->owns_descriptors()); | 1724 CHECK(!map->owns_descriptors()); |
| 1719 | 1725 |
| 1720 return Map::CopyForObserved(map); | 1726 return Map::CopyForObserved(map); |
| 1721 } | 1727 } |
| 1722 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1728 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1723 bool generalizes_representations() const { return false; } | 1729 bool generalizes_representations() const { return false; } |
| 1730 bool is_non_equevalent_transition() const { return true; } |
| 1724 }; | 1731 }; |
| 1725 TestConfig config; | 1732 TestConfig config; |
| 1726 TestGeneralizeRepresentationWithSpecialTransition( | 1733 TestGeneralizeRepresentationWithSpecialTransition( |
| 1727 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1734 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1728 value_type, Representation::Tagged(), any_type); | 1735 value_type, Representation::Tagged(), any_type); |
| 1729 } | 1736 } |
| 1730 | 1737 |
| 1731 | 1738 |
| 1732 TEST(PrototypeTransitionFromMapOwningDescriptor) { | 1739 TEST(PrototypeTransitionFromMapOwningDescriptor) { |
| 1733 CcTest::InitializeVM(); | 1740 CcTest::InitializeVM(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1747 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 1754 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
| 1748 } | 1755 } |
| 1749 | 1756 |
| 1750 Handle<Map> Transition(Handle<Map> map) { | 1757 Handle<Map> Transition(Handle<Map> map) { |
| 1751 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 1758 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
| 1752 } | 1759 } |
| 1753 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1760 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1754 bool generalizes_representations() const { | 1761 bool generalizes_representations() const { |
| 1755 return !IS_PROTO_TRANS_ISSUE_FIXED; | 1762 return !IS_PROTO_TRANS_ISSUE_FIXED; |
| 1756 } | 1763 } |
| 1764 bool is_non_equevalent_transition() const { return true; } |
| 1757 }; | 1765 }; |
| 1758 TestConfig config; | 1766 TestConfig config; |
| 1759 TestGeneralizeRepresentationWithSpecialTransition( | 1767 TestGeneralizeRepresentationWithSpecialTransition( |
| 1760 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1768 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1761 value_type, Representation::Tagged(), any_type); | 1769 value_type, Representation::Tagged(), any_type); |
| 1762 } | 1770 } |
| 1763 | 1771 |
| 1764 | 1772 |
| 1765 TEST(PrototypeTransitionFromMapNotOwningDescriptor) { | 1773 TEST(PrototypeTransitionFromMapNotOwningDescriptor) { |
| 1766 CcTest::InitializeVM(); | 1774 CcTest::InitializeVM(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1791 Representation::Smi(), | 1799 Representation::Smi(), |
| 1792 INSERT_TRANSITION).ToHandleChecked(); | 1800 INSERT_TRANSITION).ToHandleChecked(); |
| 1793 CHECK(!map->owns_descriptors()); | 1801 CHECK(!map->owns_descriptors()); |
| 1794 | 1802 |
| 1795 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 1803 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
| 1796 } | 1804 } |
| 1797 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1805 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1798 bool generalizes_representations() const { | 1806 bool generalizes_representations() const { |
| 1799 return !IS_PROTO_TRANS_ISSUE_FIXED; | 1807 return !IS_PROTO_TRANS_ISSUE_FIXED; |
| 1800 } | 1808 } |
| 1809 bool is_non_equevalent_transition() const { return true; } |
| 1801 }; | 1810 }; |
| 1802 TestConfig config; | 1811 TestConfig config; |
| 1803 TestGeneralizeRepresentationWithSpecialTransition( | 1812 TestGeneralizeRepresentationWithSpecialTransition( |
| 1804 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1813 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1805 value_type, Representation::Tagged(), any_type); | 1814 value_type, Representation::Tagged(), any_type); |
| 1806 } | 1815 } |
| 1807 | 1816 |
| 1808 | 1817 |
| 1809 //////////////////////////////////////////////////////////////////////////////// | 1818 //////////////////////////////////////////////////////////////////////////////// |
| 1810 // A set of tests for higher level transitioning mechanics. | 1819 // A set of tests for higher level transitioning mechanics. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2073 Handle<AccessorPair> pair = CreateAccessorPair(true, true); | 2082 Handle<AccessorPair> pair = CreateAccessorPair(true, true); |
| 2074 TransitionToAccessorConstantOperator transition_op(pair); | 2083 TransitionToAccessorConstantOperator transition_op(pair); |
| 2075 | 2084 |
| 2076 SameMapChecker checker; | 2085 SameMapChecker checker; |
| 2077 TestTransitionTo(transition_op, transition_op, checker); | 2086 TestTransitionTo(transition_op, transition_op, checker); |
| 2078 } | 2087 } |
| 2079 | 2088 |
| 2080 | 2089 |
| 2081 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. | 2090 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. |
| 2082 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) | 2091 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) |
| OLD | NEW |