From 7325d4ae980b20d58625ba20f4669a8cd00a795f Mon Sep 17 00:00:00 2001 From: Leszek Swirski Date: Wed, 19 Jun 2019 11:54:03 +0200 Subject: [PATCH] [ic] Replace CopyGeneralize with Normalize Rather than starting a new, orphaned transition tree in various bailout cases, simply drop down into dictionary mode. Aside from potential memory benefits, this allows us to remove CopyGeneralizeAllFields, which was the only path along which fields could end up in a different order than their descriptors. Change-Id: I5577e8a1ca51f0ffdadd7504e7895f367605aa27 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1662298 Commit-Queue: Leszek Swirski Reviewed-by: Igor Sheludko Cr-Commit-Position: refs/heads/master@{#62279} --- src/diagnostics/objects-debug.cc | 6 +- src/objects/js-objects.cc | 3 +- src/objects/lookup.cc | 15 +++-- src/objects/map-inl.h | 10 +++ src/objects/map-updater.cc | 27 ++++---- src/objects/map-updater.h | 5 +- src/objects/map.cc | 85 ++++++------------------- src/objects/map.h | 23 +++---- test/cctest/test-field-type-tracking.cc | 62 +++++++++--------- 9 files changed, 106 insertions(+), 130 deletions(-) diff --git a/src/diagnostics/objects-debug.cc b/src/diagnostics/objects-debug.cc index 8f40cf4fc0..aba1a541a3 100644 --- a/src/diagnostics/objects-debug.cc +++ b/src/diagnostics/objects-debug.cc @@ -799,7 +799,9 @@ void DescriptorArray::DescriptorArrayVerify(Isolate* isolate) { CHECK_LT(0, number_of_all_descriptors()); CHECK_LE(number_of_descriptors(), number_of_all_descriptors()); - // Check that properties with private symbols names are non-enumerable. + // Check that properties with private symbols names are non-enumerable, and + // that fields are in order. + int expected_field_index = 0; for (int descriptor = 0; descriptor < number_of_descriptors(); descriptor++) { Object key = *(GetDescriptorSlot(descriptor) + kEntryKeyIndex); @@ -813,11 +815,13 @@ void DescriptorArray::DescriptorArrayVerify(Isolate* isolate) { MaybeObject value = GetValue(descriptor); HeapObject heap_object; if (details.location() == kField) { + CHECK_EQ(details.field_index(), expected_field_index); CHECK( value == MaybeObject::FromObject(FieldType::None()) || value == MaybeObject::FromObject(FieldType::Any()) || value->IsCleared() || (value->GetHeapObjectIfWeak(&heap_object) && heap_object.IsMap())); + expected_field_index += details.field_width_in_words(); } else { CHECK(!value->IsWeakOrCleared()); CHECK(!value->cast().IsMap()); diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc index 8c7f32ebf7..0ddd60233d 100644 --- a/src/objects/js-objects.cc +++ b/src/objects/js-objects.cc @@ -3267,7 +3267,8 @@ void JSObject::NormalizeProperties(Isolate* isolate, Handle object, if (!object->HasFastProperties()) return; Handle map(object->map(), isolate); - Handle new_map = Map::Normalize(isolate, map, mode, reason); + Handle new_map = + Map::Normalize(isolate, map, map->elements_kind(), mode, reason); JSObject::MigrateToMap(isolate, object, new_map, expected_additional_properties); diff --git a/src/objects/lookup.cc b/src/objects/lookup.cc index 0334da3205..889e8bb470 100644 --- a/src/objects/lookup.cc +++ b/src/objects/lookup.cc @@ -525,13 +525,18 @@ void LookupIterator::ReconfigureDataProperty(Handle value, ReloadPropertyInformation(); } else if (holder_obj->HasFastProperties()) { Handle old_map(holder_obj->map(), isolate_); - Handle new_map = Map::ReconfigureExistingProperty( - isolate_, old_map, descriptor_number(), i::kData, attributes); // Force mutable to avoid changing constant value by reconfiguring // kData -> kAccessor -> kData. - new_map = - Map::PrepareForDataProperty(isolate(), new_map, descriptor_number(), - PropertyConstness::kMutable, value); + Handle new_map = Map::ReconfigureExistingProperty( + isolate_, old_map, descriptor_number(), i::kData, attributes, + PropertyConstness::kMutable); + if (!new_map->is_dictionary_map()) { + // Make sure that the data property has a compatible representation. + // TODO(leszeks): Do this as part of ReconfigureExistingProperty. + new_map = + Map::PrepareForDataProperty(isolate(), new_map, descriptor_number(), + PropertyConstness::kMutable, value); + } JSObject::MigrateToMap(isolate_, holder_obj, new_map); ReloadPropertyInformation(); } diff --git a/src/objects/map-inl.h b/src/objects/map-inl.h index 6546846c42..14b7c2c0d4 100644 --- a/src/objects/map-inl.h +++ b/src/objects/map-inl.h @@ -132,6 +132,16 @@ void Map::GeneralizeIfCanHaveTransitionableFastElementsKind( } } +Handle Map::Normalize(Isolate* isolate, Handle fast_map, + PropertyNormalizationMode mode, const char* reason) { + return Normalize(isolate, fast_map, fast_map->elements_kind(), mode, reason); +} + +bool Map::EquivalentToForNormalization(const Map other, + PropertyNormalizationMode mode) const { + return EquivalentToForNormalization(other, elements_kind(), mode); +} + bool Map::IsUnboxedDoubleField(FieldIndex index) const { if (!FLAG_unbox_double_fields) return false; if (!index.is_inobject()) return false; diff --git a/src/objects/map-updater.cc b/src/objects/map-updater.cc index 855fdabdf3..d21f0e1a12 100644 --- a/src/objects/map-updater.cc +++ b/src/objects/map-updater.cc @@ -201,10 +201,9 @@ void MapUpdater::GeneralizeField(Handle map, int modify_index, *old_descriptors_ == integrity_source_map_->instance_descriptors()); } -MapUpdater::State MapUpdater::CopyGeneralizeAllFields(const char* reason) { - result_map_ = Map::CopyGeneralizeAllFields( - isolate_, old_map_, new_elements_kind_, modified_descriptor_, new_kind_, - new_attributes_, reason); +MapUpdater::State MapUpdater::Normalize(const char* reason) { + result_map_ = Map::Normalize(isolate_, old_map_, new_elements_kind_, + CLEAR_INOBJECT_PROPERTIES, reason); state_ = kEnd; return state_; // Done. } @@ -310,14 +309,14 @@ MapUpdater::State MapUpdater::FindRootMap() { } if (!old_map_->EquivalentToForTransition(*root_map_)) { - return CopyGeneralizeAllFields("GenAll_NotEquivalent"); + return Normalize("Normalize_NotEquivalent"); } else if (old_map_->is_extensible() != root_map_->is_extensible()) { DCHECK(!old_map_->is_extensible()); DCHECK(root_map_->is_extensible()); // We have an integrity level transition in the tree, let us make a note // of that transition to be able to replay it later. if (!TrySaveIntegrityLevelTransitions()) { - return CopyGeneralizeAllFields("GenAll_PrivateSymbolsOnNonExtensible"); + return Normalize("Normalize_PrivateSymbolsOnNonExtensible"); } // We want to build transitions to the original element kind (before @@ -335,7 +334,7 @@ MapUpdater::State MapUpdater::FindRootMap() { to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && !(IsTransitionableFastElementsKind(from_kind) && IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { - return CopyGeneralizeAllFields("GenAll_InvalidElementsTransition"); + return Normalize("Normalize_InvalidElementsTransition"); } int root_nof = root_map_->NumberOfOwnDescriptors(); @@ -344,13 +343,13 @@ MapUpdater::State MapUpdater::FindRootMap() { old_descriptors_->GetDetails(modified_descriptor_); if (old_details.kind() != new_kind_ || old_details.attributes() != new_attributes_) { - return CopyGeneralizeAllFields("GenAll_RootModification1"); + return Normalize("Normalize_RootModification1"); } if (old_details.location() != kField) { - return CopyGeneralizeAllFields("GenAll_RootModification2"); + return Normalize("Normalize_RootModification2"); } if (!new_representation_.fits_into(old_details.representation())) { - return CopyGeneralizeAllFields("GenAll_RootModification4"); + return Normalize("Normalize_RootModification4"); } DCHECK_EQ(kData, old_details.kind()); @@ -394,7 +393,7 @@ MapUpdater::State MapUpdater::FindTargetMap() { !EqualImmutableValues(GetValue(i), tmp_descriptors->GetStrongValue(i))) { // TODO(ishell): mutable accessors are not implemented yet. - return CopyGeneralizeAllFields("GenAll_Incompatible"); + return Normalize("Normalize_Incompatible"); } if (!IsGeneralizableTo(old_details.location(), tmp_details.location())) { break; @@ -484,7 +483,7 @@ MapUpdater::State MapUpdater::FindTargetMap() { if (old_details.kind() == kAccessor && !EqualImmutableValues(GetValue(i), tmp_descriptors->GetStrongValue(i))) { - return CopyGeneralizeAllFields("GenAll_Incompatible"); + return Normalize("Normalize_Incompatible"); } DCHECK(!tmp_map->is_deprecated()); target_map_ = tmp_map; @@ -723,7 +722,7 @@ MapUpdater::State MapUpdater::ConstructNewMap() { // contains entry for given descriptor. This means that the transition // could be inserted regardless of whether transitions array is full or not. if (maybe_transition.is_null() && !transitions.CanHaveMoreTransitions()) { - return CopyGeneralizeAllFields("GenAll_CantHaveMoreTransitions"); + return Normalize("Normalize_CantHaveMoreTransitions"); } old_map_->NotifyLeafMapLayoutChange(isolate_); @@ -787,7 +786,7 @@ MapUpdater::State MapUpdater::ConstructNewMapWithIntegrityLevelTransition() { TransitionsAccessor transitions(isolate_, target_map_); if (!transitions.CanHaveMoreTransitions()) { - return CopyGeneralizeAllFields("GenAll_CantHaveMoreTransitions"); + return Normalize("Normalize_CantHaveMoreTransitions"); } result_map_ = Map::CopyForPreventExtensions( diff --git a/src/objects/map-updater.h b/src/objects/map-updater.h index 3ba86eacbc..6ee373cbdf 100644 --- a/src/objects/map-updater.h +++ b/src/objects/map-updater.h @@ -123,9 +123,8 @@ class MapUpdater { State ConstructNewMapWithIntegrityLevelTransition(); // When a requested reconfiguration can not be done the result is a copy - // of |old_map_| where every field has |Tagged| representation and |Any| - // field type. This map is disconnected from the transition tree. - State CopyGeneralizeAllFields(const char* reason); + // of |old_map_| in dictionary mode. + State Normalize(const char* reason); // Returns name of a |descriptor| property. inline Name GetKey(int descriptor) const; diff --git a/src/objects/map.cc b/src/objects/map.cc index 6e5a820ed7..53bc4470b6 100644 --- a/src/objects/map.cc +++ b/src/objects/map.cc @@ -570,61 +570,6 @@ bool Map::HasOutOfObjectProperties() const { return GetInObjectProperties() < NumberOfFields(); } -Handle Map::CopyGeneralizeAllFields(Isolate* isolate, Handle map, - ElementsKind elements_kind, - int modify_index, PropertyKind kind, - PropertyAttributes attributes, - const char* reason) { - Handle old_descriptors(map->instance_descriptors(), isolate); - int number_of_own_descriptors = map->NumberOfOwnDescriptors(); - Handle descriptors = DescriptorArray::CopyUpTo( - isolate, old_descriptors, number_of_own_descriptors); - descriptors->GeneralizeAllFields(); - - Handle new_layout_descriptor( - LayoutDescriptor::FastPointerLayout(), isolate); - Handle new_map = CopyReplaceDescriptors( - isolate, map, descriptors, new_layout_descriptor, OMIT_TRANSITION, - MaybeHandle(), reason, SPECIAL_TRANSITION); - - // Unless the instance is being migrated, ensure that modify_index is a field. - if (modify_index >= 0) { - PropertyDetails details = descriptors->GetDetails(modify_index); - if (details.constness() != PropertyConstness::kMutable || - details.location() != kField || details.attributes() != attributes) { - int field_index = details.location() == kField - ? details.field_index() - : new_map->NumberOfFields(); - Descriptor d = Descriptor::DataField( - isolate, handle(descriptors->GetKey(modify_index), isolate), - field_index, attributes, Representation::Tagged()); - descriptors->Replace(modify_index, &d); - if (details.location() != kField) { - new_map->AccountAddedPropertyField(); - } - } else { - DCHECK(details.attributes() == attributes); - } - - if (FLAG_trace_generalization) { - MaybeHandle field_type = FieldType::None(isolate); - if (details.location() == kField) { - field_type = handle( - map->instance_descriptors().GetFieldType(modify_index), isolate); - } - map->PrintGeneralization( - isolate, stdout, reason, modify_index, - new_map->NumberOfOwnDescriptors(), new_map->NumberOfOwnDescriptors(), - details.location() == kDescriptor, details.representation(), - Representation::Tagged(), details.constness(), details.constness(), - field_type, MaybeHandle(), FieldType::Any(isolate), - MaybeHandle()); - } - } - new_map->set_elements_kind(elements_kind); - return new_map; -} - void Map::DeprecateTransitionTree(Isolate* isolate) { if (is_deprecated()) return; DisallowHeapAllocation no_gc; @@ -1477,6 +1422,7 @@ Handle Map::RawCopy(Isolate* isolate, Handle map, int instance_size, } Handle Map::Normalize(Isolate* isolate, Handle fast_map, + ElementsKind new_elements_kind, PropertyNormalizationMode mode, const char* reason) { DCHECK(!fast_map->is_dictionary_map()); @@ -1488,7 +1434,8 @@ Handle Map::Normalize(Isolate* isolate, Handle fast_map, if (use_cache) cache = Handle::cast(maybe_cache); Handle new_map; - if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) { + if (use_cache && + cache->Get(fast_map, new_elements_kind, mode).ToHandle(&new_map)) { #ifdef VERIFY_HEAP if (FLAG_verify_heap) new_map->DictionaryMapVerify(isolate); #endif @@ -1498,6 +1445,7 @@ Handle Map::Normalize(Isolate* isolate, Handle fast_map, // except for the code cache, which can contain some ICs which can be // applied to the shared map, dependent code and weak cell cache. Handle fresh = Map::CopyNormalized(isolate, fast_map, mode); + fresh->set_elements_kind(new_elements_kind); STATIC_ASSERT(Map::kPrototypeValidityCellOffset == Map::kDependentCodeOffset + kTaggedSize); @@ -1529,6 +1477,7 @@ Handle Map::Normalize(Isolate* isolate, Handle fast_map, #endif } else { new_map = Map::CopyNormalized(isolate, fast_map, mode); + new_map->set_elements_kind(new_elements_kind); if (use_cache) { cache->Set(fast_map, new_map); isolate->counters()->maps_normalized()->Increment(); @@ -2203,16 +2152,16 @@ Handle Map::TransitionToDataProperty(Isolate* isolate, Handle map, Handle Map::ReconfigureExistingProperty(Isolate* isolate, Handle map, int descriptor, PropertyKind kind, - PropertyAttributes attributes) { + PropertyAttributes attributes, + PropertyConstness constness) { // Dictionaries have to be reconfigured in-place. DCHECK(!map->is_dictionary_map()); if (!map->GetBackPointer().IsMap()) { // There is no benefit from reconstructing transition tree for maps without - // back pointers. - return CopyGeneralizeAllFields(isolate, map, map->elements_kind(), - descriptor, kind, attributes, - "GenAll_AttributesMismatchProtoMap"); + // back pointers, normalize and try to hit the map cache instead. + return Map::Normalize(isolate, map, CLEAR_INOBJECT_PROPERTIES, + "Normalize_AttributesMismatchProtoMap"); } if (FLAG_trace_generalization) { @@ -2222,7 +2171,7 @@ Handle Map::ReconfigureExistingProperty(Isolate* isolate, Handle map, MapUpdater mu(isolate, map); DCHECK_EQ(kData, kind); // Only kData case is supported so far. Handle new_map = mu.ReconfigureToDataField( - descriptor, attributes, PropertyConstness::kConst, Representation::None(), + descriptor, attributes, constness, Representation::None(), FieldType::None(isolate)); return new_map; } @@ -2474,10 +2423,16 @@ bool Map::EquivalentToForElementsKindTransition(const Map other) const { } bool Map::EquivalentToForNormalization(const Map other, + ElementsKind elements_kind, PropertyNormalizationMode mode) const { int properties = mode == CLEAR_INOBJECT_PROPERTIES ? 0 : other.GetInObjectProperties(); - return CheckEquivalent(*this, other) && bit_field2() == other.bit_field2() && + // Make sure the elements_kind bits are in bit_field2. + DCHECK_EQ(this->elements_kind(), Map::ElementsKindBits::decode(bit_field2())); + int adjusted_bit_field2 = + Map::ElementsKindBits::update(bit_field2(), elements_kind); + return CheckEquivalent(*this, other) && + adjusted_bit_field2 == other.bit_field2() && GetInObjectProperties() == properties && JSObject::GetEmbedderFieldCount(*this) == JSObject::GetEmbedderFieldCount(other); @@ -2668,6 +2623,7 @@ Handle NormalizedMapCache::New(Isolate* isolate) { } MaybeHandle NormalizedMapCache::Get(Handle fast_map, + ElementsKind elements_kind, PropertyNormalizationMode mode) { DisallowHeapAllocation no_gc; MaybeObject value = WeakFixedArray::Get(GetIndex(fast_map)); @@ -2677,7 +2633,8 @@ MaybeHandle NormalizedMapCache::Get(Handle fast_map, } Map normalized_map = Map::cast(heap_object); - if (!normalized_map.EquivalentToForNormalization(*fast_map, mode)) { + if (!normalized_map.EquivalentToForNormalization(*fast_map, elements_kind, + mode)) { return MaybeHandle(); } return handle(normalized_map, GetIsolate()); diff --git a/src/objects/map.h b/src/objects/map.h index eebf2f553a..2e9ae179a8 100644 --- a/src/objects/map.h +++ b/src/objects/map.h @@ -542,9 +542,14 @@ class Map : public HeapObject { V8_EXPORT_PRIVATE static Handle Normalize(Isolate* isolate, Handle map, + ElementsKind new_elements_kind, PropertyNormalizationMode mode, const char* reason); + inline static Handle Normalize(Isolate* isolate, Handle fast_map, + PropertyNormalizationMode mode, + const char* reason); + // Tells whether the map is used for JSObjects in dictionary mode (ie // normalized objects, ie objects for which HasFastProperties returns false). // A map can never be used for both dictionary mode and fast mode JSObjects. @@ -739,7 +744,7 @@ class Map : public HeapObject { PropertyAttributes attributes); V8_EXPORT_PRIVATE static Handle ReconfigureExistingProperty( Isolate* isolate, Handle map, int descriptor, PropertyKind kind, - PropertyAttributes attributes); + PropertyAttributes attributes, PropertyConstness constness); inline void AppendDescriptor(Isolate* isolate, Descriptor* desc); @@ -833,12 +838,15 @@ class Map : public HeapObject { class BodyDescriptor; - // Compares this map to another to see if they describe equivalent objects. + // Compares this map to another to see if they describe equivalent objects, + // up to the given |elements_kind|. // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if // it had exactly zero inobject properties. // The "shared" flags of both this map and |other| are ignored. - bool EquivalentToForNormalization(const Map other, + bool EquivalentToForNormalization(const Map other, ElementsKind elements_kind, PropertyNormalizationMode mode) const; + inline bool EquivalentToForNormalization( + const Map other, PropertyNormalizationMode mode) const; // Returns true if given field is unboxed double. inline bool IsUnboxedDoubleField(FieldIndex index) const; @@ -929,14 +937,6 @@ class Map : public HeapObject { static Handle CopyNormalized(Isolate* isolate, Handle map, PropertyNormalizationMode mode); - // TODO(ishell): Move to MapUpdater. - static Handle CopyGeneralizeAllFields(Isolate* isolate, Handle map, - ElementsKind elements_kind, - int modify_index, - PropertyKind kind, - PropertyAttributes attributes, - const char* reason); - void DeprecateTransitionTree(Isolate* isolate); void ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors, @@ -983,6 +983,7 @@ class NormalizedMapCache : public WeakFixedArray { static Handle New(Isolate* isolate); V8_WARN_UNUSED_RESULT MaybeHandle Get(Handle fast_map, + ElementsKind elements_kind, PropertyNormalizationMode mode); void Set(Handle fast_map, Handle normalized_map); diff --git a/test/cctest/test-field-type-tracking.cc b/test/cctest/test-field-type-tracking.cc index fdb030562e..b847477822 100644 --- a/test/cctest/test-field-type-tracking.cc +++ b/test/cctest/test-field-type-tracking.cc @@ -306,6 +306,14 @@ class Expectations { bool Check(Map map) const { return Check(map, number_of_properties_); } + bool CheckNormalized(Map map) const { + CHECK(map.is_dictionary_map()); + CHECK_EQ(elements_kind_, map.elements_kind()); + // TODO(leszeks): Iterate over the key/value pairs of the map and compare + // them against the expected fields. + return true; + } + // // Helper methods for initializing expectations and adding properties to // given |map|. @@ -1053,8 +1061,8 @@ void TestReconfigureDataFieldAttribute_GeneralizeField( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle new_map = - Map::ReconfigureExistingProperty(isolate, map2, kSplitProp, kData, NONE); + Handle new_map = Map::ReconfigureExistingProperty( + isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1141,8 +1149,8 @@ void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle new_map = - Map::ReconfigureExistingProperty(isolate, map2, kSplitProp, kData, NONE); + Handle new_map = Map::ReconfigureExistingProperty( + isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1399,22 +1407,17 @@ struct CheckUnrelated { } }; - -// Checks that given |map| is NOT deprecated, and |new_map| is a result of -// copy-generalize-all-representations. -struct CheckCopyGeneralizeAllFields { +// Checks that given |map| is NOT deprecated, and |new_map| is a result of going +// dictionary mode. +struct CheckNormalize { void Check(Isolate* isolate, Handle map, Handle new_map, - Expectations& expectations) { + const Expectations& expectations) { CHECK(!map->is_deprecated()); CHECK_NE(*map, *new_map); CHECK(new_map->GetBackPointer().IsUndefined(isolate)); - for (int i = 0; i < kPropCount; i++) { - expectations.GeneralizeField(i); - } - CHECK(!new_map->is_deprecated()); - CHECK(expectations.Check(*new_map)); + CHECK(expectations.CheckNormalized(*new_map)); } }; @@ -1497,8 +1500,8 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle new_map = - Map::ReconfigureExistingProperty(isolate, map2, kSplitProp, kData, NONE); + Handle new_map = Map::ReconfigureExistingProperty( + isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1671,8 +1674,8 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) { if (IS_ACCESSOR_FIELD_SUPPORTED) { expectations.SetAccessorField(property_index); } else { - // Currently we have a copy-generalize-all-representations case and - // ACCESSOR property becomes ACCESSOR_CONSTANT. + // Currently we have a normalize case and ACCESSOR property becomes + // ACCESSOR_CONSTANT. expectations.SetAccessorConstant(property_index, pair2_); } } @@ -1680,11 +1683,11 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) { TestConfig config; if (IS_ACCESSOR_FIELD_SUPPORTED) { - CheckCopyGeneralizeAllFields checker; + CheckSameMap checker; TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); } else { - // Currently we have a copy-generalize-all-representations case. - CheckCopyGeneralizeAllFields checker; + // Currently we have a normalize case. + CheckNormalize checker; TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); } } @@ -2083,18 +2086,13 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) { CHECK(!TransitionsAccessor(isolate, map2).CanHaveMoreTransitions()); // Try to update |map|, since there is no place for propX transition at |map2| - // |map| should become "copy-generalized". + // |map| should become normalized. Handle updated_map = Map::Update(isolate, map); - CHECK(updated_map->GetBackPointer().IsUndefined(isolate)); - for (int i = 0; i < kPropCount; i++) { - expectations.SetDataField(i, PropertyConstness::kMutable, - Representation::Tagged(), any_type); - } - CHECK(expectations.Check(*updated_map)); + CheckNormalize checker; + checker.Check(isolate, map2, updated_map, expectations); } - //////////////////////////////////////////////////////////////////////////////// // A set of tests involving special transitions (such as elements kind // transition, observed transition or prototype transition). @@ -2502,7 +2500,8 @@ struct ReconfigureAsDataPropertyOperator { expectations.SetDataField(descriptor_, PropertyConstness::kMutable, representation_, heap_type_); return Map::ReconfigureExistingProperty(isolate, map, descriptor_, kData, - attributes_); + attributes_, + PropertyConstness::kConst); } }; @@ -2519,7 +2518,8 @@ struct ReconfigureAsAccessorPropertyOperator { Handle map) { expectations.SetAccessorField(descriptor_); return Map::ReconfigureExistingProperty(isolate, map, descriptor_, - kAccessor, attributes_); + kAccessor, attributes_, + PropertyConstness::kConst); } };