diff --git a/src/heap.cc b/src/heap.cc index 0497ad5f6a..ccf9b47a35 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -3757,14 +3757,21 @@ bool Heap::IdleNotification() { static const int kIdlesBeforeScavenge = 4; static const int kIdlesBeforeMarkSweep = 7; static const int kIdlesBeforeMarkCompact = 8; + static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; + static const int kGCsBetweenCleanup = 4; static int number_idle_notifications = 0; static int last_gc_count = gc_count_; bool uncommit = true; bool finished = false; - if (last_gc_count == gc_count_) { - number_idle_notifications++; + // Reset the number of idle notifications received when a number of + // GCs have taken place. This allows another round of cleanup based + // on idle notifications if enough work has been carried out to + // provoke a number of garbage collections. + if (gc_count_ < last_gc_count + kGCsBetweenCleanup) { + number_idle_notifications = + Min(number_idle_notifications + 1, kMaxIdleCount); } else { number_idle_notifications = 0; last_gc_count = gc_count_; @@ -3779,7 +3786,6 @@ bool Heap::IdleNotification() { } new_space_.Shrink(); last_gc_count = gc_count_; - } else if (number_idle_notifications == kIdlesBeforeMarkSweep) { // Before doing the mark-sweep collections we clear the // compilation cache to avoid hanging on to source code and @@ -3794,7 +3800,6 @@ bool Heap::IdleNotification() { CollectAllGarbage(true); new_space_.Shrink(); last_gc_count = gc_count_; - number_idle_notifications = 0; finished = true; } else if (contexts_disposed_ > 0) { @@ -3813,6 +3818,11 @@ bool Heap::IdleNotification() { number_idle_notifications = 0; uncommit = false; } + } else if (number_idle_notifications > kIdlesBeforeMarkCompact) { + // If we have received more than kIdlesBeforeMarkCompact idle + // notifications we do not perform any cleanup because we don't + // expect to gain much by doing so. + finished = true; } // Make sure that we have no pending context disposals and