From 8448d09d3bfb7cdaf94ebcb12c2c3487af73c23b Mon Sep 17 00:00:00 2001 From: "vitalyr@chromium.org" Date: Fri, 1 Jul 2011 13:18:42 +0000 Subject: [PATCH] Do a backing store sparseness check on fast element delete. R=vegorov@chromium.org Review URL: http://codereview.chromium.org/7298004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8516 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 74c1f42beb..6242198ec3 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3031,11 +3031,33 @@ MaybeObject* JSObject::DeleteFastElement(uint32_t index) { if (!maybe->ToObject(&writable)) return maybe; backing_store = FixedArray::cast(writable); } - int length = IsJSArray() + uint32_t length = static_cast( + IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value() - : backing_store->length(); - if (index < static_cast(length)) { + : backing_store->length()); + if (index < length) { backing_store->set_the_hole(index); + // If an old space backing store is larger than a certain size and + // has too few used values, normalize it. + // To avoid doing the check on every delete we require at least + // one adjacent hole to the value being deleted. + Object* hole = heap->the_hole_value(); + const int kMinLengthForSparsenessCheck = 64; + if (backing_store->length() >= kMinLengthForSparsenessCheck && + !heap->InNewSpace(backing_store) && + ((index > 0 && backing_store->get(index - 1) == hole) || + (index + 1 < length && backing_store->get(index + 1) == hole))) { + int num_used = 0; + for (int i = 0; i < backing_store->length(); ++i) { + if (backing_store->get(i) != hole) ++num_used; + // Bail out early if more than 1/4 is used. + if (4 * num_used > backing_store->length()) break; + } + if (4 * num_used <= backing_store->length()) { + MaybeObject* result = NormalizeElements(); + if (result->IsFailure()) return result; + } + } } return heap->true_value(); }