[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:
parent
4a80642e54
commit
12963af725
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user