Skip to content

Commit

Permalink
Do not left-trim arrays when concurrent sweeping is active.
Browse files Browse the repository at this point in the history
BUG=
R=mstarzinger@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@20238 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
  • Loading branch information
hpayer@chromium.org committed Mar 25, 2014
1 parent 5b4c20d commit dcf5226
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 7 deletions.
22 changes: 19 additions & 3 deletions src/builtins.cc
Expand Up @@ -567,7 +567,7 @@ BUILTIN(ArrayShift) {
first = isolate->factory()->undefined_value();
}

if (!heap->lo_space()->Contains(*elms_obj)) {
if (!heap->CanMoveObjectStart(*elms_obj)) {
array->set_elements(LeftTrimFixedArray(heap, *elms_obj, 1));
} else {
// Shift the elements.
Expand Down Expand Up @@ -891,8 +891,24 @@ BUILTIN(ArraySplice) {
heap->MoveElements(*elms, delta, 0, actual_start);
}

elms_obj = handle(LeftTrimFixedArray(heap, *elms_obj, delta));

if (heap->CanMoveObjectStart(*elms_obj)) {
// On the fast path we move the start of the object in memory.
elms_obj = handle(LeftTrimFixedArray(heap, *elms_obj, delta));
} else {
// This is the slow path. We are going to move the elements to the left
// by copying them. For trimmed values we store the hole.
if (elms_obj->IsFixedDoubleArray()) {
Handle<FixedDoubleArray> elms =
Handle<FixedDoubleArray>::cast(elms_obj);
MoveDoubleElements(*elms, 0, *elms, delta, len - delta);
FillWithHoles(*elms, len - delta, len);
} else {
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
DisallowHeapAllocation no_gc;
heap->MoveElements(*elms, 0, delta, len - delta);
FillWithHoles(heap, *elms, len - delta, len);
}
}
elms_changed = true;
} else {
if (elms_obj->IsFixedDoubleArray()) {
Expand Down
15 changes: 15 additions & 0 deletions src/heap.cc
Expand Up @@ -3968,6 +3968,21 @@ void Heap::CreateFillerObjectAt(Address addr, int size) {
}


bool Heap::CanMoveObjectStart(HeapObject* object) {
Address address = object->address();
bool is_in_old_pointer_space = InOldPointerSpace(address);
bool is_in_old_data_space = InOldDataSpace(address);

if (lo_space()->Contains(object)) return false;

// We cannot move the object start if the given old space page is
// concurrently swept.
return (!is_in_old_pointer_space && !is_in_old_data_space) ||
Page::FromAddress(address)->parallel_sweeping() <=
MemoryChunk::PARALLEL_SWEEPING_FINALIZE;
}


void Heap::AdjustLiveBytes(Address address, int by, InvocationMode mode) {
if (incremental_marking()->IsMarking() &&
Marking::IsBlack(Marking::MarkBitFrom(address))) {
Expand Down
2 changes: 2 additions & 0 deletions src/heap.h
Expand Up @@ -1177,6 +1177,8 @@ class Heap {
// when shortening objects.
void CreateFillerObjectAt(Address addr, int size);

bool CanMoveObjectStart(HeapObject* object);

enum InvocationMode { FROM_GC, FROM_MUTATOR };

// Maintain marking consistency for IncrementalMarking.
Expand Down
4 changes: 3 additions & 1 deletion src/mark-compact.cc
Expand Up @@ -4086,6 +4086,7 @@ void MarkCompactCollector::SweepInParallel(PagedSpace* space) {
if (p->TryParallelSweeping()) {
SweepConservatively<SWEEP_IN_PARALLEL>(space, &private_free_list, p);
free_list->Concatenate(&private_free_list);
p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
}
}
}
Expand Down Expand Up @@ -4284,10 +4285,11 @@ void MarkCompactCollector::ParallelSweepSpaceComplete(PagedSpace* space) {
PageIterator it(space);
while (it.has_next()) {
Page* p = it.next();
if (p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_IN_PROGRESS) {
if (p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_FINALIZE) {
p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_DONE);
p->MarkSweptConservatively();
}
ASSERT(p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_DONE);
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/spaces.h
Expand Up @@ -468,13 +468,16 @@ class MemoryChunk {
intptr_t GetFlags() { return flags_; }


// PARALLEL_SWEEPING_PENDING - This page is ready for parallel sweeping.
// PARALLEL_SWEEPING_IN_PROGRESS - This page is currently swept or was
// swept by a sweeper thread.
// PARALLEL_SWEEPING_DONE - The page state when sweeping is complete or
// sweeping must not be performed on that page.
// PARALLEL_SWEEPING_FINALIZE - A sweeper thread is done sweeping this
// page and will not touch the page memory anymore.
// PARALLEL_SWEEPING_IN_PROGRESS - This page is currently swept by a
// sweeper thread.
// PARALLEL_SWEEPING_PENDING - This page is ready for parallel sweeping.
enum ParallelSweepingState {
PARALLEL_SWEEPING_DONE,
PARALLEL_SWEEPING_FINALIZE,
PARALLEL_SWEEPING_IN_PROGRESS,
PARALLEL_SWEEPING_PENDING
};
Expand Down

0 comments on commit dcf5226

Please sign in to comment.