From 1345f811bf6a3ab9376cfbed6f08084662b32a4d Mon Sep 17 00:00:00 2001 From: ulan Date: Fri, 7 Aug 2015 03:20:40 -0700 Subject: [PATCH] Make sure that memory reducer makes progress in incremental marking even if there are no idle notifications. BUG=chromium:515873 LOG=NO Review URL: https://codereview.chromium.org/1274633003 Cr-Commit-Position: refs/heads/master@{#30062} --- src/heap/heap.cc | 13 +++++++++++++ src/heap/heap.h | 4 ++++ src/heap/memory-reducer.cc | 25 ++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 95195450ad0..c93b6d15384 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -4778,6 +4778,19 @@ void Heap::ReduceNewSpaceSize() { } +void Heap::FinalizeIncrementalMarkingIfComplete(const char* comment) { + if (FLAG_overapproximate_weak_closure && + (incremental_marking()->IsReadyToOverApproximateWeakClosure() || + (!incremental_marking()->weak_closure_was_overapproximated() && + mark_compact_collector_.marking_deque()->IsEmpty()))) { + OverApproximateWeakClosure(comment); + } else if (incremental_marking()->IsComplete() || + (mark_compact_collector_.marking_deque()->IsEmpty())) { + CollectAllGarbage(kNoGCFlags, comment); + } +} + + bool Heap::TryFinalizeIdleIncrementalMarking( double idle_time_in_ms, size_t size_of_objects, size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { diff --git a/src/heap/heap.h b/src/heap/heap.h index 6666b2c8238..690837c4f4c 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -867,6 +867,8 @@ class Heap { intptr_t step_size_in_bytes, double deadline_in_ms, IncrementalMarking::StepActions step_actions); + void FinalizeIncrementalMarkingIfComplete(const char* comment); + inline void increment_scan_on_scavenge_pages() { scan_on_scavenge_pages_++; if (FLAG_gc_verbose) { @@ -1650,6 +1652,8 @@ class Heap { bool HasHighFragmentation(); bool HasHighFragmentation(intptr_t used, intptr_t committed); + bool ShouldOptimizeForMemoryUsage() { return optimize_for_memory_usage_; } + protected: // Methods made available to tests. diff --git a/src/heap/memory-reducer.cc b/src/heap/memory-reducer.cc index 25378b59112..c297c4dde24 100644 --- a/src/heap/memory-reducer.cc +++ b/src/heap/memory-reducer.cc @@ -45,12 +45,35 @@ void MemoryReducer::NotifyTimer(const Event& event) { if (state_.action == kRun) { DCHECK(heap()->incremental_marking()->IsStopped()); DCHECK(FLAG_incremental_marking); - heap()->StartIdleIncrementalMarking(); if (FLAG_trace_gc_verbose) { PrintIsolate(heap()->isolate(), "Memory reducer: started GC #%d\n", state_.started_gcs); } + if (heap()->ShouldOptimizeForMemoryUsage()) { + // Do full GC if memory usage has higher priority than latency. This is + // important for background tabs that do not send idle notifications. + heap()->CollectAllGarbage(Heap::kReduceMemoryFootprintMask, + "memory reducer"); + } else { + heap()->StartIdleIncrementalMarking(); + } } else if (state_.action == kWait) { + if (!heap()->incremental_marking()->IsStopped() && + heap()->ShouldOptimizeForMemoryUsage()) { + // Make progress with pending incremental marking if memory usage has + // higher priority than latency. This is important for background tabs + // that do not send idle notifications. + const int kIncrementalMarkingDelayMs = 500; + double deadline = heap()->MonotonicallyIncreasingTimeInMs() + + kIncrementalMarkingDelayMs; + heap()->AdvanceIncrementalMarking( + 0, deadline, i::IncrementalMarking::StepActions( + i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, + i::IncrementalMarking::FORCE_MARKING, + i::IncrementalMarking::FORCE_COMPLETION)); + heap()->FinalizeIncrementalMarkingIfComplete( + "Memory reducer: finalize incremental marking"); + } // Re-schedule the timer. ScheduleTimer(state_.next_gc_start_ms - event.time_ms); if (FLAG_trace_gc_verbose) {