Filter old space and large object space to new space references when moving parts of a FixedArray.

BUG=v8:2452

Review URL: https://codereview.chromium.org/11737006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13343 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
hpayer@chromium.org 2013-01-09 14:01:39 +00:00
parent a0fb367755
commit 7541dff7bb
3 changed files with 36 additions and 31 deletions

View File

@ -337,26 +337,6 @@ static void MoveDoubleElements(FixedDoubleArray* dst,
}
static void MoveElements(Heap* heap,
AssertNoAllocation* no_gc,
FixedArray* dst,
int dst_index,
FixedArray* src,
int src_index,
int len) {
if (len == 0) return;
ASSERT(dst->map() != HEAP->fixed_cow_array_map());
memmove(dst->data_start() + dst_index,
src->data_start() + src_index,
len * kPointerSize);
WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
if (mode == UPDATE_WRITE_BARRIER) {
heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
}
heap->incremental_marking()->RecordWrites(dst);
}
static void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
ASSERT(dst->map() != heap->fixed_cow_array_map());
MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
@ -724,7 +704,7 @@ BUILTIN(ArrayShift) {
if (elms_obj->IsFixedArray()) {
FixedArray* elms = FixedArray::cast(elms_obj);
AssertNoAllocation no_gc;
MoveElements(heap, &no_gc, elms, 0, elms, 1, len - 1);
heap->MoveElements(elms, 0, 1, len - 1);
elms->set(len - 1, heap->the_hole_value());
} else {
FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
@ -794,7 +774,7 @@ BUILTIN(ArrayUnshift) {
array->set_elements(elms);
} else {
AssertNoAllocation no_gc;
MoveElements(heap, &no_gc, elms, to_add, elms, 0, len);
heap->MoveElements(elms, to_add, 0, len);
}
// Add the provided values.
@ -1060,7 +1040,7 @@ BUILTIN(ArraySplice) {
} else {
FixedArray* elms = FixedArray::cast(elms_obj);
AssertNoAllocation no_gc;
MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start);
heap->MoveElements(elms, delta, 0, actual_start);
}
elms_obj = LeftTrimFixedArray(heap, elms_obj, delta);
@ -1076,10 +1056,9 @@ BUILTIN(ArraySplice) {
} else {
FixedArray* elms = FixedArray::cast(elms_obj);
AssertNoAllocation no_gc;
MoveElements(heap, &no_gc,
elms, actual_start + item_count,
elms, actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
heap->MoveElements(elms, actual_start + item_count,
actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
FillWithHoles(heap, elms, new_length, len);
}
}
@ -1119,10 +1098,9 @@ BUILTIN(ArraySplice) {
elms_changed = true;
} else {
AssertNoAllocation no_gc;
MoveElements(heap, &no_gc,
elms, actual_start + item_count,
elms, actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
heap->MoveElements(elms, actual_start + item_count,
actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
}
}

View File

@ -677,6 +677,29 @@ void Heap::PerformScavenge() {
}
void Heap::MoveElements(FixedArray* array,
int dst_index,
int src_index,
int len) {
if (len == 0) return;
ASSERT(array->map() != HEAP->fixed_cow_array_map());
Object** dst_objects = array->data_start() + dst_index;
memmove(dst_objects,
array->data_start() + src_index,
len * kPointerSize);
if (!InNewSpace(array)) {
for (int i = 0; i < len; i++) {
// TODO(hpayer): check store buffer for entries
if (InNewSpace(dst_objects[i])) {
RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i));
}
}
}
incremental_marking()->RecordWrites(array);
}
#ifdef VERIFY_HEAP
// Helper class for verifying the symbol table.
class SymbolTableVerifier : public ObjectVisitor {

View File

@ -813,6 +813,10 @@ class Heap {
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedArray(int length);
// Move len elements within a given array from src_index index to dst_index
// index.
void MoveElements(FixedArray* array, int dst_index, int src_index, int len);
// Make a copy of src and return it. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
MUST_USE_RESULT inline MaybeObject* CopyFixedArray(FixedArray* src);