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