[heap] Support for minor MC marking during incremental marking part 1

First part of relanding d2c093bcaf.

BUG=chromium:651354

Change-Id: I34ebea331d482d5039626ccff48b11ad175793ee
Reviewed-on: https://chromium-review.googlesource.com/448518
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43541}
This commit is contained in:
Michael Lippautz 2017-03-02 13:53:25 +01:00 committed by Commit Bot
parent 4a80642e54
commit 12963af725
4 changed files with 91 additions and 68 deletions

View File

@ -1332,12 +1332,12 @@ void MarkCompactCollector::PrepareForCodeFlushing() {
heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); heap()->isolate()->compilation_cache()->IterateFunctions(&visitor);
heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); heap()->isolate()->handle_scope_implementer()->Iterate(&visitor);
ProcessMarkingDeque<MarkCompactMode::FULL>(); ProcessMarkingDeque<MarkingMode::FULL>();
} }
// Visitor class for marking heap roots. // Visitor class for marking heap roots.
template <MarkCompactMode mode> template <MarkingMode mode>
class RootMarkingVisitor : public ObjectVisitor { class RootMarkingVisitor : public ObjectVisitor {
public: public:
explicit RootMarkingVisitor(Heap* heap) explicit RootMarkingVisitor(Heap* heap)
@ -1359,7 +1359,7 @@ class RootMarkingVisitor : public ObjectVisitor {
HeapObject* object = HeapObject::cast(*p); HeapObject* object = HeapObject::cast(*p);
if (mode == MarkCompactMode::YOUNG_GENERATION && if (mode == MarkingMode::YOUNG_GENERATION &&
!collector_->heap()->InNewSpace(object)) !collector_->heap()->InNewSpace(object))
return; return;
@ -1367,15 +1367,15 @@ class RootMarkingVisitor : public ObjectVisitor {
Map* map = object->map(); Map* map = object->map();
// Mark the object. // Mark the object.
ObjectMarking::WhiteToBlack(object); ObjectMarking::WhiteToBlack<mode>(object);
switch (mode) { switch (mode) {
case MarkCompactMode::FULL: { case MarkingMode::FULL: {
// Mark the map pointer and body, and push them on the marking stack. // Mark the map pointer and body, and push them on the marking stack.
collector_->MarkObject(map); collector_->MarkObject(map);
MarkCompactMarkingVisitor::IterateBody(map, object); MarkCompactMarkingVisitor::IterateBody(map, object);
} break; } break;
case MarkCompactMode::YOUNG_GENERATION: case MarkingMode::YOUNG_GENERATION:
StaticYoungGenerationMarkingVisitor::IterateBody(map, object); StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
break; break;
} }
@ -1950,7 +1950,7 @@ bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap,
} }
void MarkCompactCollector::MarkStringTable( void MarkCompactCollector::MarkStringTable(
RootMarkingVisitor<MarkCompactMode::FULL>* visitor) { RootMarkingVisitor<MarkingMode::FULL>* visitor) {
StringTable* string_table = heap()->string_table(); StringTable* string_table = heap()->string_table();
// Mark the string table itself. // Mark the string table itself.
if (ObjectMarking::IsWhite(string_table)) { if (ObjectMarking::IsWhite(string_table)) {
@ -1959,11 +1959,11 @@ void MarkCompactCollector::MarkStringTable(
} }
// Explicitly mark the prefix. // Explicitly mark the prefix.
string_table->IteratePrefix(visitor); string_table->IteratePrefix(visitor);
ProcessMarkingDeque<MarkCompactMode::FULL>(); ProcessMarkingDeque<MarkingMode::FULL>();
} }
void MarkCompactCollector::MarkRoots( void MarkCompactCollector::MarkRoots(
RootMarkingVisitor<MarkCompactMode::FULL>* visitor) { RootMarkingVisitor<MarkingMode::FULL>* visitor) {
// Mark the heap roots including global variables, stack variables, // Mark the heap roots including global variables, stack variables,
// etc., and all objects reachable from them. // etc., and all objects reachable from them.
heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
@ -1973,8 +1973,8 @@ void MarkCompactCollector::MarkRoots(
// There may be overflowed objects in the heap. Visit them now. // There may be overflowed objects in the heap. Visit them now.
while (marking_deque()->overflowed()) { while (marking_deque()->overflowed()) {
RefillMarkingDeque<MarkCompactMode::FULL>(); RefillMarkingDeque<MarkingMode::FULL>();
EmptyMarkingDeque<MarkCompactMode::FULL>(); EmptyMarkingDeque<MarkingMode::FULL>();
} }
} }
@ -2014,7 +2014,7 @@ void MarkCompactCollector::MarkImplicitRefGroups(
// Before: the marking stack contains zero or more heap object pointers. // Before: the marking stack contains zero or more heap object pointers.
// After: the marking stack is empty, and all objects reachable from the // After: the marking stack is empty, and all objects reachable from the
// marking stack have been marked, or are overflowed in the heap. // marking stack have been marked, or are overflowed in the heap.
template <MarkCompactMode mode> template <MarkingMode mode>
void MarkCompactCollector::EmptyMarkingDeque() { void MarkCompactCollector::EmptyMarkingDeque() {
while (!marking_deque()->IsEmpty()) { while (!marking_deque()->IsEmpty()) {
HeapObject* object = marking_deque()->Pop(); HeapObject* object = marking_deque()->Pop();
@ -2026,11 +2026,11 @@ void MarkCompactCollector::EmptyMarkingDeque() {
Map* map = object->map(); Map* map = object->map();
switch (mode) { switch (mode) {
case MarkCompactMode::FULL: { case MarkingMode::FULL: {
MarkObject(map); MarkObject(map);
MarkCompactMarkingVisitor::IterateBody(map, object); MarkCompactMarkingVisitor::IterateBody(map, object);
} break; } break;
case MarkCompactMode::YOUNG_GENERATION: { case MarkingMode::YOUNG_GENERATION: {
DCHECK(ObjectMarking::IsBlack(object)); DCHECK(ObjectMarking::IsBlack(object));
StaticYoungGenerationMarkingVisitor::IterateBody(map, object); StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
} break; } break;
@ -2044,7 +2044,7 @@ void MarkCompactCollector::EmptyMarkingDeque() {
// before sweeping completes. If sweeping completes, there are no remaining // before sweeping completes. If sweeping completes, there are no remaining
// overflowed objects in the heap so the overflow flag on the markings stack // overflowed objects in the heap so the overflow flag on the markings stack
// is cleared. // is cleared.
template <MarkCompactMode mode> template <MarkingMode mode>
void MarkCompactCollector::RefillMarkingDeque() { void MarkCompactCollector::RefillMarkingDeque() {
isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow); isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow);
DCHECK(marking_deque()->overflowed()); DCHECK(marking_deque()->overflowed());
@ -2052,7 +2052,7 @@ void MarkCompactCollector::RefillMarkingDeque() {
DiscoverGreyObjectsInNewSpace(); DiscoverGreyObjectsInNewSpace();
if (marking_deque()->IsFull()) return; if (marking_deque()->IsFull()) return;
if (mode == MarkCompactMode::FULL) { if (mode == MarkingMode::FULL) {
DiscoverGreyObjectsInSpace(heap()->old_space()); DiscoverGreyObjectsInSpace(heap()->old_space());
if (marking_deque()->IsFull()) return; if (marking_deque()->IsFull()) return;
DiscoverGreyObjectsInSpace(heap()->code_space()); DiscoverGreyObjectsInSpace(heap()->code_space());
@ -2072,7 +2072,7 @@ void MarkCompactCollector::RefillMarkingDeque() {
// stack. Before: the marking stack contains zero or more heap object // stack. Before: the marking stack contains zero or more heap object
// pointers. After: the marking stack is empty and there are no overflowed // pointers. After: the marking stack is empty and there are no overflowed
// objects in the heap. // objects in the heap.
template <MarkCompactMode mode> template <MarkingMode mode>
void MarkCompactCollector::ProcessMarkingDeque() { void MarkCompactCollector::ProcessMarkingDeque() {
EmptyMarkingDeque<mode>(); EmptyMarkingDeque<mode>();
while (marking_deque()->overflowed()) { while (marking_deque()->overflowed()) {
@ -2112,7 +2112,7 @@ void MarkCompactCollector::ProcessEphemeralMarking(
} }
ProcessWeakCollections(); ProcessWeakCollections();
work_to_do = !marking_deque()->IsEmpty(); work_to_do = !marking_deque()->IsEmpty();
ProcessMarkingDeque<MarkCompactMode::FULL>(); ProcessMarkingDeque<MarkingMode::FULL>();
} }
CHECK(marking_deque()->IsEmpty()); CHECK(marking_deque()->IsEmpty());
CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace()); CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace());
@ -2129,7 +2129,7 @@ void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
if (!code->CanDeoptAt(it.frame()->pc())) { if (!code->CanDeoptAt(it.frame()->pc())) {
Code::BodyDescriptor::IterateBody(code, visitor); Code::BodyDescriptor::IterateBody(code, visitor);
} }
ProcessMarkingDeque<MarkCompactMode::FULL>(); ProcessMarkingDeque<MarkingMode::FULL>();
return; return;
} }
} }
@ -2313,7 +2313,7 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
PostponeInterruptsScope postpone(isolate()); PostponeInterruptsScope postpone(isolate());
StaticYoungGenerationMarkingVisitor::Initialize(heap()); StaticYoungGenerationMarkingVisitor::Initialize(heap());
RootMarkingVisitor<MarkCompactMode::YOUNG_GENERATION> root_visitor(heap()); RootMarkingVisitor<MarkingMode::YOUNG_GENERATION> root_visitor(heap());
marking_deque()->StartUsing(); marking_deque()->StartUsing();
@ -2323,7 +2323,7 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
{ {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_ROOTS); TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_ROOTS);
heap()->IterateRoots(&root_visitor, VISIT_ALL_IN_SCAVENGE); heap()->IterateRoots(&root_visitor, VISIT_ALL_IN_SCAVENGE);
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>(); ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
} }
{ {
@ -2340,20 +2340,20 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
reinterpret_cast<Address>(addr)); reinterpret_cast<Address>(addr));
}); });
}); });
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>(); ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
} }
{ {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK); TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK);
heap()->VisitEncounteredWeakCollections(&root_visitor); heap()->VisitEncounteredWeakCollections(&root_visitor);
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>(); ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
} }
if (is_code_flushing_enabled()) { if (is_code_flushing_enabled()) {
TRACE_GC(heap()->tracer(), TRACE_GC(heap()->tracer(),
GCTracer::Scope::MINOR_MC_MARK_CODE_FLUSH_CANDIDATES); GCTracer::Scope::MINOR_MC_MARK_CODE_FLUSH_CANDIDATES);
code_flusher()->IteratePointersToFromSpace(&root_visitor); code_flusher()->IteratePointersToFromSpace(&root_visitor);
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>(); ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
} }
{ {
@ -2364,7 +2364,7 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
->global_handles() ->global_handles()
->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>( ->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>(
&root_visitor); &root_visitor);
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>(); ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
} }
marking_deque()->StopUsing(); marking_deque()->StopUsing();
@ -2401,7 +2401,7 @@ void MarkCompactCollector::MarkLiveObjects() {
PrepareForCodeFlushing(); PrepareForCodeFlushing();
} }
RootMarkingVisitor<MarkCompactMode::FULL> root_visitor(heap()); RootMarkingVisitor<MarkingMode::FULL> root_visitor(heap());
{ {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_ROOTS); TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_ROOTS);
@ -2433,7 +2433,7 @@ void MarkCompactCollector::MarkLiveObjects() {
GCTracer::Scope::MC_MARK_WEAK_CLOSURE_WEAK_HANDLES); GCTracer::Scope::MC_MARK_WEAK_CLOSURE_WEAK_HANDLES);
heap()->isolate()->global_handles()->IdentifyWeakHandles( heap()->isolate()->global_handles()->IdentifyWeakHandles(
&IsUnmarkedHeapObject); &IsUnmarkedHeapObject);
ProcessMarkingDeque<MarkCompactMode::FULL>(); ProcessMarkingDeque<MarkingMode::FULL>();
} }
// Then we mark the objects. // Then we mark the objects.
@ -2441,7 +2441,7 @@ void MarkCompactCollector::MarkLiveObjects() {
TRACE_GC(heap()->tracer(), TRACE_GC(heap()->tracer(),
GCTracer::Scope::MC_MARK_WEAK_CLOSURE_WEAK_ROOTS); GCTracer::Scope::MC_MARK_WEAK_CLOSURE_WEAK_ROOTS);
heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor); heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
ProcessMarkingDeque<MarkCompactMode::FULL>(); ProcessMarkingDeque<MarkingMode::FULL>();
} }
// Repeat Harmony weak maps marking to mark unmarked objects reachable from // Repeat Harmony weak maps marking to mark unmarked objects reachable from

