| 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 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 | 1580 |
| 1586 CHECK(map->is_deprecated()); | 1581 CHECK(map->is_deprecated()); |
| 1587 CHECK_NE(*map, *new_map); | 1582 CHECK_NE(*map, *new_map); |
| 1588 CHECK(i == 0 || maps[i - 1]->is_deprecated()); | 1583 CHECK(i == 0 || maps[i - 1]->is_deprecated()); |
| 1589 CHECK(expectations.Check(*new_map)); | 1584 CHECK(expectations.Check(*new_map)); |
| 1590 | 1585 |
| 1591 Handle<Map> new_map2 = Map::Update(map2); | 1586 Handle<Map> new_map2 = Map::Update(map2); |
| 1592 CHECK(!new_map2->is_deprecated()); | 1587 CHECK(!new_map2->is_deprecated()); |
| 1593 CHECK(!new_map2->is_dictionary_map()); | 1588 CHECK(!new_map2->is_dictionary_map()); |
| 1594 | 1589 |
| 1595 if (!IS_NON_EQUIVALENT_TRANSITION_SUPPORTED) { | 1590 Handle<Map> tmp_map; |
| 1591 if (Map::TryUpdate(map2).ToHandle(&tmp_map)) { |
| 1592 // If Map::TryUpdate() manages to succeed the result must match the result |
| 1593 // of Map::Update(). |
| 1594 CHECK_EQ(*new_map2, *tmp_map); |
| 1595 } |
| 1596 |
| 1597 if (config.is_non_equevalent_transition()) { |
| 1596 // In case of non-equivalent transition currently we generalize all | 1598 // In case of non-equivalent transition currently we generalize all |
| 1597 // representations. | 1599 // representations. |
| 1598 for (int i = 0; i < kPropCount; i++) { | 1600 for (int i = 0; i < kPropCount; i++) { |
| 1599 expectations2.GeneralizeRepresentation(i); | 1601 expectations2.GeneralizeRepresentation(i); |
| 1600 } | 1602 } |
| 1601 CHECK(new_map2->GetBackPointer()->IsUndefined()); | 1603 CHECK(new_map2->GetBackPointer()->IsUndefined()); |
| 1602 CHECK(expectations2.Check(*new_map2)); | 1604 CHECK(expectations2.Check(*new_map2)); |
| 1603 } else { | 1605 } else { |
| 1604 CHECK(expectations.Check(*new_map2)); | 1606 CHECK(!new_map2->GetBackPointer()->IsUndefined()); |
| 1607 CHECK(expectations2.Check(*new_map2)); |
| 1605 } | 1608 } |
| 1606 } | 1609 } |
| 1607 | 1610 |
| 1608 Handle<Map> active_map = maps[kPropCount - 1]; | 1611 Handle<Map> active_map = maps[kPropCount - 1]; |
| 1609 CHECK(!active_map->is_deprecated()); | 1612 CHECK(!active_map->is_deprecated()); |
| 1610 | 1613 |
| 1611 // Update all deprecated maps and check that they are now the same. | 1614 // Update all deprecated maps and check that they are now the same. |
| 1612 Handle<Map> updated_map = Map::Update(map); | 1615 Handle<Map> updated_map = Map::Update(map); |
| 1613 CHECK_EQ(*active_map, *updated_map); | 1616 CHECK_EQ(*active_map, *updated_map); |
| 1614 for (int i = 0; i < kPropCount; i++) { | 1617 for (int i = 0; i < kPropCount; i++) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1626 Handle<HeapType> value_type = | 1629 Handle<HeapType> value_type = |
| 1627 HeapType::Class(Map::Create(isolate, 0), isolate); | 1630 HeapType::Class(Map::Create(isolate, 0), isolate); |
| 1628 | 1631 |
| 1629 struct TestConfig { | 1632 struct TestConfig { |
| 1630 Handle<Map> Transition(Handle<Map> map) { | 1633 Handle<Map> Transition(Handle<Map> map) { |
| 1631 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 1634 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, |
| 1632 INSERT_TRANSITION); | 1635 INSERT_TRANSITION); |
| 1633 } | 1636 } |
| 1634 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1637 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1635 bool generalizes_representations() const { return false; } | 1638 bool generalizes_representations() const { return false; } |
| 1639 bool is_non_equevalent_transition() const { return false; } |
| 1636 }; | 1640 }; |
| 1637 TestConfig config; | 1641 TestConfig config; |
| 1638 TestGeneralizeRepresentationWithSpecialTransition( | 1642 TestGeneralizeRepresentationWithSpecialTransition( |
| 1639 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1643 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1640 value_type, Representation::Tagged(), any_type); | 1644 value_type, Representation::Tagged(), any_type); |
| 1641 } | 1645 } |
| 1642 | 1646 |
| 1643 | 1647 |
| 1644 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { | 1648 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { |
| 1645 CcTest::InitializeVM(); | 1649 CcTest::InitializeVM(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1660 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 1664 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
| 1661 Representation::Smi(), | 1665 Representation::Smi(), |
| 1662 INSERT_TRANSITION).ToHandleChecked(); | 1666 INSERT_TRANSITION).ToHandleChecked(); |
| 1663 CHECK(!map->owns_descriptors()); | 1667 CHECK(!map->owns_descriptors()); |
| 1664 | 1668 |
| 1665 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 1669 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, |
| 1666 INSERT_TRANSITION); | 1670 INSERT_TRANSITION); |
| 1667 } | 1671 } |
| 1668 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1672 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1669 bool generalizes_representations() const { return false; } | 1673 bool generalizes_representations() const { return false; } |
| 1674 bool is_non_equevalent_transition() const { return false; } |
| 1670 }; | 1675 }; |
| 1671 TestConfig config; | 1676 TestConfig config; |
| 1672 TestGeneralizeRepresentationWithSpecialTransition( | 1677 TestGeneralizeRepresentationWithSpecialTransition( |
| 1673 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1678 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1674 value_type, Representation::Tagged(), any_type); | 1679 value_type, Representation::Tagged(), any_type); |
| 1675 } | 1680 } |
| 1676 | 1681 |
| 1677 | 1682 |
| 1678 TEST(ForObservedTransitionFromMapOwningDescriptor) { | 1683 TEST(ForObservedTransitionFromMapOwningDescriptor) { |
| 1679 CcTest::InitializeVM(); | 1684 CcTest::InitializeVM(); |
| 1680 v8::HandleScope scope(CcTest::isolate()); | 1685 v8::HandleScope scope(CcTest::isolate()); |
| 1681 Isolate* isolate = CcTest::i_isolate(); | 1686 Isolate* isolate = CcTest::i_isolate(); |
| 1682 Handle<HeapType> any_type = HeapType::Any(isolate); | 1687 Handle<HeapType> any_type = HeapType::Any(isolate); |
| 1683 Handle<HeapType> value_type = | 1688 Handle<HeapType> value_type = |
| 1684 HeapType::Class(Map::Create(isolate, 0), isolate); | 1689 HeapType::Class(Map::Create(isolate, 0), isolate); |
| 1685 | 1690 |
| 1686 struct TestConfig { | 1691 struct TestConfig { |
| 1687 Handle<Map> Transition(Handle<Map> map) { | 1692 Handle<Map> Transition(Handle<Map> map) { |
| 1688 return Map::CopyForObserved(map); | 1693 return Map::CopyForObserved(map); |
| 1689 } | 1694 } |
| 1690 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1695 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1691 bool generalizes_representations() const { return false; } | 1696 bool generalizes_representations() const { return false; } |
| 1697 bool is_non_equevalent_transition() const { return true; } |
| 1692 }; | 1698 }; |
| 1693 TestConfig config; | 1699 TestConfig config; |
| 1694 TestGeneralizeRepresentationWithSpecialTransition( | 1700 TestGeneralizeRepresentationWithSpecialTransition( |
| 1695 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1701 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1696 value_type, Representation::Tagged(), any_type); | 1702 value_type, Representation::Tagged(), any_type); |
| 1697 } | 1703 } |
| 1698 | 1704 |
| 1699 | 1705 |
| 1700 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { | 1706 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { |
| 1701 CcTest::InitializeVM(); | 1707 CcTest::InitializeVM(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1715 CHECK(map->owns_descriptors()); | 1721 CHECK(map->owns_descriptors()); |
| 1716 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 1722 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
| 1717 Representation::Smi(), | 1723 Representation::Smi(), |
| 1718 INSERT_TRANSITION).ToHandleChecked(); | 1724 INSERT_TRANSITION).ToHandleChecked(); |
| 1719 CHECK(!map->owns_descriptors()); | 1725 CHECK(!map->owns_descriptors()); |
| 1720 | 1726 |
| 1721 return Map::CopyForObserved(map); | 1727 return Map::CopyForObserved(map); |
| 1722 } | 1728 } |
| 1723 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1729 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1724 bool generalizes_representations() const { return false; } | 1730 bool generalizes_representations() const { return false; } |
| 1731 bool is_non_equevalent_transition() const { return true; } |
| 1725 }; | 1732 }; |
| 1726 TestConfig config; | 1733 TestConfig config; |
| 1727 TestGeneralizeRepresentationWithSpecialTransition( | 1734 TestGeneralizeRepresentationWithSpecialTransition( |
| 1728 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1735 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1729 value_type, Representation::Tagged(), any_type); | 1736 value_type, Representation::Tagged(), any_type); |
| 1730 } | 1737 } |
| 1731 | 1738 |
| 1732 | 1739 |
| 1733 TEST(PrototypeTransitionFromMapOwningDescriptor) { | 1740 TEST(PrototypeTransitionFromMapOwningDescriptor) { |
| 1734 CcTest::InitializeVM(); | 1741 CcTest::InitializeVM(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1748 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 1755 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
| 1749 } | 1756 } |
| 1750 | 1757 |
| 1751 Handle<Map> Transition(Handle<Map> map) { | 1758 Handle<Map> Transition(Handle<Map> map) { |
| 1752 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 1759 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
| 1753 } | 1760 } |
| 1754 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1761 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1755 bool generalizes_representations() const { | 1762 bool generalizes_representations() const { |
| 1756 return !IS_PROTO_TRANS_ISSUE_FIXED; | 1763 return !IS_PROTO_TRANS_ISSUE_FIXED; |
| 1757 } | 1764 } |
| 1765 bool is_non_equevalent_transition() const { return true; } |
| 1758 }; | 1766 }; |
| 1759 TestConfig config; | 1767 TestConfig config; |
| 1760 TestGeneralizeRepresentationWithSpecialTransition( | 1768 TestGeneralizeRepresentationWithSpecialTransition( |
| 1761 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1769 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1762 value_type, Representation::Tagged(), any_type); | 1770 value_type, Representation::Tagged(), any_type); |
| 1763 } | 1771 } |
| 1764 | 1772 |
| 1765 | 1773 |
| 1766 TEST(PrototypeTransitionFromMapNotOwningDescriptor) { | 1774 TEST(PrototypeTransitionFromMapNotOwningDescriptor) { |
| 1767 CcTest::InitializeVM(); | 1775 CcTest::InitializeVM(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1792 Representation::Smi(), | 1800 Representation::Smi(), |
| 1793 INSERT_TRANSITION).ToHandleChecked(); | 1801 INSERT_TRANSITION).ToHandleChecked(); |
| 1794 CHECK(!map->owns_descriptors()); | 1802 CHECK(!map->owns_descriptors()); |
| 1795 | 1803 |
| 1796 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 1804 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
| 1797 } | 1805 } |
| 1798 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 1806 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1799 bool generalizes_representations() const { | 1807 bool generalizes_representations() const { |
| 1800 return !IS_PROTO_TRANS_ISSUE_FIXED; | 1808 return !IS_PROTO_TRANS_ISSUE_FIXED; |
| 1801 } | 1809 } |
| 1810 bool is_non_equevalent_transition() const { return true; } |
| 1802 }; | 1811 }; |
| 1803 TestConfig config; | 1812 TestConfig config; |
| 1804 TestGeneralizeRepresentationWithSpecialTransition( | 1813 TestGeneralizeRepresentationWithSpecialTransition( |
| 1805 config, Representation::Smi(), any_type, Representation::HeapObject(), | 1814 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1806 value_type, Representation::Tagged(), any_type); | 1815 value_type, Representation::Tagged(), any_type); |
| 1807 } | 1816 } |
| 1808 | 1817 |
| 1809 | 1818 |
| 1810 //////////////////////////////////////////////////////////////////////////////// | 1819 //////////////////////////////////////////////////////////////////////////////// |
| 1811 // A set of tests for higher level transitioning mechanics. | 1820 // A set of tests for higher level transitioning mechanics. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 Handle<AccessorPair> pair = CreateAccessorPair(true, true); | 2083 Handle<AccessorPair> pair = CreateAccessorPair(true, true); |
| 2075 TransitionToAccessorConstantOperator transition_op(pair); | 2084 TransitionToAccessorConstantOperator transition_op(pair); |
| 2076 | 2085 |
| 2077 SameMapChecker checker; | 2086 SameMapChecker checker; |
| 2078 TestTransitionTo(transition_op, transition_op, checker); | 2087 TestTransitionTo(transition_op, transition_op, checker); |
| 2079 } | 2088 } |
| 2080 | 2089 |
| 2081 | 2090 |
| 2082 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. | 2091 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. |
| 2083 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) | 2092 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) |
| OLD | NEW |