Reviewers: Mads Ager,

Description:
Trim fast elements tail on significant length decreases.

Runtime_RegExpExecMultiple had to be updated because it assumed
setting an array's length to zero still keeps some capacity in the
backing store.

[email protected]


Please review this at http://codereview.chromium.org/7237004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/objects.cc
  M src/runtime.cc


Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 6c9f52b2df89839306e30b8f925f87412fc111f4..cff87bdb471395cf498e84246334fa7dda44c0cb 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -7507,12 +7507,24 @@ MaybeObject* JSObject::SetElementsLength(Object* len) {
             { MaybeObject* maybe_obj = EnsureWritableFastElements();
               if (!maybe_obj->ToObject(&obj)) return maybe_obj;
             }
- int old_length = FastD2I(JSArray::cast(this)->length()->Number());
-            // NOTE: We may be able to optimize this by removing the
-            // last part of the elements backing storage array and
-            // setting the capacity to the new size.
-            for (int i = value; i < old_length; i++) {
-              FixedArray::cast(elements())->set_the_hole(i);
+            FixedArray* fast_elements = FixedArray::cast(elements());
+            if (2 * value <= old_capacity) {
+ // If more than half the elements won't be used, trim the array.
+              if (value == 0) {
+                initialize_elements();
+              } else {
+                fast_elements->set_length(value);
+                Address filler_start = fast_elements->address() +
+ FixedArray::OffsetOfElementAt(value);
+                int filler_size = (old_capacity - value) * kPointerSize;
+                GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
+              }
+            } else {
+              // Otherwise, fill the unused tail with holes.
+ int old_length = FastD2I(JSArray::cast(this)->length()->Number());
+              for (int i = value; i < old_length; i++) {
+                fast_elements->set_the_hole(i);
+              }
             }
             JSArray::cast(this)->set_length(Smi::cast(smi_length));
           }
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 32d25179233275c62ff07d5592d1dfabd2d75e77..f11d745d8f8fc258076653877dd57022b48d414d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -3532,7 +3532,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
   if (result_array->HasFastElements()) {
     result_elements =
         Handle<FixedArray>(FixedArray::cast(result_array->elements()));
-  } else {
+  }
+  if (result_elements.is_null() || result_elements->length() < 16) {
     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
   }
   FixedArrayBuilder builder(result_elements);


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to