From 3f336d41444b597788fd4dd4c0a9231e7c494004 Mon Sep 17 00:00:00 2001 From: verwaest Date: Thu, 25 Jun 2015 07:43:28 -0700 Subject: [PATCH] Only try to delete dictionary elements if the length is actually reduced BUG=v8:4137 LOG=n Review URL: https://codereview.chromium.org/1209983002 Cr-Commit-Position: refs/heads/master@{#29297} --- src/elements.cc | 66 +++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/elements.cc b/src/elements.cc index 751a292cfa..1f1cd5696a 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -1372,43 +1372,45 @@ class DictionaryElementsAccessor int capacity = dict->Capacity(); uint32_t old_length = 0; CHECK(array->length()->ToArrayLength(&old_length)); - if (dict->requires_slow_elements() && length < old_length) { - // Find last non-deletable element in range of elements to be - // deleted and adjust range accordingly. - for (int i = 0; i < capacity; i++) { + if (length < old_length) { + if (dict->requires_slow_elements()) { + // Find last non-deletable element in range of elements to be + // deleted and adjust range accordingly. + for (int i = 0; i < capacity; i++) { + DisallowHeapAllocation no_gc; + Object* key = dict->KeyAt(i); + if (key->IsNumber()) { + uint32_t number = static_cast(key->Number()); + if (length <= number && number < old_length) { + PropertyDetails details = dict->DetailsAt(i); + if (!details.IsConfigurable()) length = number + 1; + } + } + } + } + + if (length == 0) { + // Flush the backing store. + JSObject::ResetElements(array); + } else { DisallowHeapAllocation no_gc; - Object* key = dict->KeyAt(i); - if (key->IsNumber()) { - uint32_t number = static_cast(key->Number()); - if (length <= number && number < old_length) { - PropertyDetails details = dict->DetailsAt(i); - if (!details.IsConfigurable()) length = number + 1; + // Remove elements that should be deleted. + int removed_entries = 0; + Handle the_hole_value = isolate->factory()->the_hole_value(); + for (int i = 0; i < capacity; i++) { + Object* key = dict->KeyAt(i); + if (key->IsNumber()) { + uint32_t number = static_cast(key->Number()); + if (length <= number && number < old_length) { + dict->SetEntry(i, the_hole_value, the_hole_value); + removed_entries++; + } } } - } - } - if (length == 0) { - // Flush the backing store. - JSObject::ResetElements(array); - } else { - DisallowHeapAllocation no_gc; - // Remove elements that should be deleted. - int removed_entries = 0; - Handle the_hole_value = isolate->factory()->the_hole_value(); - for (int i = 0; i < capacity; i++) { - Object* key = dict->KeyAt(i); - if (key->IsNumber()) { - uint32_t number = static_cast(key->Number()); - if (length <= number && number < old_length) { - dict->SetEntry(i, the_hole_value, the_hole_value); - removed_entries++; - } - } + // Update the number of elements. + dict->ElementsRemoved(removed_entries); } - - // Update the number of elements. - dict->ElementsRemoved(removed_entries); } Handle length_obj = isolate->factory()->NewNumberFromUint(length);