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 8def9005e647b344685050b96c19bac4fa1e3e98..03232fa2cfb24d7d14ef4ef59369a36d41172aa8 100644 |
--- a/src/heap/gc-idle-time-handler.cc |
+++ b/src/heap/gc-idle-time-handler.cc |
@@ -68,9 +68,40 @@ size_t GCIdleTimeHandler::EstimateMarkCompactTime( |
} |
+size_t GCIdleTimeHandler::EstimateScavengeTime( |
+ size_t new_space_size, size_t scavenge_speed_in_bytes_per_ms) { |
+ if (scavenge_speed_in_bytes_per_ms == 0) { |
+ scavenge_speed_in_bytes_per_ms = kInitialConservativeScavengeSpeed; |
+ } |
+ return new_space_size / scavenge_speed_in_bytes_per_ms; |
+} |
+ |
+ |
+// The following logic is implemented by the controller: |
+// (1) If the new space is almost full and we can effort a Scavenge, then a |
+// Scavenge is performed. |
+// (2) If there is currently no MarkCompact idle round going on, we start a |
+// new idle round if enough garbage was created or we received a context |
+// disposal event. Otherwise we do not perform garbage collection to keep |
+// system utilization low. |
+// (3) If incremental marking is done, we perform a full garbage collection |
+// if context was disposed or 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. |
+// (4) If sweeping is in progress and we received a large enough idle time |
+// request, we finalize sweeping here. |
+// (5) If incremental marking is in progress, we perform a marking step. Note, |
+// that this currently may trigger a full garbage collection. |
GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms, |
HeapState heap_state) { |
- if (IsIdleRoundFinished()) { |
+ if (heap_state.available_new_space_memory < kNewSpaceAlmostFullTreshold && |
+ idle_time_in_ms >= |
+ EstimateScavengeTime(heap_state.new_space_capacity, |
+ heap_state.scavenge_speed_in_bytes_per_ms)) { |
+ return GCIdleTimeAction::Scavenge(); |
+ } |
+ if (IsMarkCompactIdleRoundFinished()) { |
if (EnoughGarbageSinceLastIdleRound() || heap_state.contexts_disposed > 0) { |
StartIdleRound(); |
} else { |