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 "test/cctest/test-api.h" | 8 #include "test/cctest/test-api.h" |
9 | 9 |
10 #include "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 if (details.attributes() != attributes) return false; | 79 if (details.attributes() != attributes) return false; |
80 if (!details.representation().Equals(representation)) return false; | 80 if (!details.representation().Equals(representation)) return false; |
81 if (field_index >= 0 && details.field_index() != field_index) return false; | 81 if (field_index >= 0 && details.field_index() != field_index) return false; |
82 return true; | 82 return true; |
83 } | 83 } |
84 | 84 |
85 | 85 |
86 class Expectations { | 86 class Expectations { |
87 static const int MAX_PROPERTIES = 10; | 87 static const int MAX_PROPERTIES = 10; |
88 Isolate* isolate_; | 88 Isolate* isolate_; |
| 89 ElementsKind elements_kind_; |
89 PropertyType types_[MAX_PROPERTIES]; | 90 PropertyType types_[MAX_PROPERTIES]; |
90 PropertyAttributes attributes_[MAX_PROPERTIES]; | 91 PropertyAttributes attributes_[MAX_PROPERTIES]; |
91 Representation representations_[MAX_PROPERTIES]; | 92 Representation representations_[MAX_PROPERTIES]; |
92 // FieldType for kField, value for DATA_CONSTANT and getter for | 93 // FieldType for kField, value for DATA_CONSTANT and getter for |
93 // ACCESSOR_CONSTANT. | 94 // ACCESSOR_CONSTANT. |
94 Handle<Object> values_[MAX_PROPERTIES]; | 95 Handle<Object> values_[MAX_PROPERTIES]; |
95 // Setter for ACCESSOR_CONSTANT. | 96 // Setter for ACCESSOR_CONSTANT. |
96 Handle<Object> setter_values_[MAX_PROPERTIES]; | 97 Handle<Object> setter_values_[MAX_PROPERTIES]; |
97 int number_of_properties_; | 98 int number_of_properties_; |
98 | 99 |
99 public: | 100 public: |
| 101 explicit Expectations(Isolate* isolate, ElementsKind elements_kind) |
| 102 : isolate_(isolate), |
| 103 elements_kind_(elements_kind), |
| 104 number_of_properties_(0) {} |
| 105 |
100 explicit Expectations(Isolate* isolate) | 106 explicit Expectations(Isolate* isolate) |
101 : isolate_(isolate), number_of_properties_(0) {} | 107 : Expectations( |
| 108 isolate, |
| 109 isolate->object_function()->initial_map()->elements_kind()) {} |
102 | 110 |
103 void Init(int index, PropertyType type, PropertyAttributes attributes, | 111 void Init(int index, PropertyType type, PropertyAttributes attributes, |
104 Representation representation, Handle<Object> value) { | 112 Representation representation, Handle<Object> value) { |
105 CHECK(index < MAX_PROPERTIES); | 113 CHECK(index < MAX_PROPERTIES); |
106 types_[index] = type; | 114 types_[index] = type; |
107 attributes_[index] = attributes; | 115 attributes_[index] = attributes; |
108 representations_[index] = representation; | 116 representations_[index] = representation; |
109 values_[index] = value; | 117 values_[index] = value; |
110 } | 118 } |
111 | 119 |
(...skipping 24 matching lines...) Expand all Loading... |
136 case ACCESSOR: | 144 case ACCESSOR: |
137 os << "accessor"; | 145 os << "accessor"; |
138 break; | 146 break; |
139 } | 147 } |
140 os << ": " << representations_[i].Mnemonic(); | 148 os << ": " << representations_[i].Mnemonic(); |
141 os << ", attrs: " << attributes_[i] << ")\n"; | 149 os << ", attrs: " << attributes_[i] << ")\n"; |
142 } | 150 } |
143 os << "\n"; | 151 os << "\n"; |
144 } | 152 } |
145 | 153 |
| 154 void SetElementsKind(ElementsKind elements_kind) { |
| 155 elements_kind_ = elements_kind; |
| 156 } |
| 157 |
146 Handle<FieldType> GetFieldType(int index) { | 158 Handle<FieldType> GetFieldType(int index) { |
147 CHECK(index < MAX_PROPERTIES); | 159 CHECK(index < MAX_PROPERTIES); |
148 CHECK(types_[index] == DATA || types_[index] == ACCESSOR); | 160 CHECK(types_[index] == DATA || types_[index] == ACCESSOR); |
149 return Handle<FieldType>::cast(values_[index]); | 161 return Handle<FieldType>::cast(values_[index]); |
150 } | 162 } |
151 | 163 |
152 void SetDataField(int index, PropertyAttributes attrs, | 164 void SetDataField(int index, PropertyAttributes attrs, |
153 Representation representation, Handle<FieldType> value) { | 165 Representation representation, Handle<FieldType> value) { |
154 Init(index, DATA, attrs, representation, value); | 166 Init(index, DATA, attrs, representation, value); |
155 } | 167 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 if (!value->IsAccessorPair()) return false; | 257 if (!value->IsAccessorPair()) return false; |
246 AccessorPair* pair = AccessorPair::cast(value); | 258 AccessorPair* pair = AccessorPair::cast(value); |
247 return pair->Equals(expected_value, *setter_values_[descriptor]); | 259 return pair->Equals(expected_value, *setter_values_[descriptor]); |
248 } | 260 } |
249 } | 261 } |
250 UNREACHABLE(); | 262 UNREACHABLE(); |
251 return false; | 263 return false; |
252 } | 264 } |
253 | 265 |
254 bool Check(Map* map, int expected_nof) const { | 266 bool Check(Map* map, int expected_nof) const { |
| 267 CHECK_EQ(elements_kind_, map->elements_kind()); |
255 CHECK(number_of_properties_ <= MAX_PROPERTIES); | 268 CHECK(number_of_properties_ <= MAX_PROPERTIES); |
256 CHECK_EQ(expected_nof, map->NumberOfOwnDescriptors()); | 269 CHECK_EQ(expected_nof, map->NumberOfOwnDescriptors()); |
257 CHECK(!map->is_dictionary_map()); | 270 CHECK(!map->is_dictionary_map()); |
258 | 271 |
259 DescriptorArray* descriptors = map->instance_descriptors(); | 272 DescriptorArray* descriptors = map->instance_descriptors(); |
260 CHECK(expected_nof <= number_of_properties_); | 273 CHECK(expected_nof <= number_of_properties_); |
261 for (int i = 0; i < expected_nof; i++) { | 274 for (int i = 0; i < expected_nof; i++) { |
262 if (!Check(descriptors, i)) { | 275 if (!Check(descriptors, i)) { |
263 Print(); | 276 Print(); |
264 #ifdef OBJECT_PRINT | 277 #ifdef OBJECT_PRINT |
265 descriptors->Print(); | 278 descriptors->Print(); |
266 #endif | 279 #endif |
267 Check(descriptors, i); | 280 Check(descriptors, i); |
268 return false; | 281 return false; |
269 } | 282 } |
270 } | 283 } |
271 return true; | 284 return true; |
272 } | 285 } |
273 | 286 |
274 bool Check(Map* map) const { return Check(map, number_of_properties_); } | 287 bool Check(Map* map) const { return Check(map, number_of_properties_); } |
275 | 288 |
276 | 289 |
277 // | 290 // |
278 // Helper methods for initializing expectations and adding properties to | 291 // Helper methods for initializing expectations and adding properties to |
279 // given |map|. | 292 // given |map|. |
280 // | 293 // |
281 | 294 |
| 295 Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind elements_kind) { |
| 296 elements_kind_ = elements_kind; |
| 297 map = Map::AsElementsKind(map, elements_kind); |
| 298 CHECK_EQ(elements_kind_, map->elements_kind()); |
| 299 return map; |
| 300 } |
| 301 |
282 Handle<Map> AddDataField(Handle<Map> map, PropertyAttributes attributes, | 302 Handle<Map> AddDataField(Handle<Map> map, PropertyAttributes attributes, |
283 Representation representation, | 303 Representation representation, |
284 Handle<FieldType> heap_type) { | 304 Handle<FieldType> heap_type) { |
285 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); | 305 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); |
286 int property_index = number_of_properties_++; | 306 int property_index = number_of_properties_++; |
287 SetDataField(property_index, attributes, representation, heap_type); | 307 SetDataField(property_index, attributes, representation, heap_type); |
288 | 308 |
289 Handle<String> name = MakeName("prop", property_index); | 309 Handle<String> name = MakeName("prop", property_index); |
290 return Map::CopyWithField(map, name, heap_type, attributes, representation, | 310 return Map::CopyWithField(map, name, heap_type, attributes, representation, |
291 INSERT_TRANSITION) | 311 INSERT_TRANSITION) |
(...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1518 }; | 1538 }; |
1519 | 1539 |
1520 TestConfig config; | 1540 TestConfig config; |
1521 // These are completely separate branches in transition tree. | 1541 // These are completely separate branches in transition tree. |
1522 CheckUnrelated checker; | 1542 CheckUnrelated checker; |
1523 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); | 1543 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); |
1524 } | 1544 } |
1525 | 1545 |
1526 | 1546 |
1527 //////////////////////////////////////////////////////////////////////////////// | 1547 //////////////////////////////////////////////////////////////////////////////// |
| 1548 // A set of tests for elements kind reconfiguration case. |
| 1549 // |
| 1550 |
| 1551 // This test ensures that representation/field type generalization is correctly |
| 1552 // propagated from one branch of transition tree (|map2) to another (|map|). |
| 1553 // |
| 1554 // + - p0 - p1 - p2A - p3 - p4: |map| |
| 1555 // | |
| 1556 // ek |
| 1557 // | |
| 1558 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
| 1559 // |
| 1560 // where "p2A" and "p2B" differ only in the representation/field type. |
| 1561 // |
| 1562 static void TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1563 Representation from_representation, Handle<FieldType> from_type, |
| 1564 Representation to_representation, Handle<FieldType> to_type, |
| 1565 Representation expected_representation, Handle<FieldType> expected_type) { |
| 1566 Isolate* isolate = CcTest::i_isolate(); |
| 1567 |
| 1568 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
| 1569 |
| 1570 // Create a map, add required properties to it and initialize expectations. |
| 1571 Handle<Map> initial_map = Map::Create(isolate, 0); |
| 1572 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
| 1573 |
| 1574 Handle<Map> map = initial_map; |
| 1575 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
| 1576 for (int i = 0; i < kPropCount; i++) { |
| 1577 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
| 1578 } |
| 1579 CHECK(!map->is_deprecated()); |
| 1580 CHECK(map->is_stable()); |
| 1581 CHECK(expectations.Check(*map)); |
| 1582 |
| 1583 // Create another branch in transition tree (property at index |kDiffProp| |
| 1584 // has different representatio/field type), initialize expectations. |
| 1585 const int kDiffProp = kPropCount / 2; |
| 1586 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
| 1587 |
| 1588 Handle<Map> map2 = initial_map; |
| 1589 for (int i = 0; i < kPropCount; i++) { |
| 1590 if (i == kDiffProp) { |
| 1591 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); |
| 1592 } else { |
| 1593 map2 = expectations2.AddDataField(map2, NONE, from_representation, |
| 1594 from_type); |
| 1595 } |
| 1596 } |
| 1597 CHECK(!map2->is_deprecated()); |
| 1598 CHECK(map2->is_stable()); |
| 1599 CHECK(expectations2.Check(*map2)); |
| 1600 |
| 1601 Zone zone; |
| 1602 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
| 1603 CompilationInfo info("testing", isolate, &zone); |
| 1604 CHECK(!info.dependencies()->HasAborted()); |
| 1605 info.dependencies()->AssumeFieldType(field_owner); |
| 1606 |
| 1607 // Reconfigure elements kinds of |map2|, which should generalize |
| 1608 // representations in |map|. |
| 1609 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
| 1610 |
| 1611 // |map2| should be left unchanged but marked unstable. |
| 1612 CHECK(!map2->is_stable()); |
| 1613 CHECK(!map2->is_deprecated()); |
| 1614 CHECK_NE(*map2, *new_map); |
| 1615 CHECK(expectations2.Check(*map2)); |
| 1616 |
| 1617 // |map| should be deprecated and |new_map| should match new expectations. |
| 1618 expectations.SetDataField(kDiffProp, expected_representation, expected_type); |
| 1619 |
| 1620 CHECK(map->is_deprecated()); |
| 1621 CHECK(!info.dependencies()->HasAborted()); |
| 1622 info.dependencies()->Rollback(); // Properly cleanup compilation info. |
| 1623 CHECK_NE(*map, *new_map); |
| 1624 |
| 1625 CHECK(!new_map->is_deprecated()); |
| 1626 CHECK(expectations.Check(*new_map)); |
| 1627 |
| 1628 // Update deprecated |map|, it should become |new_map|. |
| 1629 Handle<Map> updated_map = Map::Update(map); |
| 1630 CHECK_EQ(*new_map, *updated_map); |
| 1631 |
| 1632 // Ensure Map::FindElementsKindTransitionedMap() is able to find the |
| 1633 // transitioned map. |
| 1634 { |
| 1635 MapHandleList map_list; |
| 1636 map_list.Add(updated_map); |
| 1637 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); |
| 1638 CHECK_EQ(*updated_map, transitioned_map); |
| 1639 } |
| 1640 } |
| 1641 |
| 1642 // This test ensures that trivial representation/field type generalization |
| 1643 // (from HeapObject to HeapObject) is correctly propagated from one branch of |
| 1644 // transition tree (|map2|) to another (|map|). |
| 1645 // |
| 1646 // + - p0 - p1 - p2A - p3 - p4: |map| |
| 1647 // | |
| 1648 // ek |
| 1649 // | |
| 1650 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
| 1651 // |
| 1652 // where "p2A" and "p2B" differ only in the representation/field type. |
| 1653 // |
| 1654 static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1655 Representation from_representation, Handle<FieldType> from_type, |
| 1656 Representation to_representation, Handle<FieldType> to_type, |
| 1657 Representation expected_representation, Handle<FieldType> expected_type, |
| 1658 bool expected_field_type_dependency = true) { |
| 1659 Isolate* isolate = CcTest::i_isolate(); |
| 1660 |
| 1661 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
| 1662 |
| 1663 // Create a map, add required properties to it and initialize expectations. |
| 1664 Handle<Map> initial_map = Map::Create(isolate, 0); |
| 1665 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
| 1666 |
| 1667 Handle<Map> map = initial_map; |
| 1668 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
| 1669 for (int i = 0; i < kPropCount; i++) { |
| 1670 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
| 1671 } |
| 1672 CHECK(!map->is_deprecated()); |
| 1673 CHECK(map->is_stable()); |
| 1674 CHECK(expectations.Check(*map)); |
| 1675 |
| 1676 // Create another branch in transition tree (property at index |kDiffProp| |
| 1677 // has different attributes), initialize expectations. |
| 1678 const int kDiffProp = kPropCount / 2; |
| 1679 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
| 1680 |
| 1681 Handle<Map> map2 = initial_map; |
| 1682 for (int i = 0; i < kPropCount; i++) { |
| 1683 if (i == kDiffProp) { |
| 1684 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); |
| 1685 } else { |
| 1686 map2 = expectations2.AddDataField(map2, NONE, from_representation, |
| 1687 from_type); |
| 1688 } |
| 1689 } |
| 1690 CHECK(!map2->is_deprecated()); |
| 1691 CHECK(map2->is_stable()); |
| 1692 CHECK(expectations2.Check(*map2)); |
| 1693 |
| 1694 Zone zone; |
| 1695 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
| 1696 CompilationInfo info("testing", isolate, &zone); |
| 1697 CHECK(!info.dependencies()->HasAborted()); |
| 1698 info.dependencies()->AssumeFieldType(field_owner); |
| 1699 |
| 1700 // Reconfigure elements kinds of |map2|, which should generalize |
| 1701 // representations in |map|. |
| 1702 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
| 1703 |
| 1704 // |map2| should be left unchanged but marked unstable. |
| 1705 CHECK(!map2->is_stable()); |
| 1706 CHECK(!map2->is_deprecated()); |
| 1707 CHECK_NE(*map2, *new_map); |
| 1708 CHECK(expectations2.Check(*map2)); |
| 1709 |
| 1710 // In trivial case |map| should be returned as a result of the elements |
| 1711 // kind reconfiguration, respective field types should be generalized and |
| 1712 // respective code dependencies should be invalidated. |map| should be NOT |
| 1713 // deprecated and it should match new expectations. |
| 1714 expectations.SetDataField(kDiffProp, expected_representation, expected_type); |
| 1715 CHECK(!map->is_deprecated()); |
| 1716 CHECK_EQ(*map, *new_map); |
| 1717 CHECK_EQ(expected_field_type_dependency, info.dependencies()->HasAborted()); |
| 1718 info.dependencies()->Rollback(); // Properly cleanup compilation info. |
| 1719 |
| 1720 CHECK(!new_map->is_deprecated()); |
| 1721 CHECK(expectations.Check(*new_map)); |
| 1722 |
| 1723 Handle<Map> updated_map = Map::Update(map); |
| 1724 CHECK_EQ(*new_map, *updated_map); |
| 1725 |
| 1726 // Ensure Map::FindElementsKindTransitionedMap() is able to find the |
| 1727 // transitioned map. |
| 1728 { |
| 1729 MapHandleList map_list; |
| 1730 map_list.Add(updated_map); |
| 1731 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); |
| 1732 CHECK_EQ(*updated_map, transitioned_map); |
| 1733 } |
| 1734 } |
| 1735 |
| 1736 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToDouble) { |
| 1737 CcTest::InitializeVM(); |
| 1738 v8::HandleScope scope(CcTest::isolate()); |
| 1739 Isolate* isolate = CcTest::i_isolate(); |
| 1740 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1741 |
| 1742 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1743 Representation::Smi(), any_type, Representation::Double(), any_type, |
| 1744 Representation::Double(), any_type); |
| 1745 } |
| 1746 |
| 1747 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) { |
| 1748 CcTest::InitializeVM(); |
| 1749 v8::HandleScope scope(CcTest::isolate()); |
| 1750 Isolate* isolate = CcTest::i_isolate(); |
| 1751 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1752 Handle<FieldType> value_type = |
| 1753 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1754 |
| 1755 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1756 Representation::Smi(), any_type, Representation::HeapObject(), value_type, |
| 1757 Representation::Tagged(), any_type); |
| 1758 } |
| 1759 |
| 1760 TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) { |
| 1761 CcTest::InitializeVM(); |
| 1762 v8::HandleScope scope(CcTest::isolate()); |
| 1763 Isolate* isolate = CcTest::i_isolate(); |
| 1764 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1765 Handle<FieldType> value_type = |
| 1766 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1767 |
| 1768 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1769 Representation::Double(), any_type, Representation::HeapObject(), |
| 1770 value_type, Representation::Tagged(), any_type); |
| 1771 } |
| 1772 |
| 1773 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) { |
| 1774 CcTest::InitializeVM(); |
| 1775 v8::HandleScope scope(CcTest::isolate()); |
| 1776 Isolate* isolate = CcTest::i_isolate(); |
| 1777 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1778 |
| 1779 Handle<FieldType> current_type = |
| 1780 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1781 |
| 1782 Handle<FieldType> new_type = |
| 1783 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1784 |
| 1785 Handle<FieldType> expected_type = any_type; |
| 1786 |
| 1787 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1788 Representation::HeapObject(), current_type, Representation::HeapObject(), |
| 1789 new_type, Representation::HeapObject(), expected_type); |
| 1790 current_type = expected_type; |
| 1791 |
| 1792 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1793 |
| 1794 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1795 Representation::HeapObject(), any_type, Representation::HeapObject(), |
| 1796 new_type, Representation::HeapObject(), any_type, false); |
| 1797 } |
| 1798 |
| 1799 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) { |
| 1800 CcTest::InitializeVM(); |
| 1801 v8::HandleScope scope(CcTest::isolate()); |
| 1802 Isolate* isolate = CcTest::i_isolate(); |
| 1803 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1804 Handle<FieldType> value_type = |
| 1805 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1806 |
| 1807 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1808 Representation::HeapObject(), value_type, Representation::Smi(), any_type, |
| 1809 Representation::Tagged(), any_type); |
| 1810 } |
| 1811 |
| 1812 //////////////////////////////////////////////////////////////////////////////// |
1528 // A set of tests checking split map deprecation. | 1813 // A set of tests checking split map deprecation. |
1529 // | 1814 // |
1530 | 1815 |
1531 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { | 1816 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { |
1532 CcTest::InitializeVM(); | 1817 CcTest::InitializeVM(); |
1533 v8::HandleScope scope(CcTest::isolate()); | 1818 v8::HandleScope scope(CcTest::isolate()); |
1534 Isolate* isolate = CcTest::i_isolate(); | 1819 Isolate* isolate = CcTest::i_isolate(); |
1535 Handle<FieldType> any_type = FieldType::Any(isolate); | 1820 Handle<FieldType> any_type = FieldType::Any(isolate); |
1536 | 1821 |
1537 Expectations expectations(isolate); | 1822 Expectations expectations(isolate); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 // Create a map, add required properties to it and initialize expectations. | 1918 // Create a map, add required properties to it and initialize expectations. |
1634 Handle<Map> initial_map = Map::Create(isolate, 0); | 1919 Handle<Map> initial_map = Map::Create(isolate, 0); |
1635 Handle<Map> map = initial_map; | 1920 Handle<Map> map = initial_map; |
1636 for (int i = 0; i < kPropCount; i++) { | 1921 for (int i = 0; i < kPropCount; i++) { |
1637 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 1922 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
1638 } | 1923 } |
1639 CHECK(!map->is_deprecated()); | 1924 CHECK(!map->is_deprecated()); |
1640 CHECK(map->is_stable()); | 1925 CHECK(map->is_stable()); |
1641 CHECK(expectations.Check(*map)); | 1926 CHECK(expectations.Check(*map)); |
1642 | 1927 |
| 1928 Expectations expectations2 = expectations; |
| 1929 |
1643 // Apply some special transition to |map|. | 1930 // Apply some special transition to |map|. |
1644 CHECK(map->owns_descriptors()); | 1931 CHECK(map->owns_descriptors()); |
1645 Handle<Map> map2 = config.Transition(map); | 1932 Handle<Map> map2 = config.Transition(map, expectations2); |
1646 | 1933 |
1647 // |map| should still match expectations. | 1934 // |map| should still match expectations. |
1648 CHECK(!map->is_deprecated()); | 1935 CHECK(!map->is_deprecated()); |
1649 CHECK(expectations.Check(*map)); | 1936 CHECK(expectations.Check(*map)); |
1650 | 1937 |
1651 Expectations expectations2 = expectations; | |
1652 if (config.generalizes_representations()) { | 1938 if (config.generalizes_representations()) { |
1653 for (int i = 0; i < kPropCount; i++) { | 1939 for (int i = 0; i < kPropCount; i++) { |
1654 expectations2.GeneralizeRepresentation(i); | 1940 expectations2.GeneralizeRepresentation(i); |
1655 } | 1941 } |
1656 } | 1942 } |
1657 | 1943 |
1658 CHECK(!map2->is_deprecated()); | 1944 CHECK(!map2->is_deprecated()); |
1659 CHECK(map2->is_stable()); | 1945 CHECK(map2->is_stable()); |
1660 CHECK(expectations2.Check(*map2)); | 1946 CHECK(expectations2.Check(*map2)); |
1661 | 1947 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1713 | 1999 |
1714 TEST(ElementsKindTransitionFromMapOwningDescriptor) { | 2000 TEST(ElementsKindTransitionFromMapOwningDescriptor) { |
1715 CcTest::InitializeVM(); | 2001 CcTest::InitializeVM(); |
1716 v8::HandleScope scope(CcTest::isolate()); | 2002 v8::HandleScope scope(CcTest::isolate()); |
1717 Isolate* isolate = CcTest::i_isolate(); | 2003 Isolate* isolate = CcTest::i_isolate(); |
1718 Handle<FieldType> any_type = FieldType::Any(isolate); | 2004 Handle<FieldType> any_type = FieldType::Any(isolate); |
1719 Handle<FieldType> value_type = | 2005 Handle<FieldType> value_type = |
1720 FieldType::Class(Map::Create(isolate, 0), isolate); | 2006 FieldType::Class(Map::Create(isolate, 0), isolate); |
1721 | 2007 |
1722 struct TestConfig { | 2008 struct TestConfig { |
1723 Handle<Map> Transition(Handle<Map> map) { | 2009 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1724 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 2010 Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol()); |
1725 INSERT_TRANSITION); | 2011 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
| 2012 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
| 2013 "CopyForPreventExtensions"); |
1726 } | 2014 } |
1727 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2015 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
1728 bool generalizes_representations() const { return false; } | 2016 bool generalizes_representations() const { return false; } |
1729 bool is_non_equevalent_transition() const { return false; } | 2017 bool is_non_equevalent_transition() const { return true; } |
1730 }; | 2018 }; |
1731 TestConfig config; | 2019 TestConfig config; |
1732 TestGeneralizeRepresentationWithSpecialTransition( | 2020 TestGeneralizeRepresentationWithSpecialTransition( |
1733 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2021 config, Representation::Smi(), any_type, Representation::HeapObject(), |
1734 value_type, Representation::Tagged(), any_type); | 2022 value_type, Representation::Tagged(), any_type); |
1735 } | 2023 } |
1736 | 2024 |
1737 | 2025 |
1738 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { | 2026 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { |
1739 CcTest::InitializeVM(); | 2027 CcTest::InitializeVM(); |
1740 v8::HandleScope scope(CcTest::isolate()); | 2028 v8::HandleScope scope(CcTest::isolate()); |
1741 Isolate* isolate = CcTest::i_isolate(); | 2029 Isolate* isolate = CcTest::i_isolate(); |
1742 Handle<FieldType> any_type = FieldType::Any(isolate); | 2030 Handle<FieldType> any_type = FieldType::Any(isolate); |
1743 Handle<FieldType> value_type = | 2031 Handle<FieldType> value_type = |
1744 FieldType::Class(Map::Create(isolate, 0), isolate); | 2032 FieldType::Class(Map::Create(isolate, 0), isolate); |
1745 | 2033 |
1746 struct TestConfig { | 2034 struct TestConfig { |
1747 Handle<Map> Transition(Handle<Map> map) { | 2035 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1748 Isolate* isolate = CcTest::i_isolate(); | 2036 Isolate* isolate = CcTest::i_isolate(); |
1749 Handle<FieldType> any_type = FieldType::Any(isolate); | 2037 Handle<FieldType> any_type = FieldType::Any(isolate); |
1750 | 2038 |
1751 // Add one more transition to |map| in order to prevent descriptors | 2039 // Add one more transition to |map| in order to prevent descriptors |
1752 // ownership. | 2040 // ownership. |
1753 CHECK(map->owns_descriptors()); | 2041 CHECK(map->owns_descriptors()); |
1754 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2042 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
1755 Representation::Smi(), INSERT_TRANSITION) | 2043 Representation::Smi(), INSERT_TRANSITION) |
1756 .ToHandleChecked(); | 2044 .ToHandleChecked(); |
1757 CHECK(!map->owns_descriptors()); | 2045 CHECK(!map->owns_descriptors()); |
1758 | 2046 |
1759 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 2047 Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol()); |
1760 INSERT_TRANSITION); | 2048 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
| 2049 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
| 2050 "CopyForPreventExtensions"); |
1761 } | 2051 } |
1762 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2052 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
1763 bool generalizes_representations() const { return false; } | 2053 bool generalizes_representations() const { return false; } |
1764 bool is_non_equevalent_transition() const { return false; } | 2054 bool is_non_equevalent_transition() const { return true; } |
1765 }; | 2055 }; |
1766 TestConfig config; | 2056 TestConfig config; |
1767 TestGeneralizeRepresentationWithSpecialTransition( | 2057 TestGeneralizeRepresentationWithSpecialTransition( |
1768 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2058 config, Representation::Smi(), any_type, Representation::HeapObject(), |
1769 value_type, Representation::Tagged(), any_type); | 2059 value_type, Representation::Tagged(), any_type); |
1770 } | 2060 } |
1771 | 2061 |
1772 | 2062 |
1773 TEST(ForObservedTransitionFromMapOwningDescriptor) { | 2063 TEST(ForObservedTransitionFromMapOwningDescriptor) { |
1774 CcTest::InitializeVM(); | 2064 CcTest::InitializeVM(); |
1775 v8::HandleScope scope(CcTest::isolate()); | 2065 v8::HandleScope scope(CcTest::isolate()); |
1776 Isolate* isolate = CcTest::i_isolate(); | 2066 Isolate* isolate = CcTest::i_isolate(); |
1777 Handle<FieldType> any_type = FieldType::Any(isolate); | 2067 Handle<FieldType> any_type = FieldType::Any(isolate); |
1778 Handle<FieldType> value_type = | 2068 Handle<FieldType> value_type = |
1779 FieldType::Class(Map::Create(isolate, 0), isolate); | 2069 FieldType::Class(Map::Create(isolate, 0), isolate); |
1780 | 2070 |
1781 struct TestConfig { | 2071 struct TestConfig { |
1782 Handle<Map> Transition(Handle<Map> map) { | 2072 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1783 return Map::CopyForObserved(map); | 2073 return Map::CopyForObserved(map); |
1784 } | 2074 } |
1785 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2075 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
1786 bool generalizes_representations() const { return false; } | 2076 bool generalizes_representations() const { return false; } |
1787 bool is_non_equevalent_transition() const { return true; } | 2077 bool is_non_equevalent_transition() const { return true; } |
1788 }; | 2078 }; |
1789 TestConfig config; | 2079 TestConfig config; |
1790 TestGeneralizeRepresentationWithSpecialTransition( | 2080 TestGeneralizeRepresentationWithSpecialTransition( |
1791 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2081 config, Representation::Smi(), any_type, Representation::HeapObject(), |
1792 value_type, Representation::Tagged(), any_type); | 2082 value_type, Representation::Tagged(), any_type); |
1793 } | 2083 } |
1794 | 2084 |
1795 | 2085 |
1796 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { | 2086 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { |
1797 CcTest::InitializeVM(); | 2087 CcTest::InitializeVM(); |
1798 v8::HandleScope scope(CcTest::isolate()); | 2088 v8::HandleScope scope(CcTest::isolate()); |
1799 Isolate* isolate = CcTest::i_isolate(); | 2089 Isolate* isolate = CcTest::i_isolate(); |
1800 Handle<FieldType> any_type = FieldType::Any(isolate); | 2090 Handle<FieldType> any_type = FieldType::Any(isolate); |
1801 Handle<FieldType> value_type = | 2091 Handle<FieldType> value_type = |
1802 FieldType::Class(Map::Create(isolate, 0), isolate); | 2092 FieldType::Class(Map::Create(isolate, 0), isolate); |
1803 | 2093 |
1804 struct TestConfig { | 2094 struct TestConfig { |
1805 Handle<Map> Transition(Handle<Map> map) { | 2095 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1806 Isolate* isolate = CcTest::i_isolate(); | 2096 Isolate* isolate = CcTest::i_isolate(); |
1807 Handle<FieldType> any_type = FieldType::Any(isolate); | 2097 Handle<FieldType> any_type = FieldType::Any(isolate); |
1808 | 2098 |
1809 // Add one more transition to |map| in order to prevent descriptors | 2099 // Add one more transition to |map| in order to prevent descriptors |
1810 // ownership. | 2100 // ownership. |
1811 CHECK(map->owns_descriptors()); | 2101 CHECK(map->owns_descriptors()); |
1812 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2102 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
1813 Representation::Smi(), INSERT_TRANSITION) | 2103 Representation::Smi(), INSERT_TRANSITION) |
1814 .ToHandleChecked(); | 2104 .ToHandleChecked(); |
1815 CHECK(!map->owns_descriptors()); | 2105 CHECK(!map->owns_descriptors()); |
(...skipping 22 matching lines...) Expand all Loading... |
1838 | 2128 |
1839 struct TestConfig { | 2129 struct TestConfig { |
1840 Handle<JSObject> prototype_; | 2130 Handle<JSObject> prototype_; |
1841 | 2131 |
1842 TestConfig() { | 2132 TestConfig() { |
1843 Isolate* isolate = CcTest::i_isolate(); | 2133 Isolate* isolate = CcTest::i_isolate(); |
1844 Factory* factory = isolate->factory(); | 2134 Factory* factory = isolate->factory(); |
1845 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 2135 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
1846 } | 2136 } |
1847 | 2137 |
1848 Handle<Map> Transition(Handle<Map> map) { | 2138 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1849 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 2139 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
1850 } | 2140 } |
1851 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2141 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
1852 bool generalizes_representations() const { | 2142 bool generalizes_representations() const { |
1853 return !IS_PROTO_TRANS_ISSUE_FIXED; | 2143 return !IS_PROTO_TRANS_ISSUE_FIXED; |
1854 } | 2144 } |
1855 bool is_non_equevalent_transition() const { return true; } | 2145 bool is_non_equevalent_transition() const { return true; } |
1856 }; | 2146 }; |
1857 TestConfig config; | 2147 TestConfig config; |
1858 TestGeneralizeRepresentationWithSpecialTransition( | 2148 TestGeneralizeRepresentationWithSpecialTransition( |
(...skipping 13 matching lines...) Expand all Loading... |
1872 | 2162 |
1873 struct TestConfig { | 2163 struct TestConfig { |
1874 Handle<JSObject> prototype_; | 2164 Handle<JSObject> prototype_; |
1875 | 2165 |
1876 TestConfig() { | 2166 TestConfig() { |
1877 Isolate* isolate = CcTest::i_isolate(); | 2167 Isolate* isolate = CcTest::i_isolate(); |
1878 Factory* factory = isolate->factory(); | 2168 Factory* factory = isolate->factory(); |
1879 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 2169 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
1880 } | 2170 } |
1881 | 2171 |
1882 Handle<Map> Transition(Handle<Map> map) { | 2172 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1883 Isolate* isolate = CcTest::i_isolate(); | 2173 Isolate* isolate = CcTest::i_isolate(); |
1884 Handle<FieldType> any_type = FieldType::Any(isolate); | 2174 Handle<FieldType> any_type = FieldType::Any(isolate); |
1885 | 2175 |
1886 // Add one more transition to |map| in order to prevent descriptors | 2176 // Add one more transition to |map| in order to prevent descriptors |
1887 // ownership. | 2177 // ownership. |
1888 CHECK(map->owns_descriptors()); | 2178 CHECK(map->owns_descriptors()); |
1889 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2179 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
1890 Representation::Smi(), INSERT_TRANSITION) | 2180 Representation::Smi(), INSERT_TRANSITION) |
1891 .ToHandleChecked(); | 2181 .ToHandleChecked(); |
1892 CHECK(!map->owns_descriptors()); | 2182 CHECK(!map->owns_descriptors()); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2175 Handle<AccessorPair> pair = CreateAccessorPair(true, true); | 2465 Handle<AccessorPair> pair = CreateAccessorPair(true, true); |
2176 TransitionToAccessorConstantOperator transition_op(pair); | 2466 TransitionToAccessorConstantOperator transition_op(pair); |
2177 | 2467 |
2178 SameMapChecker checker; | 2468 SameMapChecker checker; |
2179 TestTransitionTo(transition_op, transition_op, checker); | 2469 TestTransitionTo(transition_op, transition_op, checker); |
2180 } | 2470 } |
2181 | 2471 |
2182 | 2472 |
2183 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. | 2473 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. |
2184 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) | 2474 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) |
OLD | NEW |