Index: test/cctest/test-migrations.cc |
diff --git a/test/cctest/test-migrations.cc b/test/cctest/test-migrations.cc |
index e80ec7c06c948e61b25a92ab7d312bc295ebd2ef..0cefd54cebd5d21dd81fb4e33262627994abe863 100644 |
--- a/test/cctest/test-migrations.cc |
+++ b/test/cctest/test-migrations.cc |
@@ -437,9 +437,9 @@ TEST(ReconfigureAccessorToNonExistingDataField) { |
Handle<Map> new_map = Map::ReconfigureProperty( |
map, 0, kData, NONE, Representation::None(), none_type, FORCE_FIELD); |
- // |map| did not change. |
+ // |map| did not change except marked unstable. |
CHECK(!map->is_deprecated()); |
- CHECK(map->is_stable()); |
+ CHECK(!map->is_stable()); |
CHECK(expectations.Check(*map)); |
expectations.SetDataField(0, NONE, Representation::None(), none_type); |
@@ -600,12 +600,14 @@ static void TestGeneralizeRepresentation( |
CHECK(expectations.Check(*new_map)); |
if (is_detached_map) { |
+ CHECK(!map->is_stable()); |
CHECK(map->is_deprecated()); |
CHECK_NE(*map, *new_map); |
CHECK_EQ(expected_field_type_dependency && !field_owner->is_deprecated(), |
info.dependencies()->HasAborted()); |
} else if (expected_deprecation) { |
+ CHECK(!map->is_stable()); |
CHECK(map->is_deprecated()); |
CHECK(field_owner->is_deprecated()); |
CHECK_NE(*map, *new_map); |
@@ -613,6 +615,7 @@ static void TestGeneralizeRepresentation( |
} else { |
CHECK(!field_owner->is_deprecated()); |
+ CHECK(map->is_stable()); // Map did not change, must be left stable. |
CHECK_EQ(*map, *new_map); |
CHECK_EQ(expected_field_type_dependency, info.dependencies()->HasAborted()); |
@@ -653,6 +656,12 @@ static void TestGeneralizeRepresentation( |
to_type, expected_representation, expected_type, expected_deprecation, |
expected_field_type_dependency); |
} |
+ |
+ // Check that reconfiguration to the very same field works correctly. |
+ Representation representation = from_representation; |
+ Handle<HeapType> type = from_type; |
+ TestGeneralizeRepresentation(-1, 2, representation, type, representation, |
+ type, representation, type, false, false); |
} |
} |
@@ -876,6 +885,7 @@ TEST(GeneralizeRepresentationWithAccessorProperties) { |
expectations.SetDataField(i, Representation::Double(), any_type); |
+ CHECK(!map->is_stable()); |
CHECK(map->is_deprecated()); |
CHECK_NE(*map, *new_map); |
CHECK(i == 0 || maps[i - 1]->is_deprecated()); |
@@ -961,7 +971,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation( |
Handle<Map> new_map = |
Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); |
- // |map2| should be left unchanged. |
+ // |map2| should be left unchanged but marked unstable. |
+ CHECK(!map2->is_stable()); |
CHECK(!map2->is_deprecated()); |
CHECK_NE(*map2, *new_map); |
CHECK(expectations2.Check(*map2)); |
@@ -1046,7 +1057,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( |
Handle<Map> new_map = |
Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); |
- // |map2| should be left unchanged. |
+ // |map2| should be left unchanged but marked unstable. |
+ CHECK(!map2->is_stable()); |
CHECK(!map2->is_deprecated()); |
CHECK_NE(*map2, *new_map); |
CHECK(expectations2.Check(*map2)); |
@@ -1182,6 +1194,8 @@ struct CheckDeprecated { |
struct CheckSameMap { |
void Check(Handle<Map> map, Handle<Map> new_map, |
const Expectations& expectations) { |
+ // |map| was not reconfigured, therefore it should stay stable. |
+ CHECK(map->is_stable()); |
CHECK(!map->is_deprecated()); |
CHECK_EQ(*map, *new_map); |
@@ -1195,6 +1209,21 @@ struct CheckSameMap { |
}; |
+// Checks that given |map| is NOT deprecated and matches expectations. |
+// |new_map| is unrelated to |map|. |
+struct CheckUnrelated { |
+ void Check(Handle<Map> map, Handle<Map> new_map, |
+ const Expectations& expectations) { |
+ CHECK(!map->is_deprecated()); |
+ CHECK_NE(*map, *new_map); |
+ CHECK(expectations.Check(*map)); |
+ |
+ CHECK(new_map->is_stable()); |
+ CHECK(!new_map->is_deprecated()); |
+ } |
+}; |
+ |
+ |
// Checks that given |map| is NOT deprecated, and |new_map| is a result of |
// copy-generalize-all-representations. |
struct CheckCopyGeneralizeAllRepresentations { |
@@ -1288,7 +1317,8 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( |
Handle<Map> new_map = |
Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); |
- // |map2| should be left unchanged. |
+ // |map2| should be left unchanged but marked unstable. |
+ CHECK(!map2->is_stable()); |
CHECK(!map2->is_deprecated()); |
CHECK_NE(*map2, *new_map); |
CHECK(expectations2.Check(*map2)); |
@@ -1365,6 +1395,40 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) { |
} |
+TEST(ReconfigureDataFieldAttribute_DataConstantToAccConstantAfterTargetMap) { |
+ CcTest::InitializeVM(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ |
+ struct TestConfig { |
+ Handle<JSFunction> js_func_; |
+ Handle<AccessorPair> pair_; |
+ TestConfig() { |
+ Isolate* isolate = CcTest::i_isolate(); |
+ Factory* factory = isolate->factory(); |
+ js_func_ = factory->NewFunction(factory->empty_string()); |
+ pair_ = CreateAccessorPair(true, true); |
+ } |
+ |
+ Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations, |
+ Handle<Map> map) { |
+ CHECK(branch_id == 1 || branch_id == 2); |
+ if (branch_id == 1) { |
+ return expectations.AddDataConstant(map, NONE, js_func_); |
+ } else { |
+ return expectations.AddAccessorConstant(map, NONE, pair_); |
+ } |
+ } |
+ |
+ void UpdateExpectations(int property_index, Expectations& expectations) {} |
+ }; |
+ |
+ TestConfig config; |
+ // These are completely separate branches in transition tree. |
+ CheckUnrelated checker; |
+ TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); |
+} |
+ |
+ |
TEST(ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) { |
CcTest::InitializeVM(); |
v8::HandleScope scope(CcTest::isolate()); |
@@ -1381,9 +1445,8 @@ TEST(ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) { |
return expectations.AddAccessorConstant(map, NONE, pair_); |
} |
- bool UpdateExpectations(int property_index, Expectations& expectations) { |
+ void UpdateExpectations(int property_index, Expectations& expectations) { |
// Two branches are "compatible" so the |map1| should NOT be deprecated. |
- return false; |
} |
}; |
@@ -1435,6 +1498,37 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) { |
} |
+TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) { |
+ CcTest::InitializeVM(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ |
+ struct TestConfig { |
+ Handle<AccessorPair> pair_; |
+ TestConfig() { pair_ = CreateAccessorPair(true, true); } |
+ |
+ Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations, |
+ Handle<Map> map) { |
+ CHECK(branch_id == 1 || branch_id == 2); |
+ if (branch_id == 1) { |
+ return expectations.AddAccessorConstant(map, NONE, pair_); |
+ } else { |
+ Isolate* isolate = CcTest::i_isolate(); |
+ Handle<HeapType> any_type = HeapType::Any(isolate); |
+ return expectations.AddDataField(map, NONE, Representation::Smi(), |
+ any_type); |
+ } |
+ } |
+ |
+ void UpdateExpectations(int property_index, Expectations& expectations) {} |
+ }; |
+ |
+ TestConfig config; |
+ // These are completely separate branches in transition tree. |
+ CheckUnrelated checker; |
+ TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); |
+} |
+ |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// A set of tests checking split map deprecation. |
// |
@@ -1486,6 +1580,7 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) { |
// transition tree. |
CHECK(map->is_deprecated()); |
CHECK(!split_map->is_deprecated()); |
+ CHECK(map2->is_stable()); |
CHECK(!map2->is_deprecated()); |
// Fill in transition tree of |map2| so that it can't have more transitions. |
@@ -1931,7 +2026,8 @@ struct FieldGeneralizationChecker { |
Handle<Map> updated_map = Map::Update(map1); |
CHECK_EQ(*map2, *updated_map); |
- expectations2.SetDataField(descriptor_, representation_, heap_type_); |
+ expectations2.SetDataField(descriptor_, attributes_, representation_, |
+ heap_type_); |
CHECK(expectations2.Check(*map2)); |
} |
}; |