Skip to content

Commit db2acd7

Browse files
isheludkoCommit Bot
authored andcommitted
[const-tracking] Ensure map is updated before generalizing constness
... when reconfiguring property attributes. Bug: chromium:1195331 Change-Id: I65a29f0ad303a603207376a283e943480c4b18d2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2807608 Reviewed-by: Leszek Swirski <[email protected]> Commit-Queue: Igor Sheludko <[email protected]> Cr-Commit-Position: refs/heads/master@{#73810}
1 parent f0399fa commit db2acd7

3 files changed

Lines changed: 75 additions & 7 deletions

File tree

src/objects/map-updater.cc

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,20 @@ Handle<Map> MapUpdater::ReconfigureToDataField(InternalIndex descriptor,
143143
if (old_details.constness() == PropertyConstness::kConst &&
144144
old_details.location() == kField &&
145145
old_details.attributes() != new_attributes_) {
146+
// Ensure we'll be updating constness of the up-to-date version of old_map_.
147+
Handle<Map> old_map = UpdateMapNoLock(isolate_, old_map_);
148+
PropertyDetails details =
149+
old_map->instance_descriptors(isolate_).GetDetails(descriptor);
146150
Handle<FieldType> field_type(
147-
old_descriptors_->GetFieldType(modified_descriptor_), isolate_);
148-
Map::GeneralizeField(isolate_, old_map_, descriptor,
149-
PropertyConstness::kMutable,
150-
old_details.representation(), field_type);
151+
old_map->instance_descriptors(isolate_).GetFieldType(descriptor),
152+
isolate_);
153+
Map::GeneralizeField(isolate_, old_map, descriptor,
154+
PropertyConstness::kMutable, details.representation(),
155+
field_type);
156+
DCHECK_EQ(PropertyConstness::kMutable,
157+
old_map->instance_descriptors(isolate_)
158+
.GetDetails(descriptor)
159+
.constness());
151160
// The old_map_'s property must become mutable.
152161
// Note, that the {old_map_} and {old_descriptors_} are not expected to be
153162
// updated by the generalization if the map is already deprecated.
@@ -221,12 +230,25 @@ Handle<Map> MapUpdater::ReconfigureElementsKind(ElementsKind elements_kind) {
221230
return result_map_;
222231
}
223232

224-
Handle<Map> MapUpdater::Update() {
225-
DCHECK_EQ(kInitialized, state_);
226-
DCHECK(old_map_->is_deprecated());
233+
// static
234+
Handle<Map> MapUpdater::UpdateMapNoLock(Isolate* isolate, Handle<Map> map) {
235+
if (!map->is_deprecated()) return map;
236+
// TODO(ishell): support fast map updating if we enable it.
237+
CHECK(!FLAG_fast_map_update);
238+
MapUpdater mu(isolate, map);
239+
// Update map without locking the Isolate::map_updater_access mutex.
240+
return mu.UpdateImpl();
241+
}
227242

243+
Handle<Map> MapUpdater::Update() {
228244
base::SharedMutexGuard<base::kExclusive> mutex_guard(
229245
isolate_->map_updater_access());
246+
return UpdateImpl();
247+
}
248+
249+
Handle<Map> MapUpdater::UpdateImpl() {
250+
DCHECK_EQ(kInitialized, state_);
251+
DCHECK(old_map_->is_deprecated());
230252

231253
if (FindRootMap() == kEnd) return result_map_;
232254
if (FindTargetMap() == kEnd) return result_map_;

src/objects/map-updater.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ class V8_EXPORT_PRIVATE MapUpdater {
7676
kEnd
7777
};
7878

79+
// Updates map to the most up-to-date non-deprecated version.
80+
static inline Handle<Map> UpdateMapNoLock(Isolate* isolate,
81+
Handle<Map> old_map);
82+
83+
// Prepares for updating deprecated map to most up-to-date non-deprecated
84+
// version and performs the steps 1-6.
85+
// Unlike the Update() entry point it doesn't lock the map_updater_access
86+
// mutex.
87+
Handle<Map> UpdateImpl();
88+
7989
// Try to reconfigure property in-place without rebuilding transition tree
8090
// and creating new maps. See implementation for details.
8191
State TryReconfigureToDataFieldInplace();
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2021 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --allow-natives-syntax
6+
7+
let o1 = { a: 1, b: 0 };
8+
let o2 = { a: 2, b: 0 };
9+
assertTrue(%HaveSameMap(o1, o2));
10+
assertTrue(%HasOwnConstDataProperty(o1, "a"));
11+
assertTrue(%HasOwnConstDataProperty(o1, "b"));
12+
13+
Object.defineProperty(o1, "b", {
14+
value: 4.2, enumerable: true, configurable: true, writable: true,
15+
});
16+
assertFalse(%HaveSameMap(o1, o2));
17+
assertTrue(%HasOwnConstDataProperty(o1, "a"));
18+
assertFalse(%HasOwnConstDataProperty(o1, "b"));
19+
assertTrue(%HasOwnConstDataProperty(o2, "a"));
20+
assertTrue(%HasOwnConstDataProperty(o2, "b"));
21+
22+
let o3 = { a: "foo", b: 0 };
23+
assertFalse(%HaveSameMap(o2, o3));
24+
assertTrue(%HasOwnConstDataProperty(o3, "a"));
25+
assertFalse(%HasOwnConstDataProperty(o3, "b"));
26+
27+
Object.defineProperty(o2, "a", {
28+
value:2, enumerable: false, configurable: true, writable: true,
29+
});
30+
assertFalse(%HasOwnConstDataProperty(o1, "a"));
31+
assertFalse(%HasOwnConstDataProperty(o1, "b"));
32+
assertFalse(%HasOwnConstDataProperty(o3, "a"));
33+
assertFalse(%HasOwnConstDataProperty(o3, "b"));
34+
35+
assertFalse(%HasOwnConstDataProperty(o2, "a"));
36+
assertTrue(%HasOwnConstDataProperty(o2, "b"));

0 commit comments

Comments
 (0)