Commit 33922309 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[heap] Simplify MarkingDeque implementation.

This removes the dependency of the MarkingDeque on the underlying
collector by moving out the live bytes accounting and object color
mutations into a wrapper. The MarkingDeque can now be split into a
separate file.

R=hpayer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#30194}
parent bfbc5e7c
......@@ -202,7 +202,7 @@ class IncrementalMarkingMarkingVisitor
heap->mark_compact_collector()->marking_deque()->UnshiftGrey(object);
} else {
DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
heap->mark_compact_collector()->marking_deque()->UnshiftBlack(object);
heap->mark_compact_collector()->UnshiftBlack(object);
}
heap->incremental_marking()->NotifyIncompleteScanOfObject(
object_size - (start_offset - already_scanned_offset));
......
......@@ -23,13 +23,29 @@ void MarkCompactCollector::SetFlags(int flags) {
}
void MarkCompactCollector::PushBlack(HeapObject* obj) {
if (marking_deque_.PushBlack(obj)) {
MemoryChunk::IncrementLiveBytesFromGC(obj, obj->Size());
} else {
Marking::BlackToGrey(obj);
}
}
void MarkCompactCollector::UnshiftBlack(HeapObject* obj) {
if (!marking_deque_.UnshiftBlack(obj)) {
MemoryChunk::IncrementLiveBytesFromGC(obj, -obj->Size());
Marking::BlackToGrey(obj);
}
}
void MarkCompactCollector::MarkObject(HeapObject* obj, MarkBit mark_bit) {
DCHECK(Marking::MarkBitFrom(obj) == mark_bit);
if (Marking::IsWhite(mark_bit)) {
Marking::WhiteToBlack(mark_bit);
MemoryChunk::IncrementLiveBytesFromGC(obj, obj->Size());
DCHECK(obj->GetIsolate()->heap()->Contains(obj));
marking_deque_.PushBlack(obj);
PushBlack(obj);
}
}
......
......@@ -1734,21 +1734,18 @@ class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
// iterator. Stop when the marking stack is filled or the end of the space
// is reached, whichever comes first.
template <class T>
static void DiscoverGreyObjectsWithIterator(Heap* heap,
MarkingDeque* marking_deque,
T* it) {
void MarkCompactCollector::DiscoverGreyObjectsWithIterator(T* it) {
// The caller should ensure that the marking stack is initially not full,
// so that we don't waste effort pointlessly scanning for objects.
DCHECK(!marking_deque->IsFull());
DCHECK(!marking_deque()->IsFull());
Map* filler_map = heap->one_pointer_filler_map();
Map* filler_map = heap()->one_pointer_filler_map();
for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) {
MarkBit markbit = Marking::MarkBitFrom(object);
if ((object->map() != filler_map) && Marking::IsGrey(markbit)) {
Marking::GreyToBlack(markbit);
MemoryChunk::IncrementLiveBytesFromGC(object, object->Size());
marking_deque->PushBlack(object);
if (marking_deque->IsFull()) return;
PushBlack(object);
if (marking_deque()->IsFull()) return;
}
}
}
......@@ -1757,9 +1754,8 @@ static void DiscoverGreyObjectsWithIterator(Heap* heap,
static inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts);
static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque,
MemoryChunk* p) {
DCHECK(!marking_deque->IsFull());
void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
DCHECK(!marking_deque()->IsFull());
DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
......@@ -1791,9 +1787,8 @@ static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque,
Marking::GreyToBlack(markbit);
Address addr = cell_base + offset * kPointerSize;
HeapObject* object = HeapObject::FromAddress(addr);
MemoryChunk::IncrementLiveBytesFromGC(object, object->Size());
marking_deque->PushBlack(object);
if (marking_deque->IsFull()) return;
PushBlack(object);
if (marking_deque()->IsFull()) return;
offset += 2;
grey_objects >>= 2;
}
......@@ -1866,25 +1861,23 @@ int MarkCompactCollector::DiscoverAndEvacuateBlackObjectsOnPage(
}
static void DiscoverGreyObjectsInSpace(Heap* heap, MarkingDeque* marking_deque,
PagedSpace* space) {
void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) {
PageIterator it(space);
while (it.has_next()) {
Page* p = it.next();
DiscoverGreyObjectsOnPage(marking_deque, p);
if (marking_deque->IsFull()) return;
DiscoverGreyObjectsOnPage(p);
if (marking_deque()->IsFull()) return;
}
}
static void DiscoverGreyObjectsInNewSpace(Heap* heap,
MarkingDeque* marking_deque) {
NewSpace* space = heap->new_space();
void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() {
NewSpace* space = heap()->new_space();
NewSpacePageIterator it(space->bottom(), space->top());
while (it.has_next()) {
NewSpacePage* page = it.next();
DiscoverGreyObjectsOnPage(marking_deque, page);
if (marking_deque->IsFull()) return;
DiscoverGreyObjectsOnPage(page);
if (marking_deque()->IsFull()) return;
}
}
......@@ -2009,20 +2002,20 @@ void MarkCompactCollector::RefillMarkingDeque() {
isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow);
DCHECK(marking_deque_.overflowed());
DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_);
DiscoverGreyObjectsInNewSpace();
if (marking_deque_.IsFull()) return;
DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_space());
DiscoverGreyObjectsInSpace(heap()->old_space());
if (marking_deque_.IsFull()) return;
DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space());
DiscoverGreyObjectsInSpace(heap()->code_space());
if (marking_deque_.IsFull()) return;
DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space());
DiscoverGreyObjectsInSpace(heap()->map_space());
if (marking_deque_.IsFull()) return;
LargeObjectIterator lo_it(heap()->lo_space());
DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it);
DiscoverGreyObjectsWithIterator(&lo_it);
if (marking_deque_.IsFull()) return;
marking_deque_.ClearOverflowed();
......
......@@ -205,18 +205,17 @@ class MarkingDeque {
void SetOverflowed() { overflowed_ = true; }
// Push the (marked) object on the marking stack if there is room,
// otherwise mark the object as overflowed and wait for a rescan of the
// heap.
INLINE(void PushBlack(HeapObject* object)) {
// Push the (marked) object on the marking stack if there is room, otherwise
// mark the deque as overflowed and wait for a rescan of the heap.
INLINE(bool PushBlack(HeapObject* object)) {
DCHECK(object->IsHeapObject());
if (IsFull()) {
Marking::BlackToGrey(object);
MemoryChunk::IncrementLiveBytesFromGC(object, -object->Size());
SetOverflowed();
return false;
} else {
array_[top_] = object;
top_ = ((top_ + 1) & mask_);
return true;
}
}
......@@ -248,16 +247,16 @@ class MarkingDeque {
}
}
INLINE(void UnshiftBlack(HeapObject* object)) {
INLINE(bool UnshiftBlack(HeapObject* object)) {
DCHECK(object->IsHeapObject());
DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
if (IsFull()) {
Marking::BlackToGrey(object);
MemoryChunk::IncrementLiveBytesFromGC(object, -object->Size());
SetOverflowed();
return false;
} else {
bottom_ = ((bottom_ - 1) & mask_);
array_[bottom_] = object;
return true;
}
}
......@@ -761,11 +760,12 @@ class MarkCompactCollector {
//
// After: Live objects are marked and non-live objects are unmarked.
friend class RootMarkingVisitor;
friend class MarkingVisitor;
friend class MarkCompactMarkingVisitor;
friend class CodeMarkingVisitor;
friend class MarkCompactMarkingVisitor;
friend class MarkingVisitor;
friend class RootMarkingVisitor;
friend class SharedFunctionInfoMarkingVisitor;
friend class IncrementalMarkingMarkingVisitor;
// Mark code objects that are active on the stack to prevent them
// from being flushed.
......@@ -778,6 +778,14 @@ class MarkCompactCollector {
void AfterMarking();
// Pushes a black object onto the marking stack and accounts for live bytes.
// Note that this assumes live bytes have not yet been counted.
INLINE(void PushBlack(HeapObject* obj));
// Unshifts a black object into the marking stack and accounts for live bytes.
// Note that this assumes lives bytes have already been counted.
INLINE(void UnshiftBlack(HeapObject* obj));
// Marks the object black and pushes it on the marking stack.
// This is for non-incremental marking only.
INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit));
......@@ -826,6 +834,14 @@ class MarkCompactCollector {
// flag on the marking stack.
void RefillMarkingDeque();
// Helper methods for refilling the marking stack by discovering grey objects
// on various pages of the heap. Used by {RefillMarkingDeque} only.
template <class T>
void DiscoverGreyObjectsWithIterator(T* it);
void DiscoverGreyObjectsOnPage(MemoryChunk* p);
void DiscoverGreyObjectsInSpace(PagedSpace* space);
void DiscoverGreyObjectsInNewSpace();
// Callback function for telling whether the object *p is an unmarked
// heap object.
static bool IsUnmarkedHeapObject(Object** p);
......
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