| 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 7c74dcb3dac79d1068e2f26ca3ed7716a5227cdc..0976108c4c6fc00dd3aaa9df1f0dcd3685939ce1 100644
|
| --- a/src/heap/gc-idle-time-handler.cc
|
| +++ b/src/heap/gc-idle-time-handler.cc
|
| @@ -71,30 +71,47 @@ size_t GCIdleTimeHandler::EstimateMarkCompactTime(
|
| }
|
|
|
|
|
| -size_t GCIdleTimeHandler::EstimateScavengeTime(
|
| - size_t new_space_size, size_t scavenge_speed_in_bytes_per_ms) {
|
| +bool GCIdleTimeHandler::DoScavenge(
|
| + size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
|
| + size_t scavenge_speed_in_bytes_per_ms,
|
| + size_t new_space_allocation_throughput_in_bytes_per_ms) {
|
| + size_t 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;
|
| + }
|
| +
|
| + // We do not know the allocation throughput before the first Scavenge.
|
| + // TODO(hpayer): Estimate allocation throughput before the first Scavenge.
|
| + if (new_space_allocation_throughput_in_bytes_per_ms == 0) {
|
| + new_space_allocation_limit = new_space_size * kConservativeTimeRatio;
|
| + } else {
|
| + // We have to trigger scavenge before we reach the end of new space.
|
| + new_space_allocation_limit -=
|
| + new_space_allocation_throughput_in_bytes_per_ms *
|
| + kMaxFrameRenderingIdleTime;
|
| + }
|
| +
|
| 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;
|
| -}
|
| -
|
|
|
| -bool GCIdleTimeHandler::ScavangeMayHappenSoon(
|
| - size_t available_new_space_memory,
|
| - size_t new_space_allocation_throughput_in_bytes_per_ms) {
|
| - if (available_new_space_memory <=
|
| - new_space_allocation_throughput_in_bytes_per_ms *
|
| - kMaxFrameRenderingIdleTime) {
|
| - return true;
|
| + if (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;
|
| + }
|
| }
|
| return false;
|
| }
|
|
|
|
|
| // 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.
|
| +// (1) If the new space is almost full and we can effort a Scavenge or if the
|
| +// next Scavenge will very likely take long, 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
|
| @@ -110,14 +127,13 @@ bool GCIdleTimeHandler::ScavangeMayHappenSoon(
|
| // that this currently may trigger a full garbage collection.
|
| GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
|
| HeapState heap_state) {
|
| - if (ScavangeMayHappenSoon(
|
| - heap_state.available_new_space_memory,
|
| - heap_state.new_space_allocation_throughput_in_bytes_per_ms) &&
|
| - idle_time_in_ms >=
|
| - EstimateScavengeTime(heap_state.new_space_capacity,
|
| - heap_state.scavenge_speed_in_bytes_per_ms)) {
|
| + if (DoScavenge(idle_time_in_ms, heap_state.new_space_capacity,
|
| + heap_state.used_new_space_size,
|
| + heap_state.scavenge_speed_in_bytes_per_ms,
|
| + heap_state.new_space_allocation_throughput_in_bytes_per_ms)) {
|
| return GCIdleTimeAction::Scavenge();
|
| }
|
| +
|
| if (IsMarkCompactIdleRoundFinished()) {
|
| if (EnoughGarbageSinceLastIdleRound() || heap_state.contexts_disposed > 0) {
|
| StartIdleRound();
|
|
|