@@ -437,9 +437,9 @@ TEST(ReconfigureAccessorToNonExistingDataField) {
437437
438438 Handle<Map> new_map = Map::ReconfigureProperty (
439439 map, 0 , kData , NONE, Representation::None (), none_type, FORCE_FIELD);
440- // |map| did not change.
440+ // |map| did not change except marked unstable .
441441 CHECK (!map->is_deprecated ());
442- CHECK (map->is_stable ());
442+ CHECK (! map->is_stable ());
443443 CHECK (expectations.Check (*map));
444444
445445 expectations.SetDataField (0 , NONE, Representation::None (), none_type);
@@ -601,19 +601,22 @@ static void TestGeneralizeRepresentation(
601601 CHECK (expectations.Check (*new_map));
602602
603603 if (is_detached_map) {
604+ CHECK (!map->is_stable ());
604605 CHECK (map->is_deprecated ());
605606 CHECK_NE (*map, *new_map);
606607 CHECK_EQ (expected_field_type_dependency && !field_owner->is_deprecated (),
607608 info.dependencies ()->HasAborted ());
608609
609610 } else if (expected_deprecation) {
611+ CHECK (!map->is_stable ());
610612 CHECK (map->is_deprecated ());
611613 CHECK (field_owner->is_deprecated ());
612614 CHECK_NE (*map, *new_map);
613615 CHECK (!info.dependencies ()->HasAborted ());
614616
615617 } else {
616618 CHECK (!field_owner->is_deprecated ());
619+ CHECK (map->is_stable ()); // Map did not change, must be left stable.
617620 CHECK_EQ (*map, *new_map);
618621
619622 CHECK_EQ (expected_field_type_dependency, info.dependencies ()->HasAborted ());
@@ -654,6 +657,12 @@ static void TestGeneralizeRepresentation(
654657 to_type, expected_representation, expected_type, expected_deprecation,
655658 expected_field_type_dependency);
656659 }
660+
661+ // Check that reconfiguration to the very same field works correctly.
662+ Representation representation = from_representation;
663+ Handle<HeapType> type = from_type;
664+ TestGeneralizeRepresentation (-1 , 2 , representation, type, representation,
665+ type, representation, type, false , false );
657666 }
658667}
659668
@@ -877,6 +886,7 @@ TEST(GeneralizeRepresentationWithAccessorProperties) {
877886
878887 expectations.SetDataField (i, Representation::Double (), any_type);
879888
889+ CHECK (!map->is_stable ());
880890 CHECK (map->is_deprecated ());
881891 CHECK_NE (*map, *new_map);
882892 CHECK (i == 0 || maps[i - 1 ]->is_deprecated ());
@@ -962,7 +972,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
962972 Handle<Map> new_map =
963973 Map::ReconfigureExistingProperty (map2, kSplitProp , kData , NONE);
964974
965- // |map2| should be left unchanged.
975+ // |map2| should be left unchanged but marked unstable.
976+ CHECK (!map2->is_stable ());
966977 CHECK (!map2->is_deprecated ());
967978 CHECK_NE (*map2, *new_map);
968979 CHECK (expectations2.Check (*map2));
@@ -1047,7 +1058,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
10471058 Handle<Map> new_map =
10481059 Map::ReconfigureExistingProperty (map2, kSplitProp , kData , NONE);
10491060
1050- // |map2| should be left unchanged.
1061+ // |map2| should be left unchanged but marked unstable.
1062+ CHECK (!map2->is_stable ());
10511063 CHECK (!map2->is_deprecated ());
10521064 CHECK_NE (*map2, *new_map);
10531065 CHECK (expectations2.Check (*map2));
@@ -1183,6 +1195,8 @@ struct CheckDeprecated {
11831195struct CheckSameMap {
11841196 void Check (Handle<Map> map, Handle<Map> new_map,
11851197 const Expectations& expectations) {
1198+ // |map| was not reconfigured, therefore it should stay stable.
1199+ CHECK (map->is_stable ());
11861200 CHECK (!map->is_deprecated ());
11871201 CHECK_EQ (*map, *new_map);
11881202
@@ -1196,6 +1210,21 @@ struct CheckSameMap {
11961210};
11971211
11981212
1213+ // Checks that given |map| is NOT deprecated and matches expectations.
1214+ // |new_map| is unrelated to |map|.
1215+ struct CheckUnrelated {
1216+ void Check (Handle<Map> map, Handle<Map> new_map,
1217+ const Expectations& expectations) {
1218+ CHECK (!map->is_deprecated ());
1219+ CHECK_NE (*map, *new_map);
1220+ CHECK (expectations.Check (*map));
1221+
1222+ CHECK (new_map->is_stable ());
1223+ CHECK (!new_map->is_deprecated ());
1224+ }
1225+ };
1226+
1227+
11991228// Checks that given |map| is NOT deprecated, and |new_map| is a result of
12001229// copy-generalize-all-representations.
12011230struct CheckCopyGeneralizeAllRepresentations {
@@ -1289,7 +1318,8 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap(
12891318 Handle<Map> new_map =
12901319 Map::ReconfigureExistingProperty (map2, kSplitProp , kData , NONE);
12911320
1292- // |map2| should be left unchanged.
1321+ // |map2| should be left unchanged but marked unstable.
1322+ CHECK (!map2->is_stable ());
12931323 CHECK (!map2->is_deprecated ());
12941324 CHECK_NE (*map2, *new_map);
12951325 CHECK (expectations2.Check (*map2));
@@ -1366,6 +1396,40 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) {
13661396}
13671397
13681398
1399+ TEST (ReconfigureDataFieldAttribute_DataConstantToAccConstantAfterTargetMap) {
1400+ CcTest::InitializeVM ();
1401+ v8::HandleScope scope (CcTest::isolate ());
1402+
1403+ struct TestConfig {
1404+ Handle<JSFunction> js_func_;
1405+ Handle<AccessorPair> pair_;
1406+ TestConfig () {
1407+ Isolate* isolate = CcTest::i_isolate ();
1408+ Factory* factory = isolate->factory ();
1409+ js_func_ = factory->NewFunction (factory->empty_string ());
1410+ pair_ = CreateAccessorPair (true , true );
1411+ }
1412+
1413+ Handle<Map> AddPropertyAtBranch (int branch_id, Expectations& expectations,
1414+ Handle<Map> map) {
1415+ CHECK (branch_id == 1 || branch_id == 2 );
1416+ if (branch_id == 1 ) {
1417+ return expectations.AddDataConstant (map, NONE, js_func_);
1418+ } else {
1419+ return expectations.AddAccessorConstant (map, NONE, pair_);
1420+ }
1421+ }
1422+
1423+ void UpdateExpectations (int property_index, Expectations& expectations) {}
1424+ };
1425+
1426+ TestConfig config;
1427+ // These are completely separate branches in transition tree.
1428+ CheckUnrelated checker;
1429+ TestReconfigureProperty_CustomPropertyAfterTargetMap (config, checker);
1430+ }
1431+
1432+
13691433TEST (ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) {
13701434 CcTest::InitializeVM ();
13711435 v8::HandleScope scope (CcTest::isolate ());
@@ -1382,9 +1446,8 @@ TEST(ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) {
13821446 return expectations.AddAccessorConstant (map, NONE, pair_);
13831447 }
13841448
1385- bool UpdateExpectations (int property_index, Expectations& expectations) {
1449+ void UpdateExpectations (int property_index, Expectations& expectations) {
13861450 // Two branches are "compatible" so the |map1| should NOT be deprecated.
1387- return false ;
13881451 }
13891452 };
13901453
@@ -1436,6 +1499,37 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) {
14361499}
14371500
14381501
1502+ TEST (ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) {
1503+ CcTest::InitializeVM ();
1504+ v8::HandleScope scope (CcTest::isolate ());
1505+
1506+ struct TestConfig {
1507+ Handle<AccessorPair> pair_;
1508+ TestConfig () { pair_ = CreateAccessorPair (true , true ); }
1509+
1510+ Handle<Map> AddPropertyAtBranch (int branch_id, Expectations& expectations,
1511+ Handle<Map> map) {
1512+ CHECK (branch_id == 1 || branch_id == 2 );
1513+ if (branch_id == 1 ) {
1514+ return expectations.AddAccessorConstant (map, NONE, pair_);
1515+ } else {
1516+ Isolate* isolate = CcTest::i_isolate ();
1517+ Handle<HeapType> any_type = HeapType::Any (isolate);
1518+ return expectations.AddDataField (map, NONE, Representation::Smi (),
1519+ any_type);
1520+ }
1521+ }
1522+
1523+ void UpdateExpectations (int property_index, Expectations& expectations) {}
1524+ };
1525+
1526+ TestConfig config;
1527+ // These are completely separate branches in transition tree.
1528+ CheckUnrelated checker;
1529+ TestReconfigureProperty_CustomPropertyAfterTargetMap (config, checker);
1530+ }
1531+
1532+
14391533// //////////////////////////////////////////////////////////////////////////////
14401534// A set of tests checking split map deprecation.
14411535//
@@ -1487,6 +1581,7 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
14871581 // transition tree.
14881582 CHECK (map->is_deprecated ());
14891583 CHECK (!split_map->is_deprecated ());
1584+ CHECK (map2->is_stable ());
14901585 CHECK (!map2->is_deprecated ());
14911586
14921587 // Fill in transition tree of |map2| so that it can't have more transitions.
@@ -1932,7 +2027,8 @@ struct FieldGeneralizationChecker {
19322027 Handle<Map> updated_map = Map::Update (map1);
19332028 CHECK_EQ (*map2, *updated_map);
19342029
1935- expectations2.SetDataField (descriptor_, representation_, heap_type_);
2030+ expectations2.SetDataField (descriptor_, attributes_, representation_,
2031+ heap_type_);
19362032 CHECK (expectations2.Check (*map2));
19372033 }
19382034};
0 commit comments