Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index cdd6718736f2ebdec3695fbd55ee65b284561133..a6a716a3bcd8172e1e1e315786214b19a6a91355 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2259,18 +2259,21 @@ 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, |
+// Returns true if the transition target at given key was deprecated. |
+bool Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors, |
LayoutDescriptor* new_layout_descriptor) { |
+ bool transition_target_deprecated = false; |
if (HasTransitionArray()) { |
TransitionArray* transitions = this->transitions(); |
int transition = transitions->Search(key); |
if (transition != TransitionArray::kNotFound) { |
transitions->GetTarget(transition)->DeprecateTransitionTree(); |
+ transition_target_deprecated = true; |
} |
} |
// Don't overwrite the empty descriptor array. |
- if (NumberOfOwnDescriptors() == 0) return; |
+ if (NumberOfOwnDescriptors() == 0) return transition_target_deprecated; |
DescriptorArray* to_replace = instance_descriptors(); |
Map* current = this; |
@@ -2284,6 +2287,7 @@ void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors, |
} |
set_owns_descriptors(false); |
+ return transition_target_deprecated; |
} |
@@ -2731,8 +2735,17 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
Handle<LayoutDescriptor> new_layout_descriptor = |
LayoutDescriptor::New(split_map, new_descriptors, old_nof); |
- split_map->DeprecateTarget(old_descriptors->GetKey(split_nof), |
- *new_descriptors, *new_layout_descriptor); |
+ bool transition_target_deprecated = |
+ split_map->DeprecateTarget(old_descriptors->GetKey(split_nof), |
+ *new_descriptors, *new_layout_descriptor); |
+ |
+ // If |transition_target_deprecated| is true then the transition array |
+ // already contains entry for given descriptor. This means that the transition |
+ // could be inserted regardless of whether transitions array is full or not. |
+ if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) { |
+ return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
+ "GenAll_CantHaveMoreTransitions"); |
+ } |
if (FLAG_trace_generalization) { |
PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
@@ -2755,10 +2768,6 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
// Add missing transitions. |
Handle<Map> new_map = split_map; |
for (int i = split_nof; i < old_nof; ++i) { |
- if (!new_map->CanHaveMoreTransitions()) { |
- return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
- "can't have more transitions"); |
- } |
new_map = CopyInstallDescriptors(new_map, i, new_descriptors, |
new_layout_descriptor); |
} |