Elements kind should not change after dictionary elements kind.

When reconfigure data field (e.g. change representation), it was allowed to transition from dictionary elements kind to sealed elements kind. With this change, this transition is forbidden.

Bug: chromium:963346
Change-Id: I6c9a5f6f269bc5ee4cd6176ff5e8d803f08dba1f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1613840
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61670}
This commit is contained in:
Z Duong Nguyen-Huu 2019-05-20 10:14:46 -07:00 committed by Commit Bot
parent 9ccad33c97
commit 8cbb60f30c
4 changed files with 22 additions and 10 deletions

View File

@ -799,7 +799,9 @@ MapUpdater::State MapUpdater::ConstructNewMapWithIntegrityLevelTransition() {
result_map_ = Map::CopyForPreventExtensions(
isolate_, target_map_, integrity_level_, integrity_level_symbol_,
"CopyForPreventExtensions",
old_map_->elements_kind() != DICTIONARY_ELEMENTS);
old_map_->elements_kind() == DICTIONARY_ELEMENTS);
DCHECK_IMPLIES(old_map_->elements_kind() == DICTIONARY_ELEMENTS,
result_map_->elements_kind() == DICTIONARY_ELEMENTS);
state_ = kEnd;
return state_;

View File

@ -2002,7 +2002,7 @@ Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
Handle<Map> Map::CopyForPreventExtensions(
Isolate* isolate, Handle<Map> map, PropertyAttributes attrs_to_add,
Handle<Symbol> transition_marker, const char* reason,
bool support_holey_frozen_or_sealed_elements_kind) {
bool old_map_is_dictionary_elements_kind) {
int num_descriptors = map->NumberOfOwnDescriptors();
Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
isolate, handle(map->instance_descriptors(), isolate), num_descriptors,
@ -2020,7 +2020,8 @@ Handle<Map> Map::CopyForPreventExtensions(
ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
? SLOW_STRING_WRAPPER_ELEMENTS
: DICTIONARY_ELEMENTS;
if (FLAG_enable_sealed_frozen_elements_kind) {
if (FLAG_enable_sealed_frozen_elements_kind &&
!old_map_is_dictionary_elements_kind) {
switch (map->elements_kind()) {
case PACKED_ELEMENTS:
if (attrs_to_add == SEALED) {
@ -2035,9 +2036,6 @@ Handle<Map> Map::CopyForPreventExtensions(
}
break;
case HOLEY_ELEMENTS:
if (!support_holey_frozen_or_sealed_elements_kind) {
break;
}
if (attrs_to_add == SEALED) {
new_kind = HOLEY_SEALED_ELEMENTS;
} else if (attrs_to_add == FROZEN) {
@ -2045,9 +2043,6 @@ Handle<Map> Map::CopyForPreventExtensions(
}
break;
case HOLEY_SEALED_ELEMENTS:
if (!support_holey_frozen_or_sealed_elements_kind) {
break;
}
if (attrs_to_add == FROZEN) {
new_kind = HOLEY_FROZEN_ELEMENTS;
}

View File

@ -728,7 +728,7 @@ class Map : public HeapObject {
V8_EXPORT_PRIVATE static Handle<Map> CopyForPreventExtensions(
Isolate* isolate, Handle<Map> map, PropertyAttributes attrs_to_add,
Handle<Symbol> transition_marker, const char* reason,
bool support_holey_frozen_or_sealed_elements_kind = true);
bool old_map_is_dictionary_elements_kind = false);
// Maximal number of fast properties. Used to restrict the number of map
// transitions to avoid an explosion in the number of maps for objects used as

View File

@ -0,0 +1,15 @@
// Copyright 2019 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.
// Flags: --allow-natives-syntax
var o = ['3'];
function foo(i) { o.x = i; }
foo("string");
Object.preventExtensions(o);
Object.seal(o);
print('foo');
foo(0);
%HeapObjectVerify(o);
assertEquals(o.x, 0);