Reviewers: Erik Corry,

Message:
PTAL.

Description:
Implement high promotion mode for new space.

This mode drastically decreases pause times by limiting maximum capacity
of the young generation when mutators generate many long-lived objects.
It shrinks new space back to the initial capacity and keeps it at that
capacity until survival rate decreases again.

[email protected]


Please review this at http://codereview.chromium.org/8702006/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/heap.h
  M src/heap.cc


Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 3d6db92eca1853b9c6b96cfae1204cbd1c205c5b..5bb64101544ef6d29f9e813eda05748259bc048a 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -112,6 +112,7 @@ Heap::Heap()
       disallow_allocation_failure_(false),
       debug_utils_(NULL),
 #endif  // DEBUG
+      new_space_high_promotion_mode_active_(false),
       old_gen_promotion_limit_(kMinimumPromotionLimit),
       old_gen_allocation_limit_(kMinimumAllocationLimit),
       old_gen_limit_factor_(1),
@@ -735,6 +736,32 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,

     UpdateSurvivalRateTrend(start_new_space_size);

+    if (!new_space_high_promotion_mode_active_ &&
+        new_space_.Capacity() == new_space_.MaximumCapacity() &&
+        IsStableOrIncreasingSurvivalTrend() &&
+        IsHighSurvivalRate()) {
+      // Stable high survival rates even though young generation is at
+      // maximum capacity indicates that most objects will be promoted.
+      // To decrease scavenger pauses and final mark-sweep pauses, we
+      // have to limit maximal capacity of the young generation.
+      new_space_high_promotion_mode_active_ = true;
+      if (FLAG_trace_gc) {
+ PrintF("Limited new space size due to high promotion rate: %d MB\n",
+               new_space_.InitialCapacity() / MB);
+      }
+    } else if (new_space_high_promotion_mode_active_ &&
+        IsDecreasingSurvivalTrend() &&
+        !IsHighSurvivalRate()) {
+      // Decreasing low survival rates might indicate that the above high
+      // promotion mode is over and we should allow the young generation
+      // to grow again.
+      new_space_high_promotion_mode_active_ = false;
+      if (FLAG_trace_gc) {
+ PrintF("Unlimited new space size due to low promotion rate: %d MB\n",
+               new_space_.MaximumCapacity() / MB);
+      }
+    }
+
     size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize();

     if (high_survival_rate_during_scavenges &&
@@ -764,6 +791,11 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
     UpdateSurvivalRateTrend(start_new_space_size);
   }

+  if (new_space_high_promotion_mode_active_ &&
+      new_space_.Capacity() > new_space_.InitialCapacity()) {
+    new_space_.Shrink();
+  }
+
   isolate_->counters()->objs_since_last_young()->Set(0);

   gc_post_processing_depth_++;
@@ -916,9 +948,11 @@ static void VerifyNonPointerSpacePointers() {

 void Heap::CheckNewSpaceExpansionCriteria() {
   if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
-      survived_since_last_expansion_ > new_space_.Capacity()) {
-    // Grow the size of new space if there is room to grow and enough
-    // data has survived scavenge since the last expansion.
+      survived_since_last_expansion_ > new_space_.Capacity() &&
+      !new_space_high_promotion_mode_active_) {
+    // Grow the size of new space if there is room to grow, enough data
+    // has survived scavenge since the last expansion and we are not in
+    // high promotion mode.
     new_space_.Grow();
     survived_since_last_expansion_ = 0;
   }
Index: src/heap.h
diff --git a/src/heap.h b/src/heap.h
index 9f4f505e1d9d04a6695b1cd2d92a776e982263d0..081c4663de49df6b48ab7c3a251c29c24409d0d0 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1569,6 +1569,10 @@ class Heap {
   HeapDebugUtils* debug_utils_;
 #endif  // DEBUG

+ // Indicates that the new space should be kept small due to high promotion
+  // rates caused by the mutator allocating a lot of long-lived objects.
+  bool new_space_high_promotion_mode_active_;
+
// Limit that triggers a global GC on the next (normally caused) GC. This
   // is checked when we have already decided to do a GC to help determine
   // which collector to invoke.
@@ -1809,6 +1813,10 @@ class Heap {
     return survival_rate_trend() == INCREASING;
   }

+  bool IsDecreasingSurvivalTrend() {
+    return survival_rate_trend() == DECREASING;
+  }
+
   bool IsHighSurvivalRate() {
     return high_survival_rate_period_length_ > 0;
   }


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to