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 096412d578bc6b33693fb9d55aeafeb50f5d416b..b51b53b107392ee9aa2b46e399fc66da3347f1f9 100644 |
--- a/src/heap/gc-idle-time-handler.cc |
+++ b/src/heap/gc-idle-time-handler.cc |
@@ -119,13 +119,17 @@ bool GCIdleTimeHandler::ShouldDoScavenge( |
// It is better to do full GC for the background tab. |
return false; |
} |
- size_t new_space_allocation_limit = |
- kMaxScheduledIdleTime * scavenge_speed_in_bytes_per_ms; |
+ |
+ // Calculates how much memory are we able to scavenge in |
+ // kMaxFrameRenderingIdleTime ms. If scavenge_speed_in_bytes_per_ms is 0 we |
+ // will take care of this later. |
+ size_t idle_new_space_allocation_limit = |
+ kMaxFrameRenderingIdleTime * scavenge_speed_in_bytes_per_ms; |
// If the limit is larger than the new space size, then scavenging used to be |
// really fast. We can take advantage of the whole new space. |
- if (new_space_allocation_limit > new_space_size) { |
- new_space_allocation_limit = new_space_size; |
+ if (idle_new_space_allocation_limit > new_space_size) { |
+ idle_new_space_allocation_limit = new_space_size; |
} |
// We do not know the allocation throughput before the first scavenge. |
@@ -134,31 +138,43 @@ bool GCIdleTimeHandler::ShouldDoScavenge( |
// We have to trigger scavenge before we reach the end of new space. |
size_t adjust_limit = new_space_allocation_throughput_in_bytes_per_ms * |
kTimeUntilNextIdleEvent; |
- if (adjust_limit > new_space_allocation_limit) { |
- new_space_allocation_limit = 0; |
+ if (adjust_limit > idle_new_space_allocation_limit) { |
+ idle_new_space_allocation_limit = 0; |
} else { |
- new_space_allocation_limit -= adjust_limit; |
+ idle_new_space_allocation_limit -= adjust_limit; |
} |
} |
- if (new_space_allocation_throughput_in_bytes_per_ms < |
- kLowAllocationThroughput) { |
- new_space_allocation_limit = |
- Min(new_space_allocation_limit, |
- static_cast<size_t>(new_space_size * kConservativeTimeRatio)); |
- } |
- |
// The allocated new space limit to trigger a scavange has to be at least |
// kMinimumNewSpaceSizeToPerformScavenge. |
- if (new_space_allocation_limit < kMinimumNewSpaceSizeToPerformScavenge) { |
- new_space_allocation_limit = kMinimumNewSpaceSizeToPerformScavenge; |
+ if (idle_new_space_allocation_limit < kMinimumNewSpaceSizeToPerformScavenge) { |
+ idle_new_space_allocation_limit = kMinimumNewSpaceSizeToPerformScavenge; |
} |
+ // Set an initial scavenge speed if it is unknown. |
if (scavenge_speed_in_bytes_per_ms == 0) { |
scavenge_speed_in_bytes_per_ms = kInitialConservativeScavengeSpeed; |
} |
- if (new_space_allocation_limit <= used_new_space_size) { |
+ // We apply a max factor to the new space size to make sure that a slowly |
+ // allocating application still leaves enough of wiggle room to schedule a |
+ // scavenge. |
+ size_t max_limit; |
+ const double kMaxNewSpaceSizeFactorLongIdleTimes = 0.5; |
+ const double kMaxNewSpaceSizeFactorShortIdleTimes = 0.8; |
+ if (idle_time_in_ms > kMaxFrameRenderingIdleTime) { |
+ max_limit = static_cast<size_t>(new_space_size * |
+ kMaxNewSpaceSizeFactorLongIdleTimes); |
+ } else { |
+ max_limit = static_cast<size_t>(new_space_size * |
+ kMaxNewSpaceSizeFactorShortIdleTimes); |
+ } |
+ idle_new_space_allocation_limit = |
+ Min(idle_new_space_allocation_limit, max_limit); |
+ |
+ // We perform a scavenge if we are over the idle new space limit and |
+ // a scavenge fits into the given idle time bucket. |
+ if (idle_new_space_allocation_limit <= used_new_space_size) { |
if (used_new_space_size / scavenge_speed_in_bytes_per_ms <= |
idle_time_in_ms) { |
return true; |