@@ -121,6 +121,41 @@ Handle<Map> MapUpdater::ReconfigureToDataField(InternalIndex descriptor,
121121 PropertyDetails old_details =
122122 old_descriptors_->GetDetails (modified_descriptor_);
123123
124+ // If the {descriptor} was "const" data field so far, we need to update the
125+ // {old_map_} here, otherwise we could get the constants wrong, i.e.
126+ //
127+ // o.x = 1;
128+ // change o.x's attributes to something else
129+ // delete o.x;
130+ // o.x = 2;
131+ //
132+ // could trick V8 into thinking that `o.x` is still 1 even after the second
133+ // assignment.
134+ // This situation is similar to what might happen with property deletion.
135+ if (old_details.constness () == PropertyConstness::kConst &&
136+ old_details.location () == kField &&
137+ old_details.attributes () != new_attributes_) {
138+ Handle<FieldType> field_type (
139+ old_descriptors_->GetFieldType (modified_descriptor_), isolate_);
140+ Map::GeneralizeField (isolate_, old_map_, descriptor,
141+ PropertyConstness::kMutable ,
142+ old_details.representation (), field_type);
143+ // The old_map_'s property must become mutable.
144+ // Note, that the {old_map_} and {old_descriptors_} are not expected to be
145+ // updated by the generalization if the map is already deprecated.
146+ DCHECK_IMPLIES (
147+ !old_map_->is_deprecated (),
148+ PropertyConstness::kMutable ==
149+ old_descriptors_->GetDetails (modified_descriptor_).constness ());
150+ // Although the property in the old map is marked as mutable we still
151+ // treat it as constant when merging with the new path in transition tree.
152+ // This is fine because up until this reconfiguration the field was
153+ // known to be constant, so it's fair to proceed treating it as such
154+ // during this reconfiguration session. The issue is that after the
155+ // reconfiguration the original field might become mutable (see the delete
156+ // example above).
157+ }
158+
124159 // If property kind is not reconfigured merge the result with
125160 // representation/field type from the old descriptor.
126161 if (old_details.kind () == new_kind_) {
0 commit comments