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 |