Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 2689e2cbe26d1e034b2d329057a79873fc443273..ac03350fe35434cd20571a03e8931cbe0e62f272 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2264,10 +2264,12 @@ void Map::DeprecateTransitionTree() { |
// Invalidates a transition target at |key|, and installs |new_descriptors| over |
// the current instance_descriptors to ensure proper sharing of descriptor |
// arrays. |
-void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) { |
+void Map::DeprecateTarget(PropertyType type, Name* key, |
+ PropertyAttributes attributes, |
+ DescriptorArray* new_descriptors) { |
if (HasTransitionArray()) { |
TransitionArray* transitions = this->transitions(); |
- int transition = transitions->Search(key); |
+ int transition = transitions->Search(type, key, attributes); |
if (transition != TransitionArray::kNotFound) { |
transitions->GetTarget(transition)->DeprecateTransitionTree(); |
} |
@@ -2314,14 +2316,15 @@ Map* Map::FindLastMatchMap(int verbatim, |
for (int i = verbatim; i < length; i++) { |
if (!current->HasTransitionArray()) break; |
Name* name = descriptors->GetKey(i); |
+ PropertyDetails details = descriptors->GetDetails(i); |
TransitionArray* transitions = current->transitions(); |
- int transition = transitions->Search(name); |
+ int transition = |
+ transitions->Search(details.type(), name, details.attributes()); |
if (transition == TransitionArray::kNotFound) break; |
Map* next = transitions->GetTarget(transition); |
DescriptorArray* next_descriptors = next->instance_descriptors(); |
- PropertyDetails details = descriptors->GetDetails(i); |
PropertyDetails next_details = next_descriptors->GetDetails(i); |
if (details.type() != next_details.type()) break; |
if (details.attributes() != next_details.attributes()) break; |
@@ -2511,21 +2514,23 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
Handle<Map> target_map = root_map; |
for (int i = root_nof; i < old_nof; ++i) { |
- int j = target_map->SearchTransition(old_descriptors->GetKey(i)); |
+ PropertyDetails old_details = old_descriptors->GetDetails(i); |
+ int j = target_map->SearchTransition(old_details.type(), |
+ old_descriptors->GetKey(i), |
+ old_details.attributes()); |
if (j == TransitionArray::kNotFound) break; |
Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
Handle<DescriptorArray> tmp_descriptors = handle( |
tmp_map->instance_descriptors(), isolate); |
// Check if target map is incompatible. |
- PropertyDetails old_details = old_descriptors->GetDetails(i); |
PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
PropertyType old_type = old_details.type(); |
PropertyType tmp_type = tmp_details.type(); |
- if (tmp_details.attributes() != old_details.attributes() || |
- ((tmp_type == CALLBACKS || old_type == CALLBACKS) && |
- (tmp_type != old_type || |
- tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { |
+ DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
+ if ((tmp_type == CALLBACKS || old_type == CALLBACKS) && |
+ (tmp_type != old_type || |
+ tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
return CopyGeneralizeAllRepresentations( |
old_map, modify_index, store_mode, "incompatible"); |
} |
@@ -2577,19 +2582,21 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
// Find the last compatible target map in the transition tree. |
for (int i = target_nof; i < old_nof; ++i) { |
- int j = target_map->SearchTransition(old_descriptors->GetKey(i)); |
+ PropertyDetails old_details = old_descriptors->GetDetails(i); |
+ int j = target_map->SearchTransition(old_details.type(), |
+ old_descriptors->GetKey(i), |
+ old_details.attributes()); |
if (j == TransitionArray::kNotFound) break; |
Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
Handle<DescriptorArray> tmp_descriptors( |
tmp_map->instance_descriptors(), isolate); |
// Check if target map is compatible. |
- PropertyDetails old_details = old_descriptors->GetDetails(i); |
PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
- if (tmp_details.attributes() != old_details.attributes() || |
- ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && |
- (tmp_details.type() != old_details.type() || |
- tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { |
+ DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
+ if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && |
+ (tmp_details.type() != old_details.type() || |
+ tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
return CopyGeneralizeAllRepresentations( |
old_map, modify_index, store_mode, "incompatible"); |
} |
@@ -2721,8 +2728,10 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
int split_nof = split_map->NumberOfOwnDescriptors(); |
DCHECK_NE(old_nof, split_nof); |
- split_map->DeprecateTarget( |
- old_descriptors->GetKey(split_nof), *new_descriptors); |
+ PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); |
+ split_map->DeprecateTarget(split_prop_details.type(), |
+ old_descriptors->GetKey(split_nof), |
+ split_prop_details.attributes(), *new_descriptors); |
if (FLAG_trace_generalization) { |
PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
@@ -2807,13 +2816,15 @@ MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { |
Map* new_map = root_map; |
for (int i = root_nof; i < old_nof; ++i) { |
- int j = new_map->SearchTransition(old_descriptors->GetKey(i)); |
+ PropertyDetails old_details = old_descriptors->GetDetails(i); |
+ int j = new_map->SearchTransition(old_details.type(), |
+ old_descriptors->GetKey(i), |
+ old_details.attributes()); |
if (j == TransitionArray::kNotFound) return MaybeHandle<Map>(); |
new_map = new_map->GetTransition(j); |
DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
PropertyDetails new_details = new_descriptors->GetDetails(i); |
- PropertyDetails old_details = old_descriptors->GetDetails(i); |
if (old_details.attributes() != new_details.attributes() || |
!old_details.representation().fits_into(new_details.representation())) { |
return MaybeHandle<Map>(); |
@@ -5408,8 +5419,8 @@ MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { |
} |
Handle<Map> old_map(object->map(), isolate); |
- int transition_index = old_map->SearchTransition( |
- isolate->heap()->frozen_symbol()); |
+ int transition_index = |
+ old_map->SearchSpecialTransition(isolate->heap()->frozen_symbol()); |
if (transition_index != TransitionArray::kNotFound) { |
Handle<Map> transition_map(old_map->GetTransition(transition_index)); |
DCHECK(transition_map->has_dictionary_elements()); |
@@ -5461,8 +5472,8 @@ void JSObject::SetObserved(Handle<JSObject> object) { |
Handle<Map> new_map; |
Handle<Map> old_map(object->map(), isolate); |
DCHECK(!old_map->is_observed()); |
- int transition_index = old_map->SearchTransition( |
- isolate->heap()->observed_symbol()); |
+ int transition_index = |
+ old_map->SearchSpecialTransition(isolate->heap()->observed_symbol()); |
if (transition_index != TransitionArray::kNotFound) { |
new_map = handle(old_map->GetTransition(transition_index), isolate); |
DCHECK(new_map->is_observed()); |
@@ -6884,16 +6895,14 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
// Migrate to the newest map before storing the property. |
map = Update(map); |
- int index = map->SearchTransition(*name); |
+ int index = map->SearchTransition(FIELD, *name, attributes); |
if (index != TransitionArray::kNotFound) { |
Handle<Map> transition(map->GetTransition(index)); |
int descriptor = transition->LastAdded(); |
- // TODO(verwaest): Handle attributes better. |
- DescriptorArray* descriptors = transition->instance_descriptors(); |
- if (descriptors->GetDetails(descriptor).attributes() != attributes) { |
- return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES); |
- } |
+ DCHECK_EQ(attributes, transition->instance_descriptors() |
+ ->GetDetails(descriptor) |
+ .attributes()); |
return Map::PrepareForDataProperty(transition, descriptor, value); |
} |
@@ -6953,7 +6962,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
? KEEP_INOBJECT_PROPERTIES |
: CLEAR_INOBJECT_PROPERTIES; |
- int index = map->SearchTransition(*name); |
+ int index = map->SearchTransition(CALLBACKS, *name, attributes); |
if (index != TransitionArray::kNotFound) { |
Handle<Map> transition(map->GetTransition(index)); |
DescriptorArray* descriptors = transition->instance_descriptors(); |
@@ -6964,14 +6973,8 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
descriptor = descriptors->SearchWithCache(*name, *transition); |
} |
- if (descriptors->GetDetails(descriptor).type() != CALLBACKS) { |
- return Map::Normalize(map, mode); |
- } |
- |
- // TODO(verwaest): Handle attributes better. |
- if (descriptors->GetDetails(descriptor).attributes() != attributes) { |
- return Map::Normalize(map, mode); |
- } |
+ DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type()); |
+ DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); |
Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); |
if (!maybe_pair->IsAccessorPair()) { |