Commit 3f336d41 authored by verwaest's avatar verwaest Committed by Commit bot

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}
parent cfe89a71
...@@ -1372,43 +1372,45 @@ class DictionaryElementsAccessor ...@@ -1372,43 +1372,45 @@ class DictionaryElementsAccessor
int capacity = dict->Capacity(); int capacity = dict->Capacity();
uint32_t old_length = 0; uint32_t old_length = 0;
CHECK(array->length()->ToArrayLength(&old_length)); CHECK(array->length()->ToArrayLength(&old_length));
if (dict->requires_slow_elements() && length < old_length) { if (length < old_length) {
// Find last non-deletable element in range of elements to be if (dict->requires_slow_elements()) {
// deleted and adjust range accordingly. // Find last non-deletable element in range of elements to be
for (int i = 0; i < capacity; i++) { // deleted and adjust range accordingly.
DisallowHeapAllocation no_gc; for (int i = 0; i < capacity; i++) {
Object* key = dict->KeyAt(i); DisallowHeapAllocation no_gc;
if (key->IsNumber()) { Object* key = dict->KeyAt(i);
uint32_t number = static_cast<uint32_t>(key->Number()); if (key->IsNumber()) {
if (length <= number && number < old_length) { uint32_t number = static_cast<uint32_t>(key->Number());
PropertyDetails details = dict->DetailsAt(i); if (length <= number && number < old_length) {
if (!details.IsConfigurable()) length = number + 1; PropertyDetails details = dict->DetailsAt(i);
if (!details.IsConfigurable()) length = number + 1;
}
} }
} }
} }
}
if (length == 0) { if (length == 0) {
// Flush the backing store. // Flush the backing store.
JSObject::ResetElements(array); JSObject::ResetElements(array);
} else { } else {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
// Remove elements that should be deleted. // Remove elements that should be deleted.
int removed_entries = 0; int removed_entries = 0;
Handle<Object> the_hole_value = isolate->factory()->the_hole_value(); Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object* key = dict->KeyAt(i); Object* key = dict->KeyAt(i);
if (key->IsNumber()) { if (key->IsNumber()) {
uint32_t number = static_cast<uint32_t>(key->Number()); uint32_t number = static_cast<uint32_t>(key->Number());
if (length <= number && number < old_length) { if (length <= number && number < old_length) {
dict->SetEntry(i, the_hole_value, the_hole_value); dict->SetEntry(i, the_hole_value, the_hole_value);
removed_entries++; removed_entries++;
}
} }
} }
}
// Update the number of elements. // Update the number of elements.
dict->ElementsRemoved(removed_entries); dict->ElementsRemoved(removed_entries);
}
} }
Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length); Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment