Add a flag to over approximate the weak closure during GC

BUG=v8:3862
R=hpayer@chromium.org
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#26532}
This commit is contained in:
jochen 2015-02-09 08:25:47 -08:00 committed by Commit bot
parent 32ad0a3b3d
commit 4357bef53b
10 changed files with 119 additions and 4 deletions

View File

@ -651,7 +651,7 @@ Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
Object* StackGuard::HandleInterrupts() {
if (CheckAndClearInterrupt(GC_REQUEST)) {
isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
isolate_->heap()->HandleGCRequest();
}
if (CheckDebugBreak() || CheckDebugCommand()) {

View File

@ -613,6 +613,8 @@ DEFINE_BOOL(age_code, true,
"old code (required for code flushing)")
DEFINE_BOOL(incremental_marking, true, "use incremental marking")
DEFINE_BOOL(incremental_marking_steps, true, "do incremental marking steps")
DEFINE_BOOL(overapproximate_weak_closure, false,
"overapproximate weak closer to reduce atomic pause time")
DEFINE_BOOL(concurrent_sweeping, true, "use concurrent sweeping")
DEFINE_BOOL(trace_incremental_marking, false,
"trace progress of the incremental marking")

View File

@ -350,6 +350,8 @@ void GCTracer::PrintNVP() const {
PrintF("misc_compaction=%.1f ",
current_.scopes[Scope::MC_UPDATE_MISC_POINTERS]);
PrintF("weak_closure=%.1f ", current_.scopes[Scope::MC_WEAKCLOSURE]);
PrintF("inc_weak_closure=%.1f ",
current_.scopes[Scope::MC_INCREMENTAL_WEAKCLOSURE]);
PrintF("weakcollection_process=%.1f ",
current_.scopes[Scope::MC_WEAKCOLLECTION_PROCESS]);
PrintF("weakcollection_clear=%.1f ",

View File

@ -108,6 +108,7 @@ class GCTracer {
MC_UPDATE_POINTERS_TO_EVACUATED,
MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
MC_UPDATE_MISC_POINTERS,
MC_INCREMENTAL_WEAKCLOSURE,
MC_WEAKCLOSURE,
MC_WEAKCOLLECTION_PROCESS,
MC_WEAKCOLLECTION_CLEAR,

View File

@ -734,6 +734,49 @@ void Heap::GarbageCollectionEpilogue() {
}
void Heap::HandleGCRequest() {
if (incremental_marking()->request_type() ==
IncrementalMarking::COMPLETE_MARKING) {
CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
return;
}
DCHECK(FLAG_overapproximate_weak_closure);
DCHECK(!incremental_marking()->weak_closure_was_overapproximated());
OverApproximateWeakClosure("GC interrupt");
}
void Heap::OverApproximateWeakClosure(const char* gc_reason) {
if (FLAG_trace_incremental_marking) {
PrintF("[IncrementalMarking] Overapproximate weak closure (%s).\n",
gc_reason);
}
{
GCCallbacksScope scope(this);
if (scope.CheckReenter()) {
AllowHeapAllocation allow_allocation;
GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
VMState<EXTERNAL> state(isolate_);
HandleScope handle_scope(isolate_);
CallGCPrologueCallbacks(kGCTypeMarkSweepCompact, kNoGCCallbackFlags);
}
}
mark_compact_collector()->OverApproximateWeakClosure();
incremental_marking()->set_should_hurry(false);
incremental_marking()->set_weak_closure_was_overapproximated(true);
{
GCCallbacksScope scope(this);
if (scope.CheckReenter()) {
AllowHeapAllocation allow_allocation;
GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
VMState<EXTERNAL> state(isolate_);
HandleScope handle_scope(isolate_);
CallGCEpilogueCallbacks(kGCTypeMarkSweepCompact, kNoGCCallbackFlags);
}
}
}
void Heap::CollectAllGarbage(int flags, const char* gc_reason,
const v8::GCCallbackFlags gc_callback_flags) {
// Since we are ignoring the return value, the exact choice of space does

View File

@ -759,6 +759,15 @@ class Heap {
// Making the heap iterable requires us to abort incremental marking.
static const int kMakeHeapIterableMask = kAbortIncrementalMarkingMask;
// Invoked when GC was requested via the stack guard.
void HandleGCRequest();
// Attempt to over-approximate the weak closure by marking object groups and
// implicit references from global handles, but don't atomically complete
// marking. If we continue to mark incrementally, we might have marked
// objects that die later.
void OverApproximateWeakClosure(const char* gc_reason);
// Performs a full garbage collection. If (flags & kMakeHeapIterableMask) is
// non-zero, then the slower precise sweeper is used, which leaves the heap
// in a state where we can iterate over the heap visiting all objects.

View File

@ -28,7 +28,9 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
idle_marking_delay_counter_(0),
no_marking_scope_depth_(0),
unscanned_bytes_of_large_object_(0),
was_activated_(false) {}
was_activated_(false),
weak_closure_was_overapproximated_(false),
request_type_(COMPLETE_MARKING) {}
void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot,
@ -771,6 +773,18 @@ void IncrementalMarking::Finalize() {
}
void IncrementalMarking::OverApproximateWeakClosure() {
DCHECK(FLAG_overapproximate_weak_closure);
DCHECK(!weak_closure_was_overapproximated_);
if (FLAG_trace_incremental_marking) {
PrintF("[IncrementalMarking] requesting weak closure overapproximation.\n");
}
set_should_hurry(true);
request_type_ = OVERAPPROXIMATION;
heap_->isolate()->stack_guard()->RequestGC();
}
void IncrementalMarking::MarkingComplete(CompletionAction action) {
state_ = COMPLETE;
// We will set the stack guard to request a GC now. This will mean the rest
@ -783,12 +797,16 @@ void IncrementalMarking::MarkingComplete(CompletionAction action) {
PrintF("[IncrementalMarking] Complete (normal).\n");
}
if (action == GC_VIA_STACK_GUARD) {
request_type_ = COMPLETE_MARKING;
heap_->isolate()->stack_guard()->RequestGC();
}
}
void IncrementalMarking::Epilogue() { was_activated_ = false; }
void IncrementalMarking::Epilogue() {
was_activated_ = false;
weak_closure_was_overapproximated_ = false;
}
void IncrementalMarking::OldSpaceStep(intptr_t allocated) {
@ -931,7 +949,13 @@ intptr_t IncrementalMarking::Step(intptr_t allocated_bytes,
if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) {
if (completion == FORCE_COMPLETION ||
IsIdleMarkingDelayCounterLimitReached()) {
MarkingComplete(action);
if (FLAG_overapproximate_weak_closure &&
!weak_closure_was_overapproximated_ &&
action == GC_VIA_STACK_GUARD) {
OverApproximateWeakClosure();
} else {
MarkingComplete(action);
}
} else {
IncrementIdleMarkingDelayCounter();
}

View File

@ -24,6 +24,8 @@ class IncrementalMarking {
enum ForceCompletionAction { FORCE_COMPLETION, DO_NOT_FORCE_COMPLETION };
enum GCRequestType { COMPLETE_MARKING, OVERAPPROXIMATION };
explicit IncrementalMarking(Heap* heap);
static void Initialize();
@ -36,6 +38,13 @@ class IncrementalMarking {
bool should_hurry() { return should_hurry_; }
void set_should_hurry(bool val) { should_hurry_ = val; }
bool weak_closure_was_overapproximated() const {
return weak_closure_was_overapproximated_;
}
void set_weak_closure_was_overapproximated(bool val) {
weak_closure_was_overapproximated_ = val;
}
inline bool IsStopped() { return state() == STOPPED; }
INLINE(bool IsMarking()) { return state() >= MARKING; }
@ -44,6 +53,8 @@ class IncrementalMarking {
inline bool IsComplete() { return state() == COMPLETE; }
GCRequestType request_type() const { return request_type_; }
bool WorthActivating();
bool ShouldActivate();
@ -66,6 +77,8 @@ class IncrementalMarking {
void Abort();
void OverApproximateWeakClosure();
void MarkingComplete(CompletionAction action);
void Epilogue();
@ -228,6 +241,10 @@ class IncrementalMarking {
bool was_activated_;
bool weak_closure_was_overapproximated_;
GCRequestType request_type_;
DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalMarking);
};
}

View File

@ -2161,6 +2161,21 @@ void MarkCompactCollector::UncommitMarkingDeque() {
}
void MarkCompactCollector::OverApproximateWeakClosure() {
GCTracer::Scope gc_scope(heap()->tracer(),
GCTracer::Scope::MC_INCREMENTAL_WEAKCLOSURE);
RootMarkingVisitor root_visitor(heap());
isolate()->global_handles()->IterateObjectGroups(
&root_visitor, &IsUnmarkedHeapObjectWithHeap);
MarkImplicitRefGroups();
// Remove object groups after marking phase.
heap()->isolate()->global_handles()->RemoveObjectGroups();
heap()->isolate()->global_handles()->RemoveImplicitRefGroups();
}
void MarkCompactCollector::MarkLiveObjects() {
GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK);
double start_time = 0.0;

View File

@ -672,6 +672,8 @@ class MarkCompactCollector {
void UncommitMarkingDeque();
void OverApproximateWeakClosure();
private:
class SweeperTask;