From 309c082a7380245866576047c30b57794b8690ac Mon Sep 17 00:00:00 2001 From: hpayer Date: Tue, 28 Apr 2015 05:18:22 -0700 Subject: [PATCH] Shrink new space and uncommit from space in idle notification during long idle times. BUG=chromium:481811 LOG=n Review URL: https://codereview.chromium.org/1108133003 Cr-Commit-Position: refs/heads/master@{#28107} --- src/heap/heap.cc | 38 ++++++++++++++++++++------------------ src/heap/heap.h | 7 ++++--- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 4907030..8d34738 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -4535,17 +4535,8 @@ void Heap::MakeHeapIterable() { } -void Heap::IdleMarkCompact(const char* message) { - bool uncommit = false; - if (gc_count_at_last_idle_gc_ == gc_count_) { - // No GC since the last full GC, the mutator is probably not active. - isolate_->compilation_cache()->Clear(); - uncommit = true; - } - CollectAllGarbage(kReduceMemoryFootprintMask, message); - gc_idle_time_handler_.NotifyIdleMarkCompact(); - gc_count_at_last_idle_gc_ = gc_count_; - if (uncommit) { +void Heap::ReduceNewSpaceSize(bool is_long_idle_notification) { + if (is_long_idle_notification) { new_space_.Shrink(); UncommitFromSpace(); } @@ -4553,7 +4544,8 @@ void Heap::IdleMarkCompact(const char* message) { bool Heap::TryFinalizeIdleIncrementalMarking( - double idle_time_in_ms, size_t size_of_objects, + bool is_long_idle_notification, double idle_time_in_ms, + size_t size_of_objects, size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { if (FLAG_overapproximate_weak_closure && (incremental_marking()->IsReadyToOverApproximateWeakClosure() || @@ -4570,6 +4562,7 @@ bool Heap::TryFinalizeIdleIncrementalMarking( static_cast(idle_time_in_ms), size_of_objects, final_incremental_mark_compact_speed_in_bytes_per_ms))) { CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); + ReduceNewSpaceSize(is_long_idle_notification); return true; } return false; @@ -4598,6 +4591,9 @@ bool Heap::IdleNotification(double deadline_in_seconds) { HistogramTimerScope idle_notification_scope( isolate_->counters()->gc_idle_notification()); double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); + bool is_long_idle_notification = + static_cast(idle_time_in_ms) > + GCIdleTimeHandler::kMaxFrameRenderingIdleTime; GCIdleTimeHandler::HeapState heap_state; heap_state.contexts_disposed = contexts_disposed_; @@ -4607,8 +4603,7 @@ bool Heap::IdleNotification(double deadline_in_seconds) { heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); // TODO(ulan): Start incremental marking only for large heaps. intptr_t limit = old_generation_allocation_limit_; - if (static_cast(idle_time_in_ms) > - GCIdleTimeHandler::kMaxFrameRenderingIdleTime) { + if (is_long_idle_notification) { limit = idle_old_generation_allocation_limit_; } @@ -4663,24 +4658,31 @@ bool Heap::IdleNotification(double deadline_in_seconds) { !mark_compact_collector_.marking_deque()->IsEmpty()); if (remaining_idle_time_in_ms > 0.0) { action.additional_work = TryFinalizeIdleIncrementalMarking( - remaining_idle_time_in_ms, heap_state.size_of_objects, + is_long_idle_notification, remaining_idle_time_in_ms, + heap_state.size_of_objects, heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); } break; } case DO_FULL_GC: { + if (is_long_idle_notification && gc_count_at_last_idle_gc_ == gc_count_) { + isolate_->compilation_cache()->Clear(); + } if (contexts_disposed_) { HistogramTimerScope scope(isolate_->counters()->gc_context()); CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); - gc_idle_time_handler_.NotifyIdleMarkCompact(); - gc_count_at_last_idle_gc_ = gc_count_; } else { - IdleMarkCompact("idle notification: finalize idle round"); + CollectAllGarbage(kReduceMemoryFootprintMask, + "idle notification: finalize idle round"); } + gc_count_at_last_idle_gc_ = gc_count_; + ReduceNewSpaceSize(is_long_idle_notification); + gc_idle_time_handler_.NotifyIdleMarkCompact(); break; } case DO_SCAVENGE: CollectGarbage(NEW_SPACE, "idle notification: scavenge"); + ReduceNewSpaceSize(is_long_idle_notification); break; case DO_FINALIZE_SWEEPING: mark_compact_collector()->EnsureSweepingCompleted(); diff --git a/src/heap/heap.h b/src/heap/heap.h index 2c8a6bc..d019293 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -2069,11 +2069,11 @@ class Heap { void SelectScavengingVisitorsTable(); - void IdleMarkCompact(const char* message); + void ReduceNewSpaceSize(bool is_long_idle_notification); bool TryFinalizeIdleIncrementalMarking( - double idle_time_in_ms, size_t size_of_objects, - size_t mark_compact_speed_in_bytes_per_ms); + bool is_long_idle_notification, double idle_time_in_ms, + size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms); void ClearObjectStats(bool clear_last_time_stats = false); @@ -2117,6 +2117,7 @@ class Heap { IncrementalMarking incremental_marking_; GCIdleTimeHandler gc_idle_time_handler_; + unsigned int gc_count_at_last_idle_gc_; // These two counters are monotomically increasing and never reset. -- 2.7.4