From 6ead193b51105d1ed5796a7ba417bb62d0323176 Mon Sep 17 00:00:00 2001 From: hpayer Date: Fri, 15 May 2015 09:06:21 -0700 Subject: [PATCH] Make sure that idle scavenges are just performed when enough objects are allocated in new space. BUG= Review URL: https://codereview.chromium.org/1138643003 Cr-Commit-Position: refs/heads/master@{#28428} --- src/heap/gc-idle-time-handler.cc | 19 +++++++++++++------ src/heap/gc-idle-time-handler.h | 3 +++ test/unittests/heap/gc-idle-time-handler-unittest.cc | 12 ++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/heap/gc-idle-time-handler.cc b/src/heap/gc-idle-time-handler.cc index 19c9dab..40c2eff 100644 --- a/src/heap/gc-idle-time-handler.cc +++ b/src/heap/gc-idle-time-handler.cc @@ -122,8 +122,8 @@ bool GCIdleTimeHandler::ShouldDoScavenge( 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. + // 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 = static_cast(new_space_size * kConservativeTimeRatio); @@ -131,10 +131,17 @@ 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) + if (adjust_limit > new_space_allocation_limit) { new_space_allocation_limit = 0; - else + } else { new_space_allocation_limit -= adjust_limit; + } + } + + // 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 (scavenge_speed_in_bytes_per_ms == 0) { @@ -245,8 +252,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms, // a full GC. // (2) If the context disposal rate is high and we cannot perform a full GC, // 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. +// (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. diff --git a/src/heap/gc-idle-time-handler.h b/src/heap/gc-idle-time-handler.h index 3beee16..e76178b 100644 --- a/src/heap/gc-idle-time-handler.h +++ b/src/heap/gc-idle-time-handler.h @@ -136,6 +136,9 @@ class GCIdleTimeHandler { // lower bound for the scavenger speed. static const size_t kInitialConservativeScavengeSpeed = 100 * KB; + // The minimum size of allocated new space objects to trigger a scavenge. + static const size_t kMinimumNewSpaceSizeToPerformScavenge = MB / 2; + // If contexts are disposed at a higher rate a full gc is triggered. static const double kHighContextDisposalRate; diff --git a/test/unittests/heap/gc-idle-time-handler-unittest.cc b/test/unittests/heap/gc-idle-time-handler-unittest.cc index 011fdc0..357b08f 100644 --- a/test/unittests/heap/gc-idle-time-handler-unittest.cc +++ b/test/unittests/heap/gc-idle-time-handler-unittest.cc @@ -219,6 +219,18 @@ TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) { } +TEST_F(GCIdleTimeHandlerTest, DoNotScavengeSmallNewSpaceSize) { + GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); + heap_state.used_new_space_size = (MB / 2) - 1; + heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity; + int idle_time_ms = 16; + EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge( + idle_time_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)); +} + + TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) { size_t idle_time_ms = GCIdleTimeHandler::kMaxScheduledIdleTime; EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_ms, 0, 0)); -- 2.7.4