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:
parent
a0fb367755
commit
7541dff7bb
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
23
src/heap.cc
23
src/heap.cc
@ -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 {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user