| 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 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1522 }; | 1542 }; |
| 1523 | 1543 |
| 1524 TestConfig config; | 1544 TestConfig config; |
| 1525 // These are completely separate branches in transition tree. | 1545 // These are completely separate branches in transition tree. |
| 1526 CheckUnrelated checker; | 1546 CheckUnrelated checker; |
| 1527 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); | 1547 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); |
| 1528 } | 1548 } |
| 1529 | 1549 |
| 1530 | 1550 |
| 1531 //////////////////////////////////////////////////////////////////////////////// | 1551 //////////////////////////////////////////////////////////////////////////////// |
| 1552 // A set of tests for elements kind reconfiguration case. |
| 1553 // |
| 1554 |
| 1555 // This test ensures that representation/field type generalization is correctly |
| 1556 // propagated from one branch of transition tree (|map2) to another (|map|). |
| 1557 // |
| 1558 // + - p0 - p1 - p2A - p3 - p4: |map| |
| 1559 // | |
| 1560 // ek |
| 1561 // | |
| 1562 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
| 1563 // |
| 1564 // where "p2A" and "p2B" differ only in the representation/field type. |
| 1565 // |
| 1566 static void TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1567 Representation from_representation, Handle<FieldType> from_type, |
| 1568 Representation to_representation, Handle<FieldType> to_type, |
| 1569 Representation expected_representation, Handle<FieldType> expected_type) { |
| 1570 Isolate* isolate = CcTest::i_isolate(); |
| 1571 |
| 1572 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
| 1573 |
| 1574 // Create a map, add required properties to it and initialize expectations. |
| 1575 Handle<Map> initial_map = Map::Create(isolate, 0); |
| 1576 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
| 1577 |
| 1578 Handle<Map> map = initial_map; |
| 1579 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
| 1580 for (int i = 0; i < kPropCount; i++) { |
| 1581 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
| 1582 } |
| 1583 CHECK(!map->is_deprecated()); |
| 1584 CHECK(map->is_stable()); |
| 1585 CHECK(expectations.Check(*map)); |
| 1586 |
| 1587 // Create another branch in transition tree (property at index |kDiffProp| |
| 1588 // has different representatio/field type), initialize expectations. |
| 1589 const int kDiffProp = kPropCount / 2; |
| 1590 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
| 1591 |
| 1592 Handle<Map> map2 = initial_map; |
| 1593 for (int i = 0; i < kPropCount; i++) { |
| 1594 if (i == kDiffProp) { |
| 1595 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); |
| 1596 } else { |
| 1597 map2 = expectations2.AddDataField(map2, NONE, from_representation, |
| 1598 from_type); |
| 1599 } |
| 1600 } |
| 1601 CHECK(!map2->is_deprecated()); |
| 1602 CHECK(map2->is_stable()); |
| 1603 CHECK(expectations2.Check(*map2)); |
| 1604 |
| 1605 Zone zone(isolate->allocator()); |
| 1606 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
| 1607 CompilationInfo info("testing", isolate, &zone); |
| 1608 CHECK(!info.dependencies()->HasAborted()); |
| 1609 info.dependencies()->AssumeFieldType(field_owner); |
| 1610 |
| 1611 // Reconfigure elements kinds of |map2|, which should generalize |
| 1612 // representations in |map|. |
| 1613 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
| 1614 |
| 1615 // |map2| should be left unchanged but marked unstable. |
| 1616 CHECK(!map2->is_stable()); |
| 1617 CHECK(!map2->is_deprecated()); |
| 1618 CHECK_NE(*map2, *new_map); |
| 1619 CHECK(expectations2.Check(*map2)); |
| 1620 |
| 1621 // |map| should be deprecated and |new_map| should match new expectations. |
| 1622 expectations.SetDataField(kDiffProp, expected_representation, expected_type); |
| 1623 |
| 1624 CHECK(map->is_deprecated()); |
| 1625 CHECK(!info.dependencies()->HasAborted()); |
| 1626 info.dependencies()->Rollback(); // Properly cleanup compilation info. |
| 1627 CHECK_NE(*map, *new_map); |
| 1628 |
| 1629 CHECK(!new_map->is_deprecated()); |
| 1630 CHECK(expectations.Check(*new_map)); |
| 1631 |
| 1632 // Update deprecated |map|, it should become |new_map|. |
| 1633 Handle<Map> updated_map = Map::Update(map); |
| 1634 CHECK_EQ(*new_map, *updated_map); |
| 1635 |
| 1636 // Ensure Map::FindElementsKindTransitionedMap() is able to find the |
| 1637 // transitioned map. |
| 1638 { |
| 1639 MapHandleList map_list; |
| 1640 map_list.Add(updated_map); |
| 1641 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); |
| 1642 CHECK_EQ(*updated_map, transitioned_map); |
| 1643 } |
| 1644 } |
| 1645 |
| 1646 // This test ensures that trivial representation/field type generalization |
| 1647 // (from HeapObject to HeapObject) is correctly propagated from one branch of |
| 1648 // transition tree (|map2|) to another (|map|). |
| 1649 // |
| 1650 // + - p0 - p1 - p2A - p3 - p4: |map| |
| 1651 // | |
| 1652 // ek |
| 1653 // | |
| 1654 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
| 1655 // |
| 1656 // where "p2A" and "p2B" differ only in the representation/field type. |
| 1657 // |
| 1658 static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1659 Representation from_representation, Handle<FieldType> from_type, |
| 1660 Representation to_representation, Handle<FieldType> to_type, |
| 1661 Representation expected_representation, Handle<FieldType> expected_type, |
| 1662 bool expected_field_type_dependency = true) { |
| 1663 Isolate* isolate = CcTest::i_isolate(); |
| 1664 |
| 1665 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
| 1666 |
| 1667 // Create a map, add required properties to it and initialize expectations. |
| 1668 Handle<Map> initial_map = Map::Create(isolate, 0); |
| 1669 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
| 1670 |
| 1671 Handle<Map> map = initial_map; |
| 1672 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
| 1673 for (int i = 0; i < kPropCount; i++) { |
| 1674 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
| 1675 } |
| 1676 CHECK(!map->is_deprecated()); |
| 1677 CHECK(map->is_stable()); |
| 1678 CHECK(expectations.Check(*map)); |
| 1679 |
| 1680 // Create another branch in transition tree (property at index |kDiffProp| |
| 1681 // has different attributes), initialize expectations. |
| 1682 const int kDiffProp = kPropCount / 2; |
| 1683 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
| 1684 |
| 1685 Handle<Map> map2 = initial_map; |
| 1686 for (int i = 0; i < kPropCount; i++) { |
| 1687 if (i == kDiffProp) { |
| 1688 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); |
| 1689 } else { |
| 1690 map2 = expectations2.AddDataField(map2, NONE, from_representation, |
| 1691 from_type); |
| 1692 } |
| 1693 } |
| 1694 CHECK(!map2->is_deprecated()); |
| 1695 CHECK(map2->is_stable()); |
| 1696 CHECK(expectations2.Check(*map2)); |
| 1697 |
| 1698 Zone zone(isolate->allocator()); |
| 1699 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
| 1700 CompilationInfo info("testing", isolate, &zone); |
| 1701 CHECK(!info.dependencies()->HasAborted()); |
| 1702 info.dependencies()->AssumeFieldType(field_owner); |
| 1703 |
| 1704 // Reconfigure elements kinds of |map2|, which should generalize |
| 1705 // representations in |map|. |
| 1706 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
| 1707 |
| 1708 // |map2| should be left unchanged but marked unstable. |
| 1709 CHECK(!map2->is_stable()); |
| 1710 CHECK(!map2->is_deprecated()); |
| 1711 CHECK_NE(*map2, *new_map); |
| 1712 CHECK(expectations2.Check(*map2)); |
| 1713 |
| 1714 // In trivial case |map| should be returned as a result of the elements |
| 1715 // kind reconfiguration, respective field types should be generalized and |
| 1716 // respective code dependencies should be invalidated. |map| should be NOT |
| 1717 // deprecated and it should match new expectations. |
| 1718 expectations.SetDataField(kDiffProp, expected_representation, expected_type); |
| 1719 CHECK(!map->is_deprecated()); |
| 1720 CHECK_EQ(*map, *new_map); |
| 1721 CHECK_EQ(expected_field_type_dependency, info.dependencies()->HasAborted()); |
| 1722 info.dependencies()->Rollback(); // Properly cleanup compilation info. |
| 1723 |
| 1724 CHECK(!new_map->is_deprecated()); |
| 1725 CHECK(expectations.Check(*new_map)); |
| 1726 |
| 1727 Handle<Map> updated_map = Map::Update(map); |
| 1728 CHECK_EQ(*new_map, *updated_map); |
| 1729 |
| 1730 // Ensure Map::FindElementsKindTransitionedMap() is able to find the |
| 1731 // transitioned map. |
| 1732 { |
| 1733 MapHandleList map_list; |
| 1734 map_list.Add(updated_map); |
| 1735 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); |
| 1736 CHECK_EQ(*updated_map, transitioned_map); |
| 1737 } |
| 1738 } |
| 1739 |
| 1740 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToDouble) { |
| 1741 CcTest::InitializeVM(); |
| 1742 v8::HandleScope scope(CcTest::isolate()); |
| 1743 Isolate* isolate = CcTest::i_isolate(); |
| 1744 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1745 |
| 1746 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1747 Representation::Smi(), any_type, Representation::Double(), any_type, |
| 1748 Representation::Double(), any_type); |
| 1749 } |
| 1750 |
| 1751 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) { |
| 1752 CcTest::InitializeVM(); |
| 1753 v8::HandleScope scope(CcTest::isolate()); |
| 1754 Isolate* isolate = CcTest::i_isolate(); |
| 1755 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1756 Handle<FieldType> value_type = |
| 1757 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1758 |
| 1759 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1760 Representation::Smi(), any_type, Representation::HeapObject(), value_type, |
| 1761 Representation::Tagged(), any_type); |
| 1762 } |
| 1763 |
| 1764 TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) { |
| 1765 CcTest::InitializeVM(); |
| 1766 v8::HandleScope scope(CcTest::isolate()); |
| 1767 Isolate* isolate = CcTest::i_isolate(); |
| 1768 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1769 Handle<FieldType> value_type = |
| 1770 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1771 |
| 1772 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1773 Representation::Double(), any_type, Representation::HeapObject(), |
| 1774 value_type, Representation::Tagged(), any_type); |
| 1775 } |
| 1776 |
| 1777 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) { |
| 1778 CcTest::InitializeVM(); |
| 1779 v8::HandleScope scope(CcTest::isolate()); |
| 1780 Isolate* isolate = CcTest::i_isolate(); |
| 1781 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1782 |
| 1783 Handle<FieldType> current_type = |
| 1784 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1785 |
| 1786 Handle<FieldType> new_type = |
| 1787 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1788 |
| 1789 Handle<FieldType> expected_type = any_type; |
| 1790 |
| 1791 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1792 Representation::HeapObject(), current_type, Representation::HeapObject(), |
| 1793 new_type, Representation::HeapObject(), expected_type); |
| 1794 current_type = expected_type; |
| 1795 |
| 1796 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1797 |
| 1798 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
| 1799 Representation::HeapObject(), any_type, Representation::HeapObject(), |
| 1800 new_type, Representation::HeapObject(), any_type, false); |
| 1801 } |
| 1802 |
| 1803 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) { |
| 1804 CcTest::InitializeVM(); |
| 1805 v8::HandleScope scope(CcTest::isolate()); |
| 1806 Isolate* isolate = CcTest::i_isolate(); |
| 1807 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1808 Handle<FieldType> value_type = |
| 1809 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1810 |
| 1811 TestReconfigureElementsKind_GeneralizeRepresentation( |
| 1812 Representation::HeapObject(), value_type, Representation::Smi(), any_type, |
| 1813 Representation::Tagged(), any_type); |
| 1814 } |
| 1815 |
| 1816 //////////////////////////////////////////////////////////////////////////////// |
| 1532 // A set of tests checking split map deprecation. | 1817 // A set of tests checking split map deprecation. |
| 1533 // | 1818 // |
| 1534 | 1819 |
| 1535 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { | 1820 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { |
| 1536 CcTest::InitializeVM(); | 1821 CcTest::InitializeVM(); |
| 1537 v8::HandleScope scope(CcTest::isolate()); | 1822 v8::HandleScope scope(CcTest::isolate()); |
| 1538 Isolate* isolate = CcTest::i_isolate(); | 1823 Isolate* isolate = CcTest::i_isolate(); |
| 1539 Handle<FieldType> any_type = FieldType::Any(isolate); | 1824 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1540 | 1825 |
| 1541 Expectations expectations(isolate); | 1826 Expectations expectations(isolate); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1637 // Create a map, add required properties to it and initialize expectations. | 1922 // Create a map, add required properties to it and initialize expectations. |
| 1638 Handle<Map> initial_map = Map::Create(isolate, 0); | 1923 Handle<Map> initial_map = Map::Create(isolate, 0); |
| 1639 Handle<Map> map = initial_map; | 1924 Handle<Map> map = initial_map; |
| 1640 for (int i = 0; i < kPropCount; i++) { | 1925 for (int i = 0; i < kPropCount; i++) { |
| 1641 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 1926 map = expectations.AddDataField(map, NONE, from_representation, from_type); |
| 1642 } | 1927 } |
| 1643 CHECK(!map->is_deprecated()); | 1928 CHECK(!map->is_deprecated()); |
| 1644 CHECK(map->is_stable()); | 1929 CHECK(map->is_stable()); |
| 1645 CHECK(expectations.Check(*map)); | 1930 CHECK(expectations.Check(*map)); |
| 1646 | 1931 |
| 1932 Expectations expectations2 = expectations; |
| 1933 |
| 1647 // Apply some special transition to |map|. | 1934 // Apply some special transition to |map|. |
| 1648 CHECK(map->owns_descriptors()); | 1935 CHECK(map->owns_descriptors()); |
| 1649 Handle<Map> map2 = config.Transition(map); | 1936 Handle<Map> map2 = config.Transition(map, expectations2); |
| 1650 | 1937 |
| 1651 // |map| should still match expectations. | 1938 // |map| should still match expectations. |
| 1652 CHECK(!map->is_deprecated()); | 1939 CHECK(!map->is_deprecated()); |
| 1653 CHECK(expectations.Check(*map)); | 1940 CHECK(expectations.Check(*map)); |
| 1654 | 1941 |
| 1655 Expectations expectations2 = expectations; | |
| 1656 if (config.generalizes_representations()) { | 1942 if (config.generalizes_representations()) { |
| 1657 for (int i = 0; i < kPropCount; i++) { | 1943 for (int i = 0; i < kPropCount; i++) { |
| 1658 expectations2.GeneralizeRepresentation(i); | 1944 expectations2.GeneralizeRepresentation(i); |
| 1659 } | 1945 } |
| 1660 } | 1946 } |
| 1661 | 1947 |
| 1662 CHECK(!map2->is_deprecated()); | 1948 CHECK(!map2->is_deprecated()); |
| 1663 CHECK(map2->is_stable()); | 1949 CHECK(map2->is_stable()); |
| 1664 CHECK(expectations2.Check(*map2)); | 1950 CHECK(expectations2.Check(*map2)); |
| 1665 | 1951 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 | 2003 |
| 1718 TEST(ElementsKindTransitionFromMapOwningDescriptor) { | 2004 TEST(ElementsKindTransitionFromMapOwningDescriptor) { |
| 1719 CcTest::InitializeVM(); | 2005 CcTest::InitializeVM(); |
| 1720 v8::HandleScope scope(CcTest::isolate()); | 2006 v8::HandleScope scope(CcTest::isolate()); |
| 1721 Isolate* isolate = CcTest::i_isolate(); | 2007 Isolate* isolate = CcTest::i_isolate(); |
| 1722 Handle<FieldType> any_type = FieldType::Any(isolate); | 2008 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1723 Handle<FieldType> value_type = | 2009 Handle<FieldType> value_type = |
| 1724 FieldType::Class(Map::Create(isolate, 0), isolate); | 2010 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1725 | 2011 |
| 1726 struct TestConfig { | 2012 struct TestConfig { |
| 1727 Handle<Map> Transition(Handle<Map> map) { | 2013 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
| 1728 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 2014 Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol()); |
| 1729 INSERT_TRANSITION); | 2015 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
| 2016 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
| 2017 "CopyForPreventExtensions"); |
| 1730 } | 2018 } |
| 1731 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2019 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1732 bool generalizes_representations() const { return false; } | 2020 bool generalizes_representations() const { return false; } |
| 1733 bool is_non_equevalent_transition() const { return false; } | 2021 bool is_non_equevalent_transition() const { return true; } |
| 1734 }; | 2022 }; |
| 1735 TestConfig config; | 2023 TestConfig config; |
| 1736 TestGeneralizeRepresentationWithSpecialTransition( | 2024 TestGeneralizeRepresentationWithSpecialTransition( |
| 1737 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2025 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1738 value_type, Representation::Tagged(), any_type); | 2026 value_type, Representation::Tagged(), any_type); |
| 1739 } | 2027 } |
| 1740 | 2028 |
| 1741 | 2029 |
| 1742 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { | 2030 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { |
| 1743 CcTest::InitializeVM(); | 2031 CcTest::InitializeVM(); |
| 1744 v8::HandleScope scope(CcTest::isolate()); | 2032 v8::HandleScope scope(CcTest::isolate()); |
| 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 Handle<FieldType> value_type = | 2035 Handle<FieldType> value_type = |
| 1748 FieldType::Class(Map::Create(isolate, 0), isolate); | 2036 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1749 | 2037 |
| 1750 struct TestConfig { | 2038 struct TestConfig { |
| 1751 Handle<Map> Transition(Handle<Map> map) { | 2039 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
| 1752 Isolate* isolate = CcTest::i_isolate(); | 2040 Isolate* isolate = CcTest::i_isolate(); |
| 1753 Handle<FieldType> any_type = FieldType::Any(isolate); | 2041 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1754 | 2042 |
| 1755 // Add one more transition to |map| in order to prevent descriptors | 2043 // Add one more transition to |map| in order to prevent descriptors |
| 1756 // ownership. | 2044 // ownership. |
| 1757 CHECK(map->owns_descriptors()); | 2045 CHECK(map->owns_descriptors()); |
| 1758 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2046 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
| 1759 Representation::Smi(), INSERT_TRANSITION) | 2047 Representation::Smi(), INSERT_TRANSITION) |
| 1760 .ToHandleChecked(); | 2048 .ToHandleChecked(); |
| 1761 CHECK(!map->owns_descriptors()); | 2049 CHECK(!map->owns_descriptors()); |
| 1762 | 2050 |
| 1763 return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS, | 2051 Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol()); |
| 1764 INSERT_TRANSITION); | 2052 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
| 2053 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
| 2054 "CopyForPreventExtensions"); |
| 1765 } | 2055 } |
| 1766 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2056 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1767 bool generalizes_representations() const { return false; } | 2057 bool generalizes_representations() const { return false; } |
| 1768 bool is_non_equevalent_transition() const { return false; } | 2058 bool is_non_equevalent_transition() const { return true; } |
| 1769 }; | 2059 }; |
| 1770 TestConfig config; | 2060 TestConfig config; |
| 1771 TestGeneralizeRepresentationWithSpecialTransition( | 2061 TestGeneralizeRepresentationWithSpecialTransition( |
| 1772 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2062 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1773 value_type, Representation::Tagged(), any_type); | 2063 value_type, Representation::Tagged(), any_type); |
| 1774 } | 2064 } |
| 1775 | 2065 |
| 1776 | 2066 |
| 1777 TEST(ForObservedTransitionFromMapOwningDescriptor) { | 2067 TEST(ForObservedTransitionFromMapOwningDescriptor) { |
| 1778 CcTest::InitializeVM(); | 2068 CcTest::InitializeVM(); |
| 1779 v8::HandleScope scope(CcTest::isolate()); | 2069 v8::HandleScope scope(CcTest::isolate()); |
| 1780 Isolate* isolate = CcTest::i_isolate(); | 2070 Isolate* isolate = CcTest::i_isolate(); |
| 1781 Handle<FieldType> any_type = FieldType::Any(isolate); | 2071 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1782 Handle<FieldType> value_type = | 2072 Handle<FieldType> value_type = |
| 1783 FieldType::Class(Map::Create(isolate, 0), isolate); | 2073 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1784 | 2074 |
| 1785 struct TestConfig { | 2075 struct TestConfig { |
| 1786 Handle<Map> Transition(Handle<Map> map) { | 2076 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
| 1787 return Map::CopyForObserved(map); | 2077 return Map::CopyForObserved(map); |
| 1788 } | 2078 } |
| 1789 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2079 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1790 bool generalizes_representations() const { return false; } | 2080 bool generalizes_representations() const { return false; } |
| 1791 bool is_non_equevalent_transition() const { return true; } | 2081 bool is_non_equevalent_transition() const { return true; } |
| 1792 }; | 2082 }; |
| 1793 TestConfig config; | 2083 TestConfig config; |
| 1794 TestGeneralizeRepresentationWithSpecialTransition( | 2084 TestGeneralizeRepresentationWithSpecialTransition( |
| 1795 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2085 config, Representation::Smi(), any_type, Representation::HeapObject(), |
| 1796 value_type, Representation::Tagged(), any_type); | 2086 value_type, Representation::Tagged(), any_type); |
| 1797 } | 2087 } |
| 1798 | 2088 |
| 1799 | 2089 |
| 1800 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { | 2090 TEST(ForObservedTransitionFromMapNotOwningDescriptor) { |
| 1801 CcTest::InitializeVM(); | 2091 CcTest::InitializeVM(); |
| 1802 v8::HandleScope scope(CcTest::isolate()); | 2092 v8::HandleScope scope(CcTest::isolate()); |
| 1803 Isolate* isolate = CcTest::i_isolate(); | 2093 Isolate* isolate = CcTest::i_isolate(); |
| 1804 Handle<FieldType> any_type = FieldType::Any(isolate); | 2094 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1805 Handle<FieldType> value_type = | 2095 Handle<FieldType> value_type = |
| 1806 FieldType::Class(Map::Create(isolate, 0), isolate); | 2096 FieldType::Class(Map::Create(isolate, 0), isolate); |
| 1807 | 2097 |
| 1808 struct TestConfig { | 2098 struct TestConfig { |
| 1809 Handle<Map> Transition(Handle<Map> map) { | 2099 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
| 1810 Isolate* isolate = CcTest::i_isolate(); | 2100 Isolate* isolate = CcTest::i_isolate(); |
| 1811 Handle<FieldType> any_type = FieldType::Any(isolate); | 2101 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1812 | 2102 |
| 1813 // Add one more transition to |map| in order to prevent descriptors | 2103 // Add one more transition to |map| in order to prevent descriptors |
| 1814 // ownership. | 2104 // ownership. |
| 1815 CHECK(map->owns_descriptors()); | 2105 CHECK(map->owns_descriptors()); |
| 1816 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2106 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
| 1817 Representation::Smi(), INSERT_TRANSITION) | 2107 Representation::Smi(), INSERT_TRANSITION) |
| 1818 .ToHandleChecked(); | 2108 .ToHandleChecked(); |
| 1819 CHECK(!map->owns_descriptors()); | 2109 CHECK(!map->owns_descriptors()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1842 | 2132 |
| 1843 struct TestConfig { | 2133 struct TestConfig { |
| 1844 Handle<JSObject> prototype_; | 2134 Handle<JSObject> prototype_; |
| 1845 | 2135 |
| 1846 TestConfig() { | 2136 TestConfig() { |
| 1847 Isolate* isolate = CcTest::i_isolate(); | 2137 Isolate* isolate = CcTest::i_isolate(); |
| 1848 Factory* factory = isolate->factory(); | 2138 Factory* factory = isolate->factory(); |
| 1849 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 2139 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
| 1850 } | 2140 } |
| 1851 | 2141 |
| 1852 Handle<Map> Transition(Handle<Map> map) { | 2142 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
| 1853 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 2143 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
| 1854 } | 2144 } |
| 1855 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2145 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
| 1856 bool generalizes_representations() const { | 2146 bool generalizes_representations() const { |
| 1857 return !IS_PROTO_TRANS_ISSUE_FIXED; | 2147 return !IS_PROTO_TRANS_ISSUE_FIXED; |
| 1858 } | 2148 } |
| 1859 bool is_non_equevalent_transition() const { return true; } | 2149 bool is_non_equevalent_transition() const { return true; } |
| 1860 }; | 2150 }; |
| 1861 TestConfig config; | 2151 TestConfig config; |
| 1862 TestGeneralizeRepresentationWithSpecialTransition( | 2152 TestGeneralizeRepresentationWithSpecialTransition( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1876 | 2166 |
| 1877 struct TestConfig { | 2167 struct TestConfig { |
| 1878 Handle<JSObject> prototype_; | 2168 Handle<JSObject> prototype_; |
| 1879 | 2169 |
| 1880 TestConfig() { | 2170 TestConfig() { |
| 1881 Isolate* isolate = CcTest::i_isolate(); | 2171 Isolate* isolate = CcTest::i_isolate(); |
| 1882 Factory* factory = isolate->factory(); | 2172 Factory* factory = isolate->factory(); |
| 1883 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); | 2173 prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); |
| 1884 } | 2174 } |
| 1885 | 2175 |
| 1886 Handle<Map> Transition(Handle<Map> map) { | 2176 Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { |
| 1887 Isolate* isolate = CcTest::i_isolate(); | 2177 Isolate* isolate = CcTest::i_isolate(); |
| 1888 Handle<FieldType> any_type = FieldType::Any(isolate); | 2178 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 1889 | 2179 |
| 1890 // Add one more transition to |map| in order to prevent descriptors | 2180 // Add one more transition to |map| in order to prevent descriptors |
| 1891 // ownership. | 2181 // ownership. |
| 1892 CHECK(map->owns_descriptors()); | 2182 CHECK(map->owns_descriptors()); |
| 1893 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, | 2183 Map::CopyWithField(map, MakeString("foo"), any_type, NONE, |
| 1894 Representation::Smi(), INSERT_TRANSITION) | 2184 Representation::Smi(), INSERT_TRANSITION) |
| 1895 .ToHandleChecked(); | 2185 .ToHandleChecked(); |
| 1896 CHECK(!map->owns_descriptors()); | 2186 CHECK(!map->owns_descriptors()); |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2179 Handle<AccessorPair> pair = CreateAccessorPair(true, true); | 2469 Handle<AccessorPair> pair = CreateAccessorPair(true, true); |
| 2180 TransitionToAccessorConstantOperator transition_op(pair); | 2470 TransitionToAccessorConstantOperator transition_op(pair); |
| 2181 | 2471 |
| 2182 SameMapChecker checker; | 2472 SameMapChecker checker; |
| 2183 TestTransitionTo(transition_op, transition_op, checker); | 2473 TestTransitionTo(transition_op, transition_op, checker); |
| 2184 } | 2474 } |
| 2185 | 2475 |
| 2186 | 2476 |
| 2187 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. | 2477 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. |
| 2188 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) | 2478 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) |
| OLD | NEW |