From 40d4674d611928314d7471b03a651b179481550b Mon Sep 17 00:00:00 2001 From: ishell Date: Wed, 19 Nov 2014 10:10:12 -0800 Subject: [PATCH] Removed unnecessary generalization of all fields in Map::GeneralizeRepresentation() (introduced in r25082). This generalization caused unnecessary map deprecation when the transition tree of the split map is full. BUG=chromium:431807 LOG=N Review URL: https://codereview.chromium.org/736953003 Cr-Commit-Position: refs/heads/master@{#25427} --- src/objects.cc | 25 +++++++++++++++++-------- src/objects.h | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index cdd6718736..a6a716a3bc 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::GeneralizeRepresentation(Handle old_map, Handle 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::GeneralizeRepresentation(Handle old_map, // Add missing transitions. Handle 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); } diff --git a/src/objects.h b/src/objects.h index 0c2d22f42d..678dcb2ed5 100644 --- a/src/objects.h +++ b/src/objects.h @@ -6364,7 +6364,7 @@ class Map: public HeapObject { void ZapTransitions(); void DeprecateTransitionTree(); - void DeprecateTarget(Name* key, DescriptorArray* new_descriptors, + bool DeprecateTarget(Name* key, DescriptorArray* new_descriptors, LayoutDescriptor* new_layout_descriptor); Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);