Index: src/heap/gc-idle-time-handler.cc |
diff --git a/src/heap/gc-idle-time-handler.cc b/src/heap/gc-idle-time-handler.cc |
index 40c2eff3f96c56ff8e63cc815029a13704545b82..0a174d533db9be28da9c3f31c249cc2a35a24848 100644 |
--- a/src/heap/gc-idle-time-handler.cc |
+++ b/src/heap/gc-idle-time-handler.cc |
@@ -192,6 +192,17 @@ bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure( |
} |
+GCIdleTimeAction GCIdleTimeHandler::NothingOrDone() { |
+ if (idle_times_which_made_no_progress_per_mode_ >= |
+ kMaxNoProgressIdleTimesPerMode) { |
+ return GCIdleTimeAction::Done(); |
+ } else { |
+ idle_times_which_made_no_progress_per_mode_++; |
+ return GCIdleTimeAction::Nothing(); |
+ } |
+} |
+ |
+ |
// The idle time handler has three modes and transitions between them |
// as shown in the diagram: |
// |
@@ -283,7 +294,7 @@ GCIdleTimeAction GCIdleTimeHandler::Action(double idle_time_in_ms, |
// get the right idle signal. |
if (ShouldDoContextDisposalMarkCompact(heap_state.contexts_disposed, |
heap_state.contexts_disposal_rate)) { |
- return GCIdleTimeAction::Nothing(); |
+ return NothingOrDone(); |
} |
if (ShouldDoScavenge( |
@@ -306,13 +317,13 @@ GCIdleTimeAction GCIdleTimeHandler::Action(double idle_time_in_ms, |
if (heap_state.sweeping_completed) { |
return GCIdleTimeAction::FinalizeSweeping(); |
} else { |
- return GCIdleTimeAction::Nothing(); |
+ return NothingOrDone(); |
} |
} |
if (heap_state.incremental_marking_stopped && |
!heap_state.can_start_incremental_marking && !reduce_memory) { |
- return GCIdleTimeAction::Nothing(); |
+ return NothingOrDone(); |
} |
size_t step_size = EstimateMarkingStepSize( |
@@ -324,19 +335,19 @@ GCIdleTimeAction GCIdleTimeHandler::Action(double idle_time_in_ms, |
void GCIdleTimeHandler::UpdateCounters(double idle_time_in_ms) { |
if (mode_ == kReduceLatency) { |
- int mutator_gcs = scavenges_ + mark_compacts_ - idle_mark_compacts_; |
- if (mutator_gcs > 0) { |
- // There was a mutator GC since the last notification. |
+ int gcs = scavenges_ + mark_compacts_; |
+ if (gcs > 0) { |
+ // There was a GC since the last notification. |
long_idle_notifications_ = 0; |
+ background_idle_notifications_ = 0; |
} |
idle_mark_compacts_ = 0; |
mark_compacts_ = 0; |
scavenges_ = 0; |
- if (idle_time_in_ms >= kMinLongIdleTime) { |
- long_idle_notifications_ += |
- (idle_time_in_ms >= kLargeLongIdleTime) |
- ? kLongIdleNotificationsBeforeMutatorIsIdle |
- : 1; |
+ if (idle_time_in_ms >= kMinBackgroundIdleTime) { |
+ background_idle_notifications_++; |
+ } else if (idle_time_in_ms >= kMinLongIdleTime) { |
+ long_idle_notifications_++; |
} |
} |
} |
@@ -344,20 +355,29 @@ void GCIdleTimeHandler::UpdateCounters(double idle_time_in_ms) { |
void GCIdleTimeHandler::ResetCounters() { |
long_idle_notifications_ = 0; |
+ background_idle_notifications_ = 0; |
idle_mark_compacts_ = 0; |
mark_compacts_ = 0; |
scavenges_ = 0; |
+ idle_times_which_made_no_progress_per_mode_ = 0; |
} |
-bool GCIdleTimeHandler::IsMutatorActive(int contexts_disposed, int gcs) { |
- return contexts_disposed > 0 || gcs >= kGCsBeforeMutatorIsActive; |
+bool GCIdleTimeHandler::IsMutatorActive(int contexts_disposed, |
+ int mark_compacts) { |
+ return contexts_disposed > 0 || |
+ mark_compacts >= kMarkCompactsBeforeMutatorIsActive; |
} |
-bool GCIdleTimeHandler::IsMutatorIdle(int long_idle_notifications, int gcs) { |
- return gcs == 0 && |
- long_idle_notifications >= kLongIdleNotificationsBeforeMutatorIsIdle; |
+bool GCIdleTimeHandler::IsMutatorIdle(int long_idle_notifications, |
+ int background_idle_notifications, |
+ int mutator_gcs) { |
+ return mutator_gcs == 0 && |
+ (long_idle_notifications >= |
+ kLongIdleNotificationsBeforeMutatorIsIdle || |
+ background_idle_notifications >= |
+ kBackgroundIdleNotificationsBeforeMutatorIsIdle); |
} |
@@ -368,12 +388,13 @@ GCIdleTimeHandler::Mode GCIdleTimeHandler::NextMode( |
switch (mode_) { |
case kDone: |
DCHECK(idle_mark_compacts_ == 0); |
- if (IsMutatorActive(heap_state.contexts_disposed, mutator_gcs)) { |
+ if (IsMutatorActive(heap_state.contexts_disposed, mark_compacts_)) { |
return kReduceLatency; |
} |
break; |
case kReduceLatency: |
- if (IsMutatorIdle(long_idle_notifications_, mutator_gcs)) { |
+ if (IsMutatorIdle(long_idle_notifications_, |
+ background_idle_notifications_, mutator_gcs)) { |
return kReduceMemory; |
} |
break; |