Commit d1c0dd17 authored by antonm@chromium.org's avatar antonm@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4229 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b7833cb5
......@@ -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));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment