[keys] Fix dictionary-mode prototype invalidation

When the enumerability flag is flipped we need to invalidate the
prototype info.

Bug: chromium:1163499
Change-Id: Iceeaa5fc47eebfe7d333c9eb594bf0763e6cef92
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2831871
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Auto-Submit: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74013}
This commit is contained in:
Toon Verwaest 2021-04-16 16:44:23 +02:00 committed by Commit Bot
parent 567f4828f3
commit bbc32bd2b5
2 changed files with 21 additions and 2 deletions

View File

@ -488,11 +488,15 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
if (!IsElement(*holder) && !holder_obj->HasFastProperties(isolate_)) {
if (holder_obj->map(isolate_).is_prototype_map() &&
(property_details_.attributes() & READ_ONLY) == 0 &&
(attributes & READ_ONLY) != 0) {
(((property_details_.attributes() & READ_ONLY) == 0 &&
(attributes & READ_ONLY) != 0) ||
(property_details_.attributes() & DONT_ENUM) !=
(attributes & DONT_ENUM))) {
// Invalidate prototype validity cell when a property is reconfigured
// from writable to read-only as this may invalidate transitioning store
// IC handlers.
// Invalidate prototype validity cell when a property changes
// enumerability to clear the prototype chain enum cache.
JSObject::InvalidatePrototypeChains(holder->map(isolate_));
}
if (holder_obj->IsJSGlobalObject(isolate_)) {

View File

@ -0,0 +1,15 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const o1 = {k:1};
const o2 = Object.create(o1);
for (let i = 0; i < 1100; i++) {
Object.defineProperty(o1, "k" + i, {value: 0, enumerable: false});
}
Object.defineProperty(o1, "enum", {value: 1, enumerable: false, configurable: true});
for (let k in o2) {}
Object.defineProperty(o1, "enum", {value: 1, enumerable: true, configurable: true});
let last;
for (let k in o2) { last = k }
assertEquals("enum", last);