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:
parent
32ad0a3b3d
commit
4357bef53b
@ -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()) {
|
||||
|
@ -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")
|
||||
|
@ -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 ",
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -672,6 +672,8 @@ class MarkCompactCollector {
|
||||
|
||||
void UncommitMarkingDeque();
|
||||
|
||||
void OverApproximateWeakClosure();
|
||||
|
||||
private:
|
||||
class SweeperTask;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user