Index: test/cctest/test-migrations.cc |
diff --git a/test/cctest/test-migrations.cc b/test/cctest/test-migrations.cc |
index 2f7ff8703c7f3187d6640732de6577fa167e18db..9eb367639a647da1592873dc6ea569cf4c831948 100644 |
--- a/test/cctest/test-migrations.cc |
+++ b/test/cctest/test-migrations.cc |
@@ -145,6 +145,7 @@ class Expectations { |
os << ": " << representations_[i].Mnemonic(); |
os << ", attrs: " << attributes_[i] << ")\n"; |
} |
+ os << "\n"; |
} |
Handle<HeapType> GetFieldType(int index) { |
@@ -263,6 +264,9 @@ class Expectations { |
for (int i = 0; i < expected_nof; i++) { |
if (!Check(descriptors, i)) { |
Print(); |
+#ifdef OBJECT_PRINT |
+ descriptors->Print(); |
+#endif |
Check(descriptors, i); |
return false; |
} |
@@ -517,21 +521,51 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) { |
// A set of tests for representation generalization case. |
// |
-static void TestGeneralizeRepresentation(Representation from_representation, |
- Handle<HeapType> from_type, |
- Representation to_representation, |
- Handle<HeapType> to_type, |
- Representation expected_representation, |
- Handle<HeapType> expected_type) { |
+// This test ensures that representation/field type generalization at |
+// |property_index| is done correctly independently of the fact that the |map| |
+// is detached from transition tree or not. |
+// |
+// {} - p0 - p1 - p2: |detach_point_map| |
+// | |
+// X - detached at |detach_property_at_index| |
+// | |
+// + - p3 - p4: |map| |
+// |
+// Detaching does not happen if |detach_property_at_index| is -1. |
+// |
+static void TestGeneralizeRepresentation( |
+ int detach_property_at_index, int property_index, |
+ Representation from_representation, Handle<HeapType> from_type, |
+ Representation to_representation, Handle<HeapType> to_type, |
+ Representation expected_representation, Handle<HeapType> expected_type, |
+ bool expected_deprecation, bool expected_field_type_dependency) { |
Isolate* isolate = CcTest::i_isolate(); |
+ Handle<HeapType> any_type = HeapType::Any(isolate); |
+ |
+ CHECK(detach_property_at_index >= -1 && |
+ detach_property_at_index < kPropCount); |
+ CHECK(property_index < kPropCount); |
+ CHECK_NE(detach_property_at_index, property_index); |
+ |
+ const bool is_detached_map = detach_property_at_index >= 0; |
Expectations expectations(isolate); |
// Create a map, add required properties to it and initialize expectations. |
Handle<Map> initial_map = Map::Create(isolate, 0); |
Handle<Map> map = initial_map; |
+ Handle<Map> detach_point_map; |
for (int i = 0; i < kPropCount; i++) { |
- map = expectations.AddDataField(map, NONE, from_representation, from_type); |
+ if (i == property_index) { |
+ map = |
+ expectations.AddDataField(map, NONE, from_representation, from_type); |
+ } else { |
+ map = |
+ expectations.AddDataField(map, NONE, Representation::Smi(), any_type); |
+ if (i == detach_property_at_index) { |
+ detach_point_map = map; |
+ } |
+ } |
} |
CHECK(!map->is_deprecated()); |
CHECK(map->is_stable()); |
@@ -540,97 +574,121 @@ static void TestGeneralizeRepresentation(Representation from_representation, |
Zone zone; |
FakeStubForTesting stub(isolate); |
+ if (is_detached_map) { |
+ detach_point_map = Map::ReconfigureProperty( |
+ detach_point_map, detach_property_at_index, kData, NONE, |
+ Representation::Tagged(), any_type, FORCE_FIELD); |
+ expectations.SetDataField(detach_property_at_index, |
+ Representation::Tagged(), any_type); |
+ CHECK(map->is_deprecated()); |
+ CHECK(expectations.Check(*detach_point_map, |
+ detach_point_map->NumberOfOwnDescriptors())); |
+ } |
+ |
// Create new maps by generalizing representation of propX field. |
- Handle<Map> maps[kPropCount]; |
- for (int i = 0; i < kPropCount; i++) { |
- Handle<Map> field_owner(map->FindFieldOwner(i), isolate); |
- CompilationInfo info(&stub, isolate, &zone); |
- CHECK(!info.HasAbortedDueToDependencyChange()); |
+ Handle<Map> field_owner(map->FindFieldOwner(property_index), isolate); |
+ CompilationInfo info(&stub, isolate, &zone); |
+ CHECK(!info.HasAbortedDueToDependencyChange()); |
- Map::AddDependentCompilationInfo(field_owner, |
- DependentCode::kFieldTypeGroup, &info); |
+ Map::AddDependentCompilationInfo(field_owner, DependentCode::kFieldTypeGroup, |
+ &info); |
- Handle<Map> new_map = Map::ReconfigureProperty( |
- map, i, kData, NONE, to_representation, to_type, FORCE_FIELD); |
- maps[i] = new_map; |
+ Handle<Map> new_map = |
+ Map::ReconfigureProperty(map, property_index, kData, NONE, |
+ to_representation, to_type, FORCE_FIELD); |
- expectations.SetDataField(i, expected_representation, expected_type); |
+ expectations.SetDataField(property_index, expected_representation, |
+ expected_type); |
+ CHECK(!new_map->is_deprecated()); |
+ CHECK(expectations.Check(*new_map)); |
+ |
+ if (is_detached_map) { |
CHECK(map->is_deprecated()); |
- CHECK(!info.HasAbortedDueToDependencyChange()); |
- info.RollbackDependencies(); // Properly cleanup compilation info. |
+ CHECK_NE(*map, *new_map); |
+ CHECK_EQ(expected_field_type_dependency && !field_owner->is_deprecated(), |
+ info.HasAbortedDueToDependencyChange()); |
+ } else if (expected_deprecation) { |
+ CHECK(map->is_deprecated()); |
+ CHECK(field_owner->is_deprecated()); |
CHECK_NE(*map, *new_map); |
- CHECK(i == 0 || maps[i - 1]->is_deprecated()); |
+ CHECK(!info.HasAbortedDueToDependencyChange()); |
- CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
- CHECK(expectations.Check(*new_map)); |
+ } else { |
+ CHECK(!field_owner->is_deprecated()); |
+ CHECK_EQ(*map, *new_map); |
+ |
+ CHECK_EQ(expected_field_type_dependency, |
+ info.HasAbortedDueToDependencyChange()); |
} |
- Handle<Map> active_map = maps[kPropCount - 1]; |
- CHECK(!active_map->is_deprecated()); |
+ info.RollbackDependencies(); // Properly cleanup compilation info. |
// Update all deprecated maps and check that they are now the same. |
Handle<Map> updated_map = Map::Update(map); |
- CHECK_EQ(*active_map, *updated_map); |
- for (int i = 0; i < kPropCount; i++) { |
- updated_map = Map::Update(maps[i]); |
- CHECK_EQ(*active_map, *updated_map); |
- } |
+ CHECK_EQ(*new_map, *updated_map); |
} |
-static void TestGeneralizeRepresentationTrivial( |
+static void TestGeneralizeRepresentation( |
Representation from_representation, Handle<HeapType> from_type, |
Representation to_representation, Handle<HeapType> to_type, |
Representation expected_representation, Handle<HeapType> expected_type, |
- bool expected_field_type_dependency = true) { |
- Isolate* isolate = CcTest::i_isolate(); |
- |
- Expectations expectations(isolate); |
- |
- // Create a map, add required properties to it and initialize expectations. |
- Handle<Map> initial_map = Map::Create(isolate, 0); |
- Handle<Map> map = initial_map; |
- for (int i = 0; i < kPropCount; i++) { |
- map = expectations.AddDataField(map, NONE, from_representation, from_type); |
+ bool expected_deprecation, bool expected_field_type_dependency) { |
+ // Check the cases when the map being reconfigured is a part of the |
+ // transition tree. |
+ STATIC_ASSERT(kPropCount > 4); |
+ int indices[] = {0, 2, kPropCount - 1}; |
+ for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) { |
+ TestGeneralizeRepresentation( |
+ -1, indices[i], from_representation, from_type, to_representation, |
+ to_type, expected_representation, expected_type, expected_deprecation, |
+ expected_field_type_dependency); |
+ } |
+ |
+ if (!from_representation.IsNone()) { |
+ // Check the cases when the map being reconfigured is NOT a part of the |
+ // transition tree. "None -> anything" representation changes make sense |
+ // only for "attached" maps. |
+ int indices[] = {0, kPropCount - 1}; |
+ for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) { |
+ TestGeneralizeRepresentation( |
+ indices[i], 2, from_representation, from_type, to_representation, |
+ to_type, expected_representation, expected_type, expected_deprecation, |
+ expected_field_type_dependency); |
+ } |
} |
- CHECK(!map->is_deprecated()); |
- CHECK(map->is_stable()); |
- CHECK(expectations.Check(*map)); |
- |
- Zone zone; |
- FakeStubForTesting stub(isolate); |
- |
- // Create new maps by generalizing representation of propX field. |
- for (int i = 0; i < kPropCount; i++) { |
- Handle<Map> field_owner(map->FindFieldOwner(i), isolate); |
- CompilationInfo info(&stub, isolate, &zone); |
- CHECK(!info.HasAbortedDueToDependencyChange()); |
+} |
- Map::AddDependentCompilationInfo(field_owner, |
- DependentCode::kFieldTypeGroup, &info); |
- Handle<Map> new_map = Map::ReconfigureProperty( |
- map, i, kData, NONE, to_representation, to_type, FORCE_FIELD); |
- |
- expectations.SetDataField(i, expected_representation, expected_type); |
+static void TestGeneralizeRepresentation(Representation from_representation, |
+ Handle<HeapType> from_type, |
+ Representation to_representation, |
+ Handle<HeapType> to_type, |
+ Representation expected_representation, |
+ Handle<HeapType> expected_type) { |
+ const bool expected_deprecation = true; |
+ const bool expected_field_type_dependency = false; |
- CHECK_EQ(*map, *new_map); |
- CHECK_EQ(expected_field_type_dependency, |
- info.HasAbortedDueToDependencyChange()); |
+ TestGeneralizeRepresentation( |
+ from_representation, from_type, to_representation, to_type, |
+ expected_representation, expected_type, expected_deprecation, |
+ expected_field_type_dependency); |
+} |
- info.RollbackDependencies(); // Properly cleanup compilation info. |
- CHECK_EQ(*map, *new_map); |
- CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
- CHECK(expectations.Check(*new_map)); |
- } |
+static void TestGeneralizeRepresentationTrivial( |
+ Representation from_representation, Handle<HeapType> from_type, |
+ Representation to_representation, Handle<HeapType> to_type, |
+ Representation expected_representation, Handle<HeapType> expected_type, |
+ bool expected_field_type_dependency = true) { |
+ const bool expected_deprecation = false; |
- Handle<Map> updated_map = Map::Update(map); |
- CHECK_EQ(*map, *updated_map); |
+ TestGeneralizeRepresentation( |
+ from_representation, from_type, to_representation, to_type, |
+ expected_representation, expected_type, expected_deprecation, |
+ expected_field_type_dependency); |
} |
@@ -828,7 +886,6 @@ TEST(GeneralizeRepresentationWithAccessorProperties) { |
CHECK(i == 0 || maps[i - 1]->is_deprecated()); |
CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
CHECK(expectations.Check(*new_map)); |
} |
@@ -925,7 +982,6 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation( |
CHECK_NE(*map, *new_map); |
CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
CHECK(expectations.Check(*new_map)); |
// Update deprecated |map|, it should become |new_map|. |
@@ -1016,7 +1072,6 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( |
info.RollbackDependencies(); // Properly cleanup compilation info. |
CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
CHECK(expectations.Check(*new_map)); |
Handle<Map> updated_map = Map::Update(map); |
@@ -1121,7 +1176,6 @@ struct CheckDeprecated { |
CHECK_NE(*map, *new_map); |
CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
CHECK(expectations.Check(*new_map)); |
// Update deprecated |map|, it should become |new_map|. |
@@ -1140,7 +1194,6 @@ struct CheckSameMap { |
CHECK_EQ(*map, *new_map); |
CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
CHECK(expectations.Check(*new_map)); |
// Update deprecated |map|, it should become |new_map|. |
@@ -1163,7 +1216,6 @@ struct CheckCopyGeneralizeAllRepresentations { |
} |
CHECK(!new_map->is_deprecated()); |
- CHECK(!new_map->is_dictionary_map()); |
CHECK(expectations.Check(*new_map)); |
} |
}; |