View File

@ -17,8 +17,6 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
enum class MarkCompactMode { FULL, YOUNG_GENERATION };
// Callback function, returns whether an object is alive. The heap size // Callback function, returns whether an object is alive. The heap size
// of the object is returned in size. It optionally updates the offset // of the object is returned in size. It optionally updates the offset
// to the first live object in the page (only used for old and map objects). // to the first live object in the page (only used for old and map objects).
@ -31,87 +29,103 @@ typedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object);
class CodeFlusher; class CodeFlusher;
class MarkCompactCollector; class MarkCompactCollector;
class MarkingVisitor; class MarkingVisitor;
template <MarkCompactMode mode> template <MarkingMode mode>
class RootMarkingVisitor; class RootMarkingVisitor;
class ObjectMarking : public AllStatic { class ObjectMarking : public AllStatic {
public: public:
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static MarkBit MarkBitFrom(HeapObject* obj) { V8_INLINE static MarkBit MarkBitFrom(HeapObject* obj) {
const Address address = obj->address(); const Address address = obj->address();
MemoryChunk* p = MemoryChunk::FromAddress(address); const MemoryChunk* p = MemoryChunk::FromAddress(address);
return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(address)); return p->markbits<mode>()->MarkBitFromIndex(
p->AddressToMarkbitIndex(address));
} }
template <MarkingMode mode = MarkingMode::FULL>
static Marking::ObjectColor Color(HeapObject* obj) { static Marking::ObjectColor Color(HeapObject* obj) {
return Marking::Color(ObjectMarking::MarkBitFrom(obj)); return Marking::Color(ObjectMarking::MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static bool IsImpossible(HeapObject* obj) { V8_INLINE static bool IsImpossible(HeapObject* obj) {
return Marking::IsImpossible(MarkBitFrom(obj)); return Marking::IsImpossible(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static bool IsBlack(HeapObject* obj) { V8_INLINE static bool IsBlack(HeapObject* obj) {
return Marking::IsBlack(MarkBitFrom(obj)); return Marking::IsBlack(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static bool IsWhite(HeapObject* obj) { V8_INLINE static bool IsWhite(HeapObject* obj) {
return Marking::IsWhite(MarkBitFrom(obj)); return Marking::IsWhite(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static bool IsGrey(HeapObject* obj) { V8_INLINE static bool IsGrey(HeapObject* obj) {
return Marking::IsGrey(MarkBitFrom(obj)); return Marking::IsGrey(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static bool IsBlackOrGrey(HeapObject* obj) { V8_INLINE static bool IsBlackOrGrey(HeapObject* obj) {
return Marking::IsBlackOrGrey(MarkBitFrom(obj)); return Marking::IsBlackOrGrey(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void ClearMarkBit(HeapObject* obj) { V8_INLINE static void ClearMarkBit(HeapObject* obj) {
Marking::MarkWhite(MarkBitFrom(obj)); Marking::MarkWhite(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void BlackToWhite(HeapObject* obj) { V8_INLINE static void BlackToWhite(HeapObject* obj) {
DCHECK(IsBlack(obj)); DCHECK(IsBlack<mode>(obj));
MarkBit markbit = MarkBitFrom(obj); MarkBit markbit = MarkBitFrom<mode>(obj);
Marking::BlackToWhite(markbit); Marking::BlackToWhite(markbit);
MemoryChunk::IncrementLiveBytes(obj, -obj->Size()); MemoryChunk::IncrementLiveBytes<mode>(obj, -obj->Size());
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void GreyToWhite(HeapObject* obj) { V8_INLINE static void GreyToWhite(HeapObject* obj) {
DCHECK(IsGrey(obj)); DCHECK(IsGrey<mode>(obj));
Marking::GreyToWhite(MarkBitFrom(obj)); Marking::GreyToWhite(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void BlackToGrey(HeapObject* obj) { V8_INLINE static void BlackToGrey(HeapObject* obj) {
DCHECK(IsBlack(obj)); DCHECK(IsBlack<mode>(obj));
MarkBit markbit = MarkBitFrom(obj); MarkBit markbit = MarkBitFrom<mode>(obj);
Marking::BlackToGrey(markbit); Marking::BlackToGrey(markbit);
MemoryChunk::IncrementLiveBytes(obj, -obj->Size()); MemoryChunk::IncrementLiveBytes<mode>(obj, -obj->Size());
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void WhiteToGrey(HeapObject* obj) { V8_INLINE static void WhiteToGrey(HeapObject* obj) {
DCHECK(IsWhite(obj)); DCHECK(IsWhite<mode>(obj));
Marking::WhiteToGrey(MarkBitFrom(obj)); Marking::WhiteToGrey(MarkBitFrom<mode>(obj));
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void WhiteToBlack(HeapObject* obj) { V8_INLINE static void WhiteToBlack(HeapObject* obj) {
DCHECK(IsWhite(obj)); DCHECK(IsWhite<mode>(obj));
MarkBit markbit = MarkBitFrom(obj); MarkBit markbit = MarkBitFrom<mode>(obj);
Marking::WhiteToBlack(markbit); Marking::WhiteToBlack(markbit);
MemoryChunk::IncrementLiveBytes(obj, obj->Size()); MemoryChunk::IncrementLiveBytes<mode>(obj, obj->Size());
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void GreyToBlack(HeapObject* obj) { V8_INLINE static void GreyToBlack(HeapObject* obj) {
DCHECK(IsGrey(obj)); DCHECK(IsGrey<mode>(obj));
MarkBit markbit = MarkBitFrom(obj); MarkBit markbit = MarkBitFrom<mode>(obj);
Marking::GreyToBlack(markbit); Marking::GreyToBlack(markbit);
MemoryChunk::IncrementLiveBytes(obj, obj->Size()); MemoryChunk::IncrementLiveBytes<mode>(obj, obj->Size());
} }
template <MarkingMode mode = MarkingMode::FULL>
V8_INLINE static void AnyToGrey(HeapObject* obj) { V8_INLINE static void AnyToGrey(HeapObject* obj) {
MarkBit markbit = MarkBitFrom(obj); MarkBit markbit = MarkBitFrom<mode>(obj);
if (Marking::IsBlack(markbit)) { if (Marking::IsBlack(markbit)) {
MemoryChunk::IncrementLiveBytes(obj, -obj->Size()); MemoryChunk::IncrementLiveBytes<mode>(obj, -obj->Size());
} }
Marking::AnyToGrey(markbit); Marking::AnyToGrey(markbit);
} }
@ -631,7 +645,7 @@ class MarkCompactCollector {
friend class MarkCompactMarkingVisitor; friend class MarkCompactMarkingVisitor;
friend class MarkingVisitor; friend class MarkingVisitor;
friend class RecordMigratedSlotVisitor; friend class RecordMigratedSlotVisitor;
template <MarkCompactMode mode> template <MarkingMode mode>
friend class RootMarkingVisitor; friend class RootMarkingVisitor;
friend class SharedFunctionInfoMarkingVisitor; friend class SharedFunctionInfoMarkingVisitor;
friend class StaticYoungGenerationMarkingVisitor; friend class StaticYoungGenerationMarkingVisitor;
@ -660,15 +674,15 @@ class MarkCompactCollector {
INLINE(void MarkObject(HeapObject* obj)); INLINE(void MarkObject(HeapObject* obj));
// Mark the heap roots and all objects reachable from them. // Mark the heap roots and all objects reachable from them.
void MarkRoots(RootMarkingVisitor<MarkCompactMode::FULL>* visitor); void MarkRoots(RootMarkingVisitor<MarkingMode::FULL>* visitor);
// Mark the string table specially. References to internalized strings from // Mark the string table specially. References to internalized strings from
// the string table are weak. // the string table are weak.
void MarkStringTable(RootMarkingVisitor<MarkCompactMode::FULL>* visitor); void MarkStringTable(RootMarkingVisitor<MarkingMode::FULL>* visitor);
// Mark objects reachable (transitively) from objects in the marking stack // Mark objects reachable (transitively) from objects in the marking stack
// or overflowed in the heap. // or overflowed in the heap.
template <MarkCompactMode mode> template <MarkingMode mode>
void ProcessMarkingDeque(); void ProcessMarkingDeque();
// Mark objects reachable (transitively) from objects in the marking stack // Mark objects reachable (transitively) from objects in the marking stack
@ -692,13 +706,13 @@ class MarkCompactCollector {
// stack. This function empties the marking stack, but may leave // stack. This function empties the marking stack, but may leave
// overflowed objects in the heap, in which case the marking stack's // overflowed objects in the heap, in which case the marking stack's
// overflow flag will be set. // overflow flag will be set.
template <MarkCompactMode mode> template <MarkingMode mode>
void EmptyMarkingDeque(); void EmptyMarkingDeque();
// Refill the marking stack with overflowed objects from the heap. This // Refill the marking stack with overflowed objects from the heap. This
// function either leaves the marking stack full or clears the overflow // function either leaves the marking stack full or clears the overflow
// flag on the marking stack. // flag on the marking stack.
template <MarkCompactMode mode> template <MarkingMode mode>
void RefillMarkingDeque(); void RefillMarkingDeque();
// Helper methods for refilling the marking stack by discovering grey objects // Helper methods for refilling the marking stack by discovering grey objects

View File

@ -226,6 +226,7 @@ void Page::InitializeFreeListCategories() {
} }
} }
template <MarkingMode mode>
void MemoryChunk::IncrementLiveBytes(HeapObject* object, int by) { void MemoryChunk::IncrementLiveBytes(HeapObject* object, int by) {
MemoryChunk::FromAddress(object->address())->IncrementLiveBytes(by); MemoryChunk::FromAddress(object->address())->IncrementLiveBytes(by);
} }

View File

@ -224,6 +224,10 @@ class FreeListCategory {
friend class PagedSpace; friend class PagedSpace;
}; };
// MarkingMode determines which bitmaps and counters should be used when
// accessing marking information on MemoryChunk.
enum class MarkingMode { FULL, YOUNG_GENERATION };
// MemoryChunk represents a memory region owned by a specific space. // MemoryChunk represents a memory region owned by a specific space.
// It is divided into the header and the body. Chunk start is always // It is divided into the header and the body. Chunk start is always
// 1MB aligned. Start of the body is aligned so it can accommodate // 1MB aligned. Start of the body is aligned so it can accommodate
@ -370,6 +374,7 @@ class MemoryChunk {
static const int kAllocatableMemory = kPageSize - kObjectStartOffset; static const int kAllocatableMemory = kPageSize - kObjectStartOffset;
template <MarkingMode mode = MarkingMode::FULL>
static inline void IncrementLiveBytes(HeapObject* object, int by); static inline void IncrementLiveBytes(HeapObject* object, int by);
// Only works if the pointer is in the first kPageSize of the MemoryChunk. // Only works if the pointer is in the first kPageSize of the MemoryChunk.
@ -395,7 +400,9 @@ class MemoryChunk {
static bool IsValid(MemoryChunk* chunk) { return chunk != nullptr; } static bool IsValid(MemoryChunk* chunk) { return chunk != nullptr; }
Address address() { return reinterpret_cast<Address>(this); } Address address() const {
return reinterpret_cast<Address>(const_cast<MemoryChunk*>(this));
}
base::Mutex* mutex() { return mutex_; } base::Mutex* mutex() { return mutex_; }
@ -489,15 +496,16 @@ class MemoryChunk {
} }
} }
inline Bitmap* markbits() { template <MarkingMode mode = MarkingMode::FULL>
inline Bitmap* markbits() const {
return Bitmap::FromAddress(address() + kHeaderSize); return Bitmap::FromAddress(address() + kHeaderSize);
} }
inline uint32_t AddressToMarkbitIndex(Address addr) { inline uint32_t AddressToMarkbitIndex(Address addr) const {
return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2; return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2;
} }
inline Address MarkbitIndexToAddress(uint32_t index) { inline Address MarkbitIndexToAddress(uint32_t index) const {
return this->address() + (index << kPointerSizeLog2); return this->address() + (index << kPointerSizeLog2);
} }