| 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;
|
|
|