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 ab84a7301bb2d81ca9c50f6f141e125d28e58330..efce981ee8c2037a60216e222384de34cf7408e8 100644 |
--- a/src/heap/gc-idle-time-handler.cc |
+++ b/src/heap/gc-idle-time-handler.cc |
@@ -50,7 +50,6 @@ void GCIdleTimeHandler::HeapState::Print() { |
PrintF("contexts_disposal_rate=%f ", contexts_disposal_rate); |
PrintF("size_of_objects=%" V8_PTR_PREFIX "d ", size_of_objects); |
PrintF("incremental_marking_stopped=%d ", incremental_marking_stopped); |
- PrintF("can_start_incremental_marking=%d ", can_start_incremental_marking); |
PrintF("sweeping_in_progress=%d ", sweeping_in_progress); |
PrintF("has_low_allocation_rate=%d", has_low_allocation_rate); |
PrintF("mark_compact_speed=%" V8_PTR_PREFIX "d ", |
@@ -195,70 +194,15 @@ bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure( |
GCIdleTimeAction GCIdleTimeHandler::NothingOrDone() { |
- if (idle_times_which_made_no_progress_per_mode_ >= |
- kMaxNoProgressIdleTimesPerMode) { |
+ if (idle_times_which_made_no_progress_ >= kMaxNoProgressIdleTimes) { |
return GCIdleTimeAction::Done(); |
} else { |
- idle_times_which_made_no_progress_per_mode_++; |
+ idle_times_which_made_no_progress_++; |
return GCIdleTimeAction::Nothing(); |
} |
} |
-// The idle time handler has three modes and transitions between them |
-// as shown in the diagram: |
-// |
-// kReduceLatency -----> kReduceMemory -----> kDone |
-// ^ ^ | | |
-// | | | | |
-// | +------------------+ | |
-// | | |
-// +----------------------------------------+ |
-// |
-// In kReduceLatency mode the handler only starts incremental marking |
-// if can_start_incremental_marking is false. |
-// In kReduceMemory mode the handler can force a new GC cycle by starting |
-// incremental marking even if can_start_incremental_marking is false. It can |
-// cause at most X idle GCs. |
-// In kDone mode the idle time handler does nothing. |
-// |
-// The initial mode is kReduceLatency. |
-// |
-// kReduceLatency => kReduceMemory transition happens if there were Y |
-// consecutive long idle notifications without any mutator GC. This is our |
-// notion of "mutator is idle". |
-// |
-// kReduceMemory => kDone transition happens after X idle GCs. |
-// |
-// kReduceMemory => kReduceLatency transition happens if N mutator GCs |
-// were performed meaning that the mutator is active. |
-// |
-// kDone => kReduceLatency transition happens if there were M mutator GCs or |
-// context was disposed. |
-// |
-// X = kMaxIdleMarkCompacts |
-// Y = kLongIdleNotificationsBeforeMutatorIsIdle |
-// N = #(idle GCs) |
-// M = kGCsBeforeMutatorIsActive |
-GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms, |
- HeapState heap_state) { |
- Mode next_mode = NextMode(heap_state); |
- |
- if (next_mode != mode_) { |
- mode_ = next_mode; |
- ResetCounters(); |
- } |
- |
- UpdateCounters(idle_time_in_ms); |
- |
- if (mode_ == kDone) { |
- return GCIdleTimeAction::Done(); |
- } else { |
- return Action(idle_time_in_ms, heap_state, mode_ == kReduceMemory); |
- } |
-} |
- |
- |
// The following logic is implemented by the controller: |
// (1) If we don't have any idle time, do nothing, unless a context was |
// disposed, incremental marking is stopped, and the heap is small. Then do |
@@ -267,26 +211,18 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms, |
// we do nothing until the context disposal rate becomes lower. |
// (3) If the new space is almost full and we can affort a scavenge or if the |
// next scavenge will very likely take long, then a scavenge is performed. |
-// (4) If there is currently no MarkCompact idle round going on, we start a |
-// new idle round if enough garbage was created. Otherwise we do not perform |
-// garbage collection to keep system utilization low. |
-// (5) If incremental marking is done, we perform a full garbage collection |
-// if we are allowed to still do full garbage collections during this idle |
-// round or if we are not allowed to start incremental marking. Otherwise we |
-// do not perform garbage collection to keep system utilization low. |
-// (6) If sweeping is in progress and we received a large enough idle time |
+// (4) If sweeping is in progress and we received a large enough idle time |
// request, we finalize sweeping here. |
-// (7) If incremental marking is in progress, we perform a marking step. Note, |
+// (5) If incremental marking is in progress, we perform a marking step. Note, |
// that this currently may trigger a full garbage collection. |
-GCIdleTimeAction GCIdleTimeHandler::Action(double idle_time_in_ms, |
- const HeapState& heap_state, |
- bool reduce_memory) { |
+GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms, |
+ HeapState heap_state) { |
if (static_cast<int>(idle_time_in_ms) <= 0) { |
if (heap_state.incremental_marking_stopped) { |
if (ShouldDoContextDisposalMarkCompact( |
heap_state.contexts_disposed, |
heap_state.contexts_disposal_rate)) { |
- return GCIdleTimeAction::FullGC(false); |
+ return GCIdleTimeAction::FullGC(); |
} |
} |
return GCIdleTimeAction::Nothing(); |
@@ -307,14 +243,6 @@ GCIdleTimeAction GCIdleTimeHandler::Action(double idle_time_in_ms, |
return GCIdleTimeAction::Scavenge(); |
} |
- if (heap_state.incremental_marking_stopped && reduce_memory) { |
- if (ShouldDoMarkCompact(static_cast<size_t>(idle_time_in_ms), |
- heap_state.size_of_objects, |
- heap_state.mark_compact_speed_in_bytes_per_ms)) { |
- return GCIdleTimeAction::FullGC(reduce_memory); |
- } |
- } |
- |
if (heap_state.sweeping_in_progress) { |
if (heap_state.sweeping_completed) { |
return GCIdleTimeAction::FinalizeSweeping(); |
@@ -323,95 +251,16 @@ GCIdleTimeAction GCIdleTimeHandler::Action(double idle_time_in_ms, |
} |
} |
- if (!FLAG_incremental_marking || |
- (heap_state.incremental_marking_stopped && |
- !heap_state.can_start_incremental_marking && !reduce_memory)) { |
- return NothingOrDone(); |
+ if (!FLAG_incremental_marking || heap_state.incremental_marking_stopped) { |
+ return GCIdleTimeAction::Done(); |
} |
size_t step_size = EstimateMarkingStepSize( |
static_cast<size_t>(kIncrementalMarkingStepTimeInMs), |
heap_state.incremental_marking_speed_in_bytes_per_ms); |
- return GCIdleTimeAction::IncrementalMarking(step_size, reduce_memory); |
+ return GCIdleTimeAction::IncrementalMarking(step_size); |
} |
-void GCIdleTimeHandler::UpdateCounters(double idle_time_in_ms) { |
- if (mode_ == kReduceLatency) { |
- 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 >= kMinBackgroundIdleTime) { |
- background_idle_notifications_++; |
- } else if (idle_time_in_ms >= kMinLongIdleTime) { |
- long_idle_notifications_++; |
- } |
- } |
-} |
- |
- |
-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 mark_compacts) { |
- return contexts_disposed > 0 || |
- mark_compacts >= kMarkCompactsBeforeMutatorIsActive; |
-} |
- |
- |
-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); |
-} |
- |
- |
-GCIdleTimeHandler::Mode GCIdleTimeHandler::NextMode( |
- const HeapState& heap_state) { |
- DCHECK(mark_compacts_ >= idle_mark_compacts_); |
- int mutator_gcs = scavenges_ + mark_compacts_ - idle_mark_compacts_; |
- switch (mode_) { |
- case kDone: |
- DCHECK(idle_mark_compacts_ == 0); |
- if (IsMutatorActive(heap_state.contexts_disposed, mark_compacts_)) { |
- return kReduceLatency; |
- } |
- break; |
- case kReduceLatency: |
- if (IsMutatorIdle(long_idle_notifications_, |
- background_idle_notifications_, mutator_gcs)) { |
- return kReduceMemory; |
- } |
- break; |
- case kReduceMemory: |
- if (idle_mark_compacts_ >= kMaxIdleMarkCompacts || |
- (idle_mark_compacts_ > 0 && !next_gc_likely_to_collect_more_)) { |
- return kDone; |
- } |
- if (mutator_gcs > idle_mark_compacts_) { |
- return kReduceLatency; |
- } |
- break; |
- } |
- return mode_; |
-} |
} |
} |