From 44dcc0a2c02e65de68e67d3982639ffd95bcd7fb Mon Sep 17 00:00:00 2001 From: verwaest Date: Tue, 7 Jul 2015 09:02:30 -0700 Subject: [PATCH] Delete from non-array end by trimming the backing store Review URL: https://codereview.chromium.org/1218663009 Cr-Commit-Position: refs/heads/master@{#29521} --- src/elements.cc | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/elements.cc b/src/elements.cc index 750b1174bf..e830d7c465 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -1037,12 +1037,39 @@ class FastElementsAccessor typedef typename KindTraits::BackingStore BackingStore; + static void DeleteAtEnd(Handle obj, + Handle backing_store, uint32_t entry) { + uint32_t length = static_cast(backing_store->length()); + Heap* heap = obj->GetHeap(); + for (; entry > 0; entry--) { + if (!backing_store->is_the_hole(entry - 1)) break; + } + if (entry == 0) { + FixedArray* empty = heap->empty_fixed_array(); + if (obj->HasFastArgumentsElements()) { + FixedArray::cast(obj->elements())->set(1, empty); + } else { + obj->set_elements(empty); + } + return; + } + + heap->RightTrimFixedArray(*backing_store, + length - entry); + } + static void DeleteCommon(Handle obj, uint32_t entry, Handle store) { DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() || obj->HasFastArgumentsElements()); Handle backing_store = Handle::cast(store); + if (!obj->IsJSArray() && + entry == static_cast(store->length()) - 1) { + DeleteAtEnd(obj, backing_store, entry); + return; + } + backing_store->set_the_hole(entry); // TODO(verwaest): Move this out of elements.cc. @@ -1061,6 +1088,16 @@ class FastElementsAccessor } if ((entry > 0 && backing_store->is_the_hole(entry - 1)) || (entry + 1 < length && backing_store->is_the_hole(entry + 1))) { + if (!obj->IsJSArray()) { + uint32_t i; + for (i = entry + 1; i < length; i++) { + if (!backing_store->is_the_hole(i)) break; + } + if (i == length) { + DeleteAtEnd(obj, backing_store, entry); + return; + } + } int num_used = 0; for (int i = 0; i < backing_store->length(); ++i) { if (!backing_store->is_the_hole(i)) ++num_used;