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 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 }; | 1535 }; |
1516 | 1536 |
1517 TestConfig config; | 1537 TestConfig config; |
1518 // These are completely separate branches in transition tree. | 1538 // These are completely separate branches in transition tree. |
1519 CheckUnrelated checker; | 1539 CheckUnrelated checker; |
1520 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); | 1540 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); |
1521 } | 1541 } |
1522 | 1542 |
1523 | 1543 |
1524 //////////////////////////////////////////////////////////////////////////////// | 1544 //////////////////////////////////////////////////////////////////////////////// |
| 1545 // A set of tests for elements kind reconfiguration case. |
| 1546 // |
| 1547 |
| 1548 // This test ensures that representation/field type generalization is correctly |
| 1549 // propagated from one branch of transition tree (|map2) to another (|map|). |
| 1550 // |
| 1551 // + - p0 - p1 - p2A - p3 - p4: |map| |
| 1552 // | |
| 1553 // ek |
| 1554 // | |
| 1555 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
| 1556 // |
| 1557 // where "p2A" and "p2B" differ only in the representation/field type. |
| 1558 // |
| 1559 static void TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1560 Representation from_representation, Handle<FieldType> from_type, |
| 1561 Representation to_representation, Handle<FieldType> to_type, |
| 1562 Representation expected_representation, Handle<FieldType> expected_type) { |
| 1563 Isolate* isolate = CcTest::i_isolate(); |
| 1564 |
| 1565 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
| 1566 |
| 1567 // Create a map, add required properties to it and initialize expectations. |
| 1568 Handle<Map> initial_map = Map::Create(isolate, 0); |
| 1569 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
| 1570 |
| 1571 Handle<Map> map = initial_map; |
| 1572 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
| 1573 for (int i = 0; i < kPropCount; i++) { |
| 1574 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
| 1575 } |
| 1576 CHECK(!map->is_deprecated()); |
| 1577 CHECK(map->is_stable()); |
| 1578 CHECK(expectations.Check(*map)); |
| 1579 |
| 1580 // Create another branch in transition tree (property at index |kDiffProp| |
| 1581 // has different representatio/field type), initialize expectations. |
| 1582 const int kDiffProp = kPropCount / 2; |
| 1583 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
| 1584 |
| 1585 Handle<Map> map2 = initial_map; |
| 1586 for (int i = 0; i < kPropCount; i++) { |
| 1587 if (i == kDiffProp) { |
| 1588 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); |
| 1589 } else { |
| 1590 map2 = expectations2.AddDataField(map2, NONE, from_representation, |
| 1591 from_type); |
| 1592 } |
| 1593 } |
| 1594 CHECK(!map2->is_deprecated()); |
| 1595 CHECK(map2->is_stable()); |
| 1596 CHECK(expectations2.Check(*map2)); |
| 1597 |
| 1598 Zone zone(isolate->allocator()); |
| 1599 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
| 1600 CompilationInfo info(ArrayVector("testing"), isolate, &zone); |
| 1601 CHECK(!info.dependencies()->HasAborted()); |
| 1602 info.dependencies()->AssumeFieldType(field_owner); |
| 1603 |
| 1604 // Reconfigure elements kinds of |map2|, which should generalize |
| 1605 // representations in |map|. |
| 1606 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
| 1607 |
| 1608 // |map2| should be left unchanged but marked unstable. |
| 1609 CHECK(!map2->is_stable()); |
| 1610 CHECK(!map2->is_deprecated()); |
| 1611 CHECK_NE(*map2, *new_map); |
| 1612 CHECK(expectations2.Check(*map2)); |
| 1613 |
| 1614 // |map| should be deprecated and |new_map| should match new expectations. |
| 1615 expectations.SetDataField(kDiffProp, expected_representation, expected_type); |
| 1616 |
| 1617 CHECK(map->is_deprecated()); |
| 1618 CHECK(!info.dependencies()->HasAborted()); |
| 1619 info.dependencies()->Rollback(); // Properly cleanup compilation info. |
| 1620 CHECK_NE(*map, *new_map); |
| 1621 |
| 1622 CHECK(!new_map->is_deprecated()); |
| 1623 CHECK(expectations.Check(*new_map)); |
| 1624 |
| 1625 // Update deprecated |map|, it should become |new_map|. |
| 1626 Handle<Map> updated_map = Map::Update(map); |
| 1627 CHECK_EQ(*new_map, *updated_map); |
| 1628 |
| 1629 // Ensure Map::FindElementsKindTransitionedMap() is able to find the |
| 1630 // transitioned map. |
| 1631 { |
| 1632 MapHandleList map_list; |
| 1633 map_list.Add(updated_map); |
| 1634 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); |
| 1635 CHECK_EQ(*updated_map, transitioned_map); |
| 1636 } |
| 1637 } |
| 1638 |
| 1639 // This test ensures that trivial representation/field type generalization |
| 1640 // (from HeapObject to HeapObject) is correctly propagated from one branch of |
| 1641 // transition tree (|map2|) to another (|map|). |
| 1642 // |
| 1643 // + - p0 - p1 - p2A - p3 - p4: |map| |
| 1644 // | |
| 1645 // ek |
| 1646 // | |
| 1647 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
| 1648 // |
| 1649 // where "p2A" and "p2B" differ only in the representation/field type. |
| 1650 // |
| 1651 static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1652 Representation from_representation, Handle<FieldType> from_type, |
| 1653 Representation to_representation, Handle<FieldType> to_type, |
| 1654 Representation expected_representation, Handle<FieldType> expected_type, |
| 1655 bool expected_field_type_dependency = true) { |
| 1656 Isolate* isolate = CcTest::i_isolate(); |
| 1657 |
| 1658 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
| 1659 |
| 1660 // Create a map, add required properties to it and initialize expectations. |
| 1661 Handle<Map> initial_map = Map::Create(isolate, 0); |
| 1662 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
| 1663 |
| 1664 Handle<Map> map = initial_map; |
| 1665 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
| 1666 for (int i = 0; i < kPropCount; i++) { |
| 1667 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
| 1668 } |
| 1669 CHECK(!map->is_deprecated()); |
| 1670 CHECK(map->is_stable()); |
| 1671 CHECK(expectations.Check(*map)); |
| 1672 |
| 1673 // Create another branch in transition tree (property at index |kDiffProp| |
| 1674 // has different attributes), initialize expectations. |
| 1675 const int kDiffProp = kPropCount / 2; |
| 1676 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
| 1677 |
| 1678 Handle<Map> map2 = initial_map; |
| 1679 for (int i = 0; i < kPropCount; i++) { |
| 1680 if (i == kDiffProp) { |
| 1681 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); |
| 1682 } else { |
| 1683 map2 = expectations2.AddDataField(map2, NONE, from_representation, |
| 1684 from_type); |
| 1685 } |
| 1686 } |
| 1687 CHECK(!map2->is_deprecated()); |
| 1688 CHECK(map2->is_stable()); |
| 1689 CHECK(expectations2.Check(*map2)); |
| 1690 |
| 1691 Zone zone(isolate->allocator()); |
| 1692 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
| 1693 CompilationInfo info(ArrayVector("testing"), isolate, &zone); |
| 1694 CHECK(!info.dependencies()->HasAborted()); |
| 1695 info.dependencies()->AssumeFieldType(field_owner); |
| 1696 |
| 1697 // Reconfigure elements kinds of |map2|, which should generalize |
| 1698 // representations in |map|. |
| 1699 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
| 1700 |
| 1701 // |map2| should be left unchanged but marked unstable. |
| 1702 CHECK(!map2->is_stable()); |
| 1703 CHECK(!map2->is_deprecated()); |
| 1704 CHECK_NE(*map2, *new_map); |
| 1705 CHECK(expectations2.Check(*map2)); |
| 1706 |
| 1707 // In trivial case |map| should be returned as a result of the elements |
| 1708 // kind reconfiguration, respective field types should be generalized and |
| 1709 // respective code dependencies should be invalidated. |map| should be NOT |
| 1710 // deprecated and it should match new expectations. |
| 1711 expectations.SetDataField(kDiffProp, expected_representation, expected_type); |
| 1712 CHECK(!map->is_deprecated()); |
| 1713 CHECK_EQ(*map, *new_map); |
| 1714 CHECK_EQ(expected_field_type_dependency, info.dependencies()->HasAborted()); |
| 1715 info.dependencies()->Rollback(); // Properly cleanup compilation info. |
| 1716 |
| 1717 CHECK(!new_map->is_deprecated()); |
| 1718 CHECK(expectations.Check(*new_map)); |
| 1719 |
| 1720 Handle<Map> updated_map = Map::Update(map); |
| 1721 CHECK_EQ(*new_map, *updated_map); |
| 1722 |
| 1723 // Ensure Map::FindElementsKindTransitionedMap() is able to find the |
| 1724 // transitioned map. |
| 1725 { |
| 1726 MapHandleList map_list; |
| 1727 map_list.Add(updated_map); |
| 1728 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); |
| 1729 CHECK_EQ(*updated_map, transitioned_map); |
| 1730 } |
| 1731 } |
| 1732 |
| 1733 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToDouble) { |
| 1734 CcTest::InitializeVM(); |
| 1735 v8::HandleScope scope(CcTest::isolate()); |
| 1736 Isolate* isolate = CcTest::i_isolate(); |
| 1737 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1738 |
| 1739 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1740 Representation::Smi(), any_type, Representation::Double(), any_type, |
| 1741 Representation::Double(), any_type); |
| 1742 } |
| 1743 |
| 1744 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) { |
| 1745 CcTest::InitializeVM(); |
| 1746 v8::HandleScope scope(CcTest::isolate()); |
| 1747 Isolate* isolate = CcTest::i_isolate(); |
| 1748 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1749 Handle<FieldType> value_type = |
| 1750 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1751 |
| 1752 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1753 Representation::Smi(), any_type, Representation::HeapObject(), value_type, |
| 1754 Representation::Tagged(), any_type); |
| 1755 } |
| 1756 |
| 1757 TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) { |
| 1758 CcTest::InitializeVM(); |
| 1759 v8::HandleScope scope(CcTest::isolate()); |
| 1760 Isolate* isolate = CcTest::i_isolate(); |
| 1761 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1762 Handle<FieldType> value_type = |
| 1763 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1764 |
| 1765 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1766 Representation::Double(), any_type, Representation::HeapObject(), |
| 1767 value_type, Representation::Tagged(), any_type); |
| 1768 } |
| 1769 |
| 1770 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) { |
| 1771 CcTest::InitializeVM(); |
| 1772 v8::HandleScope scope(CcTest::isolate()); |
| 1773 Isolate* isolate = CcTest::i_isolate(); |
| 1774 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1775 |
| 1776 Handle<FieldType> current_type = |
| 1777 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1778 |
| 1779 Handle<FieldType> new_type = |
| 1780 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1781 |
| 1782 Handle<FieldType> expected_type = any_type; |
| 1783 |
| 1784 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1785 Representation::HeapObject(), current_type, Representation::HeapObject(), |
| 1786 new_type, Representation::HeapObject(), expected_type); |
| 1787 current_type = expected_type; |
| 1788 |
| 1789 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1790 |
| 1791 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1792 Representation::HeapObject(), any_type, Representation::HeapObject(), |
| 1793 new_type, Representation::HeapObject(), any_type, false); |
| 1794 } |
| 1795 |
| 1796 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) { |
| 1797 CcTest::InitializeVM(); |
| 1798 v8::HandleScope scope(CcTest::isolate()); |
| 1799 Isolate* isolate = CcTest::i_isolate(); |
| 1800 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1801 Handle<FieldType> value_type = |
| 1802 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1803 |
| 1804 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1805 Representation::HeapObject(), value_type, Representation::Smi(), any_type, |
| 1806 Representation::Tagged(), any_type); |
| 1807 } |
| 1808 |
| 1809 //////////////////////////////////////////////////////////////////////////////// |
1525 // A set of tests checking split map deprecation. | 1810 // A set of tests checking split map deprecation. |
1526 // | 1811 // |
1527 | 1812 |
1528 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { | 1813 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { |
1529 CcTest::InitializeVM(); | 1814 CcTest::InitializeVM(); |
1530 v8::HandleScope scope(CcTest::isolate()); | 1815 v8::HandleScope scope(CcTest::isolate()); |
1531 Isolate* isolate = CcTest::i_isolate(); | 1816 Isolate* isolate = CcTest::i_isolate(); |
1532 Handle<FieldType> any_type = FieldType::Any(isolate); | 1817 Handle<FieldType> any_type = FieldType::Any(isolate); |
1533 | 1818 |
1534 Expectations expectations(isolate); | 1819 Expectations expectations(isolate); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 // Create a map, add required properties to it and initialize expectations. | 1915 // Create a map, add required properties to it and initialize expectations. |
1631 Handle<Map> initial_map = Map::Create(isolate, 0); | 1916 Handle<Map> initial_map = Map::Create(isolate, 0); |
1632 Handle<Map> map = initial_map; | 1917 Handle<Map> map = initial_map; |
1633 for (int i = 0; i < kPropCount; i++) { | 1918 for (int i = 0; i < kPropCount; i++) { |
1634 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 1919 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
1635 } | 1920 } |
1636 CHECK(!map->is_deprecated()); | 1921 CHECK(!map->is_deprecated()); |
1637 CHECK(map->is_stable()); | 1922 CHECK(map->is_stable()); |
1638 CHECK(expectations.Check(*map)); | 1923 CHECK(expectations.Check(*map)); |
1639 | 1924 |
| 1925 Expectations expectations2 = expectations; |
| 1926 |
1640 // Apply some special transition to |map|. | 1927 // Apply some special transition to |map|. |
1641 CHECK(map->owns_descriptors()); | 1928 CHECK(map->owns_descriptors()); |
1642 Handle<Map> map2 = config.Transition(map); | 1929 Handle<Map> map2 = config.Transition(map, expectations2); |
1643 | 1930 |
1644 // |map| should still match expectations. | 1931 // |map| should still match expectations. |
1645 CHECK(!map->is_deprecated()); | 1932 CHECK(!map->is_deprecated()); |
1646 CHECK(expectations.Check(*map)); | 1933 CHECK(expectations.Check(*map)); |
1647 | 1934 |
1648 Expectations expectations2 = expectations; | |
1649 if (config.generalizes_representations()) { | 1935 if (config.generalizes_representations()) { |
1650 for (int i = 0; i < kPropCount; i++) { | 1936 for (int i = 0; i < kPropCount; i++) { |
1651 expectations2.GeneralizeRepresentation(i); | 1937 expectations2.GeneralizeRepresentation(i); |
1652 } | 1938 } |
1653 } | 1939 } |
1654 | 1940 |
1655 CHECK(!map2->is_deprecated()); | 1941 CHECK(!map2->is_deprecated()); |
1656 CHECK(map2->is_stable()); | 1942 CHECK(map2->is_stable()); |
1657 CHECK(expectations2.Check(*map2)); | 1943 CHECK(expectations2.Check(*map2)); |
1658 | 1944 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 | 1996 |
1711 TEST(ElementsKindTransitionFromMapOwningDescriptor) { | 1997 TEST(ElementsKindTransitionFromMapOwningDescriptor) { |
1712 CcTest::InitializeVM(); | 1998 CcTest::InitializeVM(); |
1713 v8::HandleScope scope(CcTest::isolate()); | 1999 v8::HandleScope scope(CcTest::isolate()); |
1714 Isolate* isolate = CcTest::i_isolate(); | 2000 Isolate* isolate = CcTest::i_isolate(); |
1715 Handle<FieldType> any_type = FieldType::Any(isolate); | 2001 Handle<FieldType> any_type = FieldType::Any(isolate); |
1716 Handle<FieldType> value_type = | 2002 Handle<FieldType> value_type = |
1717 FieldType::Class(Map::Create(isolate, 0), isolate); | 2003 FieldType::Class(Map::Create(isolate, 0), isolate); |
1718 | 2004 |
1719 struct TestConfig { | 2005 struct TestConfig { |
1720 Handle<Map> Transition(Handle<Map> map) { | 2006 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1721 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 2007 Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol()); |
1722 INSERT_TRANSITION); | 2008 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
| 2009 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
| 2010 "CopyForPreventExtensions"); |
1723 } | 2011 } |
1724 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2012 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
1725 bool generalizes_representations() const { return false; } | 2013 bool generalizes_representations() const { return false; } |
1726 bool is_non_equevalent_transition() const { return false; } | 2014 bool is_non_equevalent_transition() const { return true; } |
1727 }; | 2015 }; |
1728 TestConfig config; | 2016 TestConfig config; |
1729 TestGeneralizeRepresentationWithSpecialTransition( | 2017 TestGeneralizeRepresentationWithSpecialTransition( |
1730 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2018 config, Representation::Smi(), any_type, Representation::HeapObject(), |
1731 value_type, Representation::Tagged(), any_type); | 2019 value_type, Representation::Tagged(), any_type); |
1732 } | 2020 } |
1733 | 2021 |
1734 | 2022 |
1735 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { | 2023 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { |
1736 CcTest::InitializeVM(); | 2024 CcTest::InitializeVM(); |
1737 v8::HandleScope scope(CcTest::isolate()); | 2025 v8::HandleScope scope(CcTest::isolate()); |
1738 Isolate* isolate = CcTest::i_isolate(); | 2026 Isolate* isolate = CcTest::i_isolate(); |
1739 Handle<FieldType> any_type = FieldType::Any(isolate); | 2027 Handle<FieldType> any_type = FieldType::Any(isolate); |
1740 Handle<FieldType> value_type = | 2028 Handle<FieldType> value_type = |
1741 FieldType::Class(Map::Create(isolate, 0), isolate); | 2029 FieldType::Class(Map::Create(isolate, 0), isolate); |
1742 | 2030 |
1743 struct TestConfig { | 2031 struct TestConfig { |
1744 Handle<Map> Transition(Handle<Map> map) { | 2032 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1745 Isolate* isolate = CcTest::i_isolate(); | 2033 Isolate* isolate = CcTest::i_isolate(); |
1746 Handle<FieldType> any_type = FieldType::Any(isolate); | 2034 Handle<FieldType> any_type = FieldType::Any(isolate); |
1747 | 2035 |
1748 // Add one more transition to |map| in order to prevent descriptors | 2036 // Add one more transition to |map| in order to prevent descriptors |
1749 // ownership. | 2037 // ownership. |
1750 CHECK(map->owns_descriptors()); | 2038 CHECK(map->owns_descriptors()); |
1751 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2039 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
1752 Representation::Smi(), INSERT_TRANSITION) | 2040 Representation::Smi(), INSERT_TRANSITION) |
1753 .ToHandleChecked(); | 2041 .ToHandleChecked(); |
1754 CHECK(!map->owns_descriptors()); | 2042 CHECK(!map->owns_descriptors()); |
1755 | 2043 |
1756 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 2044 Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol()); |
1757 INSERT_TRANSITION); | 2045 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
| 2046 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
| 2047 "CopyForPreventExtensions"); |
1758 } | 2048 } |
1759 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2049 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
1760 bool generalizes_representations() const { return false; } | 2050 bool generalizes_representations() const { return false; } |
1761 bool is_non_equevalent_transition() const { return false; } | 2051 bool is_non_equevalent_transition() const { return true; } |
1762 }; | 2052 }; |
1763 TestConfig config; | 2053 TestConfig config; |
1764 TestGeneralizeRepresentationWithSpecialTransition( | 2054 TestGeneralizeRepresentationWithSpecialTransition( |
1765 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2055 config, Representation::Smi(), any_type, Representation::HeapObject(), |
1766 value_type, Representation::Tagged(), any_type); | 2056 value_type, Representation::Tagged(), any_type); |
1767 } | 2057 } |
1768 | 2058 |
1769 | 2059 |
1770 TEST(PrototypeTransitionFromMapOwningDescriptor) { | 2060 TEST(PrototypeTransitionFromMapOwningDescriptor) { |
1771 CcTest::InitializeVM(); | 2061 CcTest::InitializeVM(); |
1772 v8::HandleScope scope(CcTest::isolate()); | 2062 v8::HandleScope scope(CcTest::isolate()); |
1773 Isolate* isolate = CcTest::i_isolate(); | 2063 Isolate* isolate = CcTest::i_isolate(); |
1774 | 2064 |
1775 Handle<FieldType> any_type = FieldType::Any(isolate); | 2065 Handle<FieldType> any_type = FieldType::Any(isolate); |
1776 Handle<FieldType> value_type = | 2066 Handle<FieldType> value_type = |
1777 FieldType::Class(Map::Create(isolate, 0), isolate); | 2067 FieldType::Class(Map::Create(isolate, 0), isolate); |
1778 | 2068 |
1779 struct TestConfig { | 2069 struct TestConfig { |
1780 Handle<JSObject> prototype_; | 2070 Handle<JSObject> prototype_; |
1781 | 2071 |
1782 TestConfig() { | 2072 TestConfig() { |
1783 Isolate* isolate = CcTest::i_isolate(); | 2073 Isolate* isolate = CcTest::i_isolate(); |
1784 Factory* factory = isolate->factory(); | 2074 Factory* factory = isolate->factory(); |
1785 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 2075 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
1786 } | 2076 } |
1787 | 2077 |
1788 Handle<Map> Transition(Handle<Map> map) { | 2078 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1789 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 2079 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
1790 } | 2080 } |
1791 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2081 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
1792 bool generalizes_representations() const { | 2082 bool generalizes_representations() const { |
1793 return !IS_PROTO_TRANS_ISSUE_FIXED; | 2083 return !IS_PROTO_TRANS_ISSUE_FIXED; |
1794 } | 2084 } |
1795 bool is_non_equevalent_transition() const { return true; } | 2085 bool is_non_equevalent_transition() const { return true; } |
1796 }; | 2086 }; |
1797 TestConfig config; | 2087 TestConfig config; |
1798 TestGeneralizeRepresentationWithSpecialTransition( | 2088 TestGeneralizeRepresentationWithSpecialTransition( |
(...skipping 13 matching lines...) Expand all Loading... |
1812 | 2102 |
1813 struct TestConfig { | 2103 struct TestConfig { |
1814 Handle<JSObject> prototype_; | 2104 Handle<JSObject> prototype_; |
1815 | 2105 |
1816 TestConfig() { | 2106 TestConfig() { |
1817 Isolate* isolate = CcTest::i_isolate(); | 2107 Isolate* isolate = CcTest::i_isolate(); |
1818 Factory* factory = isolate->factory(); | 2108 Factory* factory = isolate->factory(); |
1819 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 2109 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
1820 } | 2110 } |
1821 | 2111 |
1822 Handle<Map> Transition(Handle<Map> map) { | 2112 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
1823 Isolate* isolate = CcTest::i_isolate(); | 2113 Isolate* isolate = CcTest::i_isolate(); |
1824 Handle<FieldType> any_type = FieldType::Any(isolate); | 2114 Handle<FieldType> any_type = FieldType::Any(isolate); |
1825 | 2115 |
1826 // Add one more transition to |map| in order to prevent descriptors | 2116 // Add one more transition to |map| in order to prevent descriptors |
1827 // ownership. | 2117 // ownership. |
1828 CHECK(map->owns_descriptors()); | 2118 CHECK(map->owns_descriptors()); |
1829 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2119 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
1830 Representation::Smi(), INSERT_TRANSITION) | 2120 Representation::Smi(), INSERT_TRANSITION) |
1831 .ToHandleChecked(); | 2121 .ToHandleChecked(); |
1832 CHECK(!map->owns_descriptors()); | 2122 CHECK(!map->owns_descriptors()); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2115 Handle<AccessorPair> pair = CreateAccessorPair(true, true); | 2405 Handle<AccessorPair> pair = CreateAccessorPair(true, true); |
2116 TransitionToAccessorConstantOperator transition_op(pair); | 2406 TransitionToAccessorConstantOperator transition_op(pair); |
2117 | 2407 |
2118 SameMapChecker checker; | 2408 SameMapChecker checker; |
2119 TestTransitionTo(transition_op, transition_op, checker); | 2409 TestTransitionTo(transition_op, transition_op, checker); |
2120 } | 2410 } |
2121 | 2411 |
2122 | 2412 |
2123 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. | 2413 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. |
2124 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) | 2414 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) |
OLD | NEW |