Revision: 23979
Author:   [email protected]
Date:     Tue Sep 16 13:00:05 2014 UTC
Log:      Allow IdleNotification to trigger Scavenges.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/563493002
https://code.google.com/p/v8/source/detail?r=23979

Modified:
 /branches/bleeding_edge/src/heap/gc-idle-time-handler-unittest.cc
 /branches/bleeding_edge/src/heap/gc-idle-time-handler.cc
 /branches/bleeding_edge/src/heap/gc-idle-time-handler.h
 /branches/bleeding_edge/src/heap/heap.cc
 /branches/bleeding_edge/src/heap/spaces.h

=======================================
--- /branches/bleeding_edge/src/heap/gc-idle-time-handler-unittest.cc Tue Sep 16 12:48:59 2014 UTC +++ /branches/bleeding_edge/src/heap/gc-idle-time-handler-unittest.cc Tue Sep 16 13:00:05 2014 UTC
@@ -28,12 +28,17 @@
     result.sweeping_in_progress = false;
     result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
     result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
+    result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
+    result.available_new_space_memory = kNewSpaceCapacity;
+    result.new_space_capacity = kNewSpaceCapacity;
     return result;
   }

   static const size_t kSizeOfObjects = 100 * MB;
   static const size_t kMarkCompactSpeed = 200 * KB;
   static const size_t kMarkingSpeed = 200 * KB;
+  static const size_t kScavengeSpeed = 100 * KB;
+  static const size_t kNewSpaceCapacity = 1 * MB;

  private:
   GCIdleTimeHandler handler_;
@@ -99,6 +104,21 @@
   size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
   EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
 }
+
+
+TEST(GCIdleTimeHandler, EstimateScavengeTimeInitial) {
+  size_t size = 1 * MB;
+  size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, 0);
+ EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeScavengeSpeed, time);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateScavengeTimeNonZero) {
+  size_t size = 1 * MB;
+  size_t speed = 1 * MB;
+  size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, speed);
+  EXPECT_EQ(size / speed, time);
+}


 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
=======================================
--- /branches/bleeding_edge/src/heap/gc-idle-time-handler.cc Tue Sep 16 12:48:59 2014 UTC +++ /branches/bleeding_edge/src/heap/gc-idle-time-handler.cc Tue Sep 16 13:00:05 2014 UTC
@@ -71,9 +71,40 @@
 }


+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 {
=======================================
--- /branches/bleeding_edge/src/heap/gc-idle-time-handler.h Tue Sep 16 12:48:59 2014 UTC +++ /branches/bleeding_edge/src/heap/gc-idle-time-handler.h Tue Sep 16 13:00:05 2014 UTC
@@ -113,6 +113,14 @@
   // That is the maximum idle time we will have during frame rendering.
   static const size_t kMaxFrameRenderingIdleTime = 16;

+  // If less than that much memory is left in the new space, we consider it
+ // as almost full and force a new space collection earlier in the idle time.
+  static const size_t kNewSpaceAlmostFullTreshold = 100 * KB;
+
+  // If we haven't recorded any scavenger events yet, we use a conservative
+  // lower bound for the scavenger speed.
+  static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
+
   struct HeapState {
     int contexts_disposed;
     size_t size_of_objects;
@@ -121,6 +129,9 @@
     bool sweeping_in_progress;
     size_t mark_compact_speed_in_bytes_per_ms;
     size_t incremental_marking_speed_in_bytes_per_ms;
+    size_t scavenge_speed_in_bytes_per_ms;
+    size_t available_new_space_memory;
+    size_t new_space_capacity;
   };

   GCIdleTimeHandler()
@@ -147,9 +158,12 @@
   static size_t EstimateMarkCompactTime(
       size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);

+  static size_t EstimateScavengeTime(size_t new_space_size,
+ size_t scavenger_speed_in_bytes_per_ms);
+
  private:
   void StartIdleRound() { mark_compacts_since_idle_round_started_ = 0; }
-  bool IsIdleRoundFinished() {
+  bool IsMarkCompactIdleRoundFinished() {
     return mark_compacts_since_idle_round_started_ ==
            kMaxMarkCompactsInIdleRound;
   }
=======================================
--- /branches/bleeding_edge/src/heap/heap.cc    Tue Sep 16 12:48:59 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.cc    Tue Sep 16 13:00:05 2014 UTC
@@ -4311,6 +4311,10 @@
static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>(
       tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
+  heap_state.scavenge_speed_in_bytes_per_ms =
+      static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond());
+  heap_state.available_new_space_memory = new_space_.Available();
+  heap_state.new_space_capacity = new_space_.Capacity();

   GCIdleTimeAction action =
       gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
=======================================
--- /branches/bleeding_edge/src/heap/spaces.h   Tue Sep  2 13:36:35 2014 UTC
+++ /branches/bleeding_edge/src/heap/spaces.h   Tue Sep 16 13:00:05 2014 UTC
@@ -2013,7 +2013,7 @@

   Address address() { return reinterpret_cast<Address>(this); }

-  // Finds the NewSpacePage containg the given address.
+  // Finds the NewSpacePage containing the given address.
   static inline NewSpacePage* FromAddress(Address address_in_page) {
     Address page_start =
reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) &

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to