Don't insert elements transitions into normalized maps
BUG=chromium:499790 LOG=n Review URL: https://codereview.chromium.org/1203653003 Cr-Commit-Position: refs/heads/master@{#29233}
This commit is contained in:
parent
dee4895d0a
commit
c49659b008
@ -1763,13 +1763,6 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
|
|
||||||
Isolate* isolate = parent->GetIsolate();
|
|
||||||
Handle<Name> name = isolate->factory()->elements_transition_symbol();
|
|
||||||
ConnectTransition(parent, child, name, SPECIAL_TRANSITION);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
|
void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
|
||||||
int expected_additional_properties) {
|
int expected_additional_properties) {
|
||||||
if (object->map() == *new_map) return;
|
if (object->map() == *new_map) return;
|
||||||
@ -3726,24 +3719,8 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TransitionElementsToSlow(map, to_kind);
|
DCHECK(!map->IsUndefined());
|
||||||
}
|
bool allow_store_transition = IsTransitionElementsKind(from_kind);
|
||||||
|
|
||||||
|
|
||||||
Handle<Map> Map::TransitionElementsToSlow(Handle<Map> map,
|
|
||||||
ElementsKind to_kind) {
|
|
||||||
ElementsKind from_kind = map->elements_kind();
|
|
||||||
|
|
||||||
if (from_kind == to_kind) {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool allow_store_transition =
|
|
||||||
// Only remember the map transition if there is not an already existing
|
|
||||||
// non-matching element transition.
|
|
||||||
!map->IsUndefined() && !map->is_dictionary_map() &&
|
|
||||||
IsTransitionElementsKind(from_kind);
|
|
||||||
|
|
||||||
// Only store fast element maps in ascending generality.
|
// Only store fast element maps in ascending generality.
|
||||||
if (IsFastElementsKind(to_kind)) {
|
if (IsFastElementsKind(to_kind)) {
|
||||||
allow_store_transition &=
|
allow_store_transition &=
|
||||||
@ -5599,8 +5576,7 @@ MaybeHandle<Object> JSObject::PreventExtensionsWithTransition(
|
|||||||
DCHECK(transition_map->has_dictionary_elements());
|
DCHECK(transition_map->has_dictionary_elements());
|
||||||
DCHECK(!transition_map->is_extensible());
|
DCHECK(!transition_map->is_extensible());
|
||||||
JSObject::MigrateToMap(object, transition_map);
|
JSObject::MigrateToMap(object, transition_map);
|
||||||
} else if (object->HasFastProperties() &&
|
} else if (TransitionArray::CanHaveMoreTransitions(old_map)) {
|
||||||
TransitionArray::CanHaveMoreTransitions(old_map)) {
|
|
||||||
// Create a new descriptor array with the appropriate property attributes
|
// Create a new descriptor array with the appropriate property attributes
|
||||||
Handle<Map> new_map = Map::CopyForPreventExtensions(
|
Handle<Map> new_map = Map::CopyForPreventExtensions(
|
||||||
old_map, attrs, transition_marker, "CopyForPreventExtensions");
|
old_map, attrs, transition_marker, "CopyForPreventExtensions");
|
||||||
@ -5668,8 +5644,7 @@ void JSObject::SetObserved(Handle<JSObject> object) {
|
|||||||
if (transition != NULL) {
|
if (transition != NULL) {
|
||||||
new_map = handle(transition, isolate);
|
new_map = handle(transition, isolate);
|
||||||
DCHECK(new_map->is_observed());
|
DCHECK(new_map->is_observed());
|
||||||
} else if (object->HasFastProperties() &&
|
} else if (TransitionArray::CanHaveMoreTransitions(old_map)) {
|
||||||
TransitionArray::CanHaveMoreTransitions(old_map)) {
|
|
||||||
new_map = Map::CopyForObserved(old_map);
|
new_map = Map::CopyForObserved(old_map);
|
||||||
} else {
|
} else {
|
||||||
new_map = Map::Copy(old_map, "SlowObserved");
|
new_map = Map::Copy(old_map, "SlowObserved");
|
||||||
@ -6963,8 +6938,9 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
|
|||||||
Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind");
|
Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind");
|
||||||
new_map->set_elements_kind(kind);
|
new_map->set_elements_kind(kind);
|
||||||
|
|
||||||
ConnectElementsTransition(map, new_map);
|
Isolate* isolate = map->GetIsolate();
|
||||||
|
Handle<Name> name = isolate->factory()->elements_transition_symbol();
|
||||||
|
ConnectTransition(map, new_map, name, SPECIAL_TRANSITION);
|
||||||
return new_map;
|
return new_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6225,7 +6225,6 @@ class Map: public HeapObject {
|
|||||||
Handle<LayoutDescriptor> layout_descriptor);
|
Handle<LayoutDescriptor> layout_descriptor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void ConnectElementsTransition(Handle<Map> parent, Handle<Map> child);
|
|
||||||
static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
|
static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
|
||||||
Handle<Name> name, SimpleTransitionFlag flag);
|
Handle<Name> name, SimpleTransitionFlag flag);
|
||||||
|
|
||||||
@ -6263,9 +6262,6 @@ class Map: public HeapObject {
|
|||||||
// the descriptor array.
|
// the descriptor array.
|
||||||
inline void NotifyLeafMapLayoutChange();
|
inline void NotifyLeafMapLayoutChange();
|
||||||
|
|
||||||
static Handle<Map> TransitionElementsToSlow(Handle<Map> object,
|
|
||||||
ElementsKind to_kind);
|
|
||||||
|
|
||||||
void DeprecateTransitionTree();
|
void DeprecateTransitionTree();
|
||||||
bool DeprecateTarget(PropertyKind kind, Name* key,
|
bool DeprecateTarget(PropertyKind kind, Name* key,
|
||||||
PropertyAttributes attributes,
|
PropertyAttributes attributes,
|
||||||
|
@ -223,6 +223,7 @@ Handle<String> TransitionArray::ExpectedTransitionKey(Handle<Map> map) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
bool TransitionArray::CanHaveMoreTransitions(Handle<Map> map) {
|
bool TransitionArray::CanHaveMoreTransitions(Handle<Map> map) {
|
||||||
|
if (map->is_dictionary_map()) return false;
|
||||||
Object* raw_transitions = map->raw_transitions();
|
Object* raw_transitions = map->raw_transitions();
|
||||||
if (IsFullTransitionArray(raw_transitions)) {
|
if (IsFullTransitionArray(raw_transitions)) {
|
||||||
TransitionArray* transitions = TransitionArray::cast(raw_transitions);
|
TransitionArray* transitions = TransitionArray::cast(raw_transitions);
|
||||||
|
14
test/mjsunit/regress/regress-499790.js
Normal file
14
test/mjsunit/regress/regress-499790.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2015 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: --enable-slow-asserts
|
||||||
|
|
||||||
|
var a = [1];
|
||||||
|
a.foo = "bla";
|
||||||
|
delete a.foo;
|
||||||
|
a[0] = 1.5;
|
||||||
|
|
||||||
|
var a2 = [];
|
||||||
|
a2.foo = "bla";
|
||||||
|
delete a2.foo;
|
Loading…
Reference in New Issue
Block a user