Revision: 4229
Author: ant...@chromium.org
Date: Tue Mar 23 07:05:16 2010
Log: Trim underlying fixed array by one element from the left when doing shift.

For now this trick is only done to objects in new space, see comments
for reasons.

Review URL: http://codereview.chromium.org/1076010
http://code.google.com/p/v8/source/detail?r=4229

Modified:
 /branches/bleeding_edge/src/builtins.cc

=======================================
--- /branches/bleeding_edge/src/builtins.cc     Wed Mar 17 02:40:54 2010
+++ /branches/bleeding_edge/src/builtins.cc     Tue Mar 23 07:05:16 2010
@@ -441,6 +441,38 @@

   return top;
 }
+
+
+static FixedArray* LeftTrimFixedArray(FixedArray* elms) {
+  // For now this trick is only applied to fixed arrays in new space.
+  // In large object space the object's start must coincide with chunk
+  // and thus the trick is just not applicable.
+  // In old space we do not use this trick to avoid dealing with
+  // remembered sets.
+  ASSERT(Heap::new_space()->Contains(elms));
+
+  Object** former_map =
+      HeapObject::RawField(elms, FixedArray::kMapOffset);
+  Object** former_length =
+      HeapObject::RawField(elms, FixedArray::kLengthOffset);
+  Object** former_first =
+      HeapObject::RawField(elms, FixedArray::kHeaderSize);
+  // Check that we don't forget to copy all the bits.
+  STATIC_ASSERT(FixedArray::kMapOffset + 2 * kPointerSize
+      == FixedArray::kHeaderSize);
+
+  int len = elms->length();
+
+  *former_first = reinterpret_cast<Object*>(len - 1);
+  *former_length = Heap::fixed_array_map();
+  // Technically in new space this write might be omitted (except for
+  // debug mode which iterates through the heap), but to play safer
+  // we still do it.
+  *former_map = Heap::raw_unchecked_one_pointer_filler_map();
+
+ ASSERT(elms->address() + kPointerSize == (elms + kPointerSize)->address());
+  return elms + kPointerSize;
+}


 BUILTIN(ArrayShift) {
@@ -462,10 +494,14 @@
     first = Heap::undefined_value();
   }

-  // Shift the elements.
-  AssertNoAllocation no_gc;
-  MoveElements(&no_gc, elms, 0, elms, 1, len - 1);
-  elms->set(len - 1, Heap::the_hole_value());
+  if (Heap::new_space()->Contains(elms)) {
+    array->set_elements(LeftTrimFixedArray(elms));
+  } else {
+    // Shift the elements.
+    AssertNoAllocation no_gc;
+    MoveElements(&no_gc, elms, 0, elms, 1, len - 1);
+    elms->set(len - 1, Heap::the_hole_value());
+  }

   // Set the length.
   array->set_length(Smi::FromInt(len - 1));

--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

To unsubscribe from this group, send email to v8-dev+unsubscribegooglegroups.com or reply 
to this email with the words "REMOVE ME" as the subject.

Reply via email to