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