Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1101)

Unified Diff: src/builtins.cc

Issue 1076010: Trim underlying fixed array by one element from the left when doing shift. (Closed)
Patch Set: Mads' round Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index 91cb1515200ac8555ed181cfb9de15ed926848ff..122fbba2c4aac4464c2a5bc1d37cf66d283b30bb 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -443,6 +443,38 @@ BUILTIN(ArrayPop) {
}
+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) {
Object* receiver = *args.receiver();
FixedArray* elms = NULL;
@@ -462,10 +494,14 @@ BUILTIN(ArrayShift) {
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));
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698