From c9fcaeb336919ce4b76fded8c8059457e9820250 Mon Sep 17 00:00:00 2001 From: mlippautz Date: Tue, 4 Aug 2015 09:56:29 -0700 Subject: [PATCH] GC: Refactor incremental marking interface from heap BUG= Review URL: https://codereview.chromium.org/1273483002 Cr-Commit-Position: refs/heads/master@{#30009} --- src/heap/heap.cc | 38 ++++++++++++++++++++++++++++---------- src/heap/heap.h | 19 +++++++++++++++---- src/heap/incremental-marking.cc | 17 ++++++++++++++--- src/heap/incremental-marking.h | 23 ++++++++++++++++++++++- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/heap/heap.cc b/src/heap/heap.cc index c17a7ac..61dd650 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -769,7 +769,8 @@ void Heap::PreprocessStackTraces() { void Heap::HandleGCRequest() { if (incremental_marking()->request_type() == IncrementalMarking::COMPLETE_MARKING) { - CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt"); + CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt", + incremental_marking()->CallbackFlags()); return; } DCHECK(FLAG_overapproximate_weak_closure); @@ -979,7 +980,7 @@ bool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason, if (!mark_compact_collector()->abort_incremental_marking() && incremental_marking()->IsStopped() && incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { - incremental_marking()->Start(kNoGCFlags); + incremental_marking()->Start(kNoGCFlags, kNoGCCallbackFlags, "GC epilogue"); } return next_gc_likely_to_collect_more; @@ -1006,9 +1007,18 @@ int Heap::NotifyContextDisposed(bool dependant_context) { } +void Heap::StartIncrementalMarking(int gc_flags, + const GCCallbackFlags gc_callback_flags, + const char* reason) { + DCHECK(incremental_marking()->IsStopped()); + incremental_marking()->Start(gc_flags, gc_callback_flags, reason); +} + + void Heap::StartIdleIncrementalMarking() { gc_idle_time_handler_.ResetNoProgressCounter(); - incremental_marking()->Start(kReduceMemoryFootprintMask); + StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags, + "idle"); } @@ -4791,13 +4801,21 @@ GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { double Heap::AdvanceIncrementalMarking( intptr_t step_size_in_bytes, double deadline_in_ms, - IncrementalMarking::ForceCompletionAction completion) { + IncrementalMarking::StepActions step_actions) { DCHECK(!incremental_marking()->IsStopped()); + + if (step_size_in_bytes == 0) { + step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( + static_cast(GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs), + static_cast( + tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond())); + } + double remaining_time_in_ms = 0.0; do { - incremental_marking()->Step(step_size_in_bytes, - IncrementalMarking::NO_GC_VIA_STACK_GUARD, - IncrementalMarking::FORCE_MARKING, completion); + incremental_marking()->Step( + step_size_in_bytes, step_actions.completion_action, + step_actions.force_marking, step_actions.force_completion); remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); } while (remaining_time_in_ms >= 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && @@ -4816,9 +4834,9 @@ bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, result = true; break; case DO_INCREMENTAL_MARKING: { - const double remaining_idle_time_in_ms = AdvanceIncrementalMarking( - action.parameter, deadline_in_ms, - IncrementalMarking::DO_NOT_FORCE_COMPLETION); + const double remaining_idle_time_in_ms = + AdvanceIncrementalMarking(action.parameter, deadline_in_ms, + IncrementalMarking::NoForcedStepActions()); if (remaining_idle_time_in_ms > 0.0) { action.additional_work = TryFinalizeIdleIncrementalMarking( remaining_idle_time_in_ms, heap_state.size_of_objects, diff --git a/src/heap/heap.h b/src/heap/heap.h index 48e3de8..2e5be2b 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -852,6 +852,21 @@ class Heap { // incremental steps. void StartIdleIncrementalMarking(); + // Starts incremental marking assuming incremental marking is currently + // stopped. + void StartIncrementalMarking(int gc_flags, + const GCCallbackFlags gc_callback_flags, + const char* reason = nullptr); + + // Performs incremental marking steps of step_size_in_bytes as long as + // deadline_ins_ms is not reached. step_size_in_bytes can be 0 to compute + // an estimate increment. Returns the remaining time that cannot be used + // for incremental marking anymore because a single step would exceed the + // deadline. + double AdvanceIncrementalMarking( + intptr_t step_size_in_bytes, double deadline_in_ms, + IncrementalMarking::StepActions step_actions); + inline void increment_scan_on_scavenge_pages() { scan_on_scavenge_pages_++; if (FLAG_gc_verbose) { @@ -2231,10 +2246,6 @@ class Heap { GCIdleTimeHandler::HeapState ComputeHeapState(); - double AdvanceIncrementalMarking( - intptr_t step_size_in_bytes, double deadline_in_ms, - IncrementalMarking::ForceCompletionAction completion); - bool PerformIdleTimeAction(GCIdleTimeAction action, GCIdleTimeHandler::HeapState heap_state, double deadline_in_ms); diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc index 6b44771..343fd80 100644 --- a/src/heap/incremental-marking.cc +++ b/src/heap/incremental-marking.cc @@ -16,6 +16,13 @@ namespace v8 { namespace internal { +IncrementalMarking::StepActions IncrementalMarking::NoForcedStepActions() { + return StepActions(IncrementalMarking::NO_GC_VIA_STACK_GUARD, + IncrementalMarking::DO_NOT_FORCE_MARKING, + IncrementalMarking::DO_NOT_FORCE_COMPLETION); +} + + IncrementalMarking::IncrementalMarking(Heap* heap) : heap_(heap), state_(STOPPED), @@ -458,9 +465,12 @@ static void PatchIncrementalMarkingRecordWriteStubs( } -void IncrementalMarking::Start(int mark_compact_flags) { +void IncrementalMarking::Start(int mark_compact_flags, + const GCCallbackFlags gc_callback_flags, + const char* reason) { if (FLAG_trace_incremental_marking) { - PrintF("[IncrementalMarking] Start\n"); + PrintF("[IncrementalMarking] Start (%s)\n", + (reason == nullptr) ? "unknown reason" : reason); } DCHECK(FLAG_incremental_marking); DCHECK(FLAG_incremental_marking_steps); @@ -470,6 +480,7 @@ void IncrementalMarking::Start(int mark_compact_flags) { ResetStepCounters(); + gc_callback_flags_ = gc_callback_flags; was_activated_ = true; if (!heap_->mark_compact_collector()->sweeping_in_progress()) { @@ -812,7 +823,7 @@ void IncrementalMarking::Epilogue() { void IncrementalMarking::OldSpaceStep(intptr_t allocated) { if (IsStopped() && ShouldActivateEvenWithoutIdleNotification()) { - Start(Heap::kNoGCFlags); + Start(Heap::kNoGCFlags, kNoGCCallbackFlags, "old space step"); } else { Step(allocated * kFastMarking / kInitialMarkingSpeed, GC_VIA_STACK_GUARD); } diff --git a/src/heap/incremental-marking.h b/src/heap/incremental-marking.h index 8fe3411..2c63cfc 100644 --- a/src/heap/incremental-marking.h +++ b/src/heap/incremental-marking.h @@ -26,6 +26,21 @@ class IncrementalMarking { enum GCRequestType { COMPLETE_MARKING, OVERAPPROXIMATION }; + struct StepActions { + StepActions(CompletionAction complete_action_, + ForceMarkingAction force_marking_, + ForceCompletionAction force_completion_) + : completion_action(complete_action_), + force_marking(force_marking_), + force_completion(force_completion_) {} + + CompletionAction completion_action; + ForceMarkingAction force_marking; + ForceCompletionAction force_completion; + }; + + static StepActions NoForcedStepActions(); + explicit IncrementalMarking(Heap* heap); static void Initialize(); @@ -67,7 +82,9 @@ class IncrementalMarking { bool WasActivated(); - void Start(int mark_compact_flags); + void Start(int mark_compact_flags, + const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags, + const char* reason = nullptr); void Stop(); @@ -185,6 +202,8 @@ class IncrementalMarking { Heap* heap() const { return heap_; } + GCCallbackFlags CallbackFlags() const { return gc_callback_flags_; } + private: int64_t SpaceLeftInOldSpace(); @@ -243,6 +262,8 @@ class IncrementalMarking { GCRequestType request_type_; + GCCallbackFlags gc_callback_flags_; + DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalMarking); }; } -- 2.7.4