Revision: 10500
Author:   [email protected]
Date:     Wed Jan 25 05:46:42 2012
Log:      Fix responsiveness of high promotion mode heuristics.

This changes the heuristics for the high promotion mode to be checked
on all GCs (including scavenges), so that changes in the applications
behavior are recognized earlier. It also fixes miscalculations in the
survival counter and rate which caused heuristics to fail completely.

[email protected]
BUG=v8:1899

Review URL: https://chromiumcodereview.appspot.com/9196003
http://code.google.com/p/v8/source/detail?r=10500

Modified:
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h

=======================================
--- /branches/bleeding_edge/src/heap.cc Mon Jan 23 08:18:10 2012
+++ /branches/bleeding_edge/src/heap.cc Wed Jan 25 05:46:42 2012
@@ -695,11 +695,17 @@
       (static_cast<double>(young_survivors_after_last_gc_) * 100) /
       start_new_space_size;

-  if (survival_rate > kYoungSurvivalRateThreshold) {
+  if (survival_rate > kYoungSurvivalRateHighThreshold) {
     high_survival_rate_period_length_++;
   } else {
     high_survival_rate_period_length_ = 0;
   }
+
+  if (survival_rate < kYoungSurvivalRateLowThreshold) {
+    low_survival_rate_period_length_++;
+  } else {
+    low_survival_rate_period_length_ = 0;
+  }

   double survival_rate_diff = survival_rate_ - survival_rate;

@@ -759,32 +765,6 @@
         IsStableOrIncreasingSurvivalTrend();

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

@@ -814,6 +794,32 @@

     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_ &&
+      IsStableOrDecreasingSurvivalTrend() &&
+      IsLowSurvivalRate()) {
+    // 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);
+    }
+  }

   if (new_space_high_promotion_mode_active_ &&
       new_space_.Capacity() > new_space_.InitialCapacity()) {
@@ -1099,7 +1105,7 @@
   isolate_->descriptor_lookup_cache()->Clear();

   // Used for updating survived_since_last_expansion_ at function end.
-  intptr_t survived_watermark = PromotedSpaceSize();
+  intptr_t survived_watermark = PromotedSpaceSizeOfObjects();

   CheckNewSpaceExpansionCriteria();

@@ -1191,7 +1197,7 @@

   // Update how much has survived scavenge.
   IncrementYoungSurvivorsCounter(static_cast<int>(
-      (PromotedSpaceSize() - survived_watermark) + new_space_.Size()));
+ (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));

   LOG(isolate_, ResourceEvent("scavenge", "end"));

@@ -5420,6 +5426,16 @@
       + cell_space_->Size()
       + lo_space_->Size();
 }
+
+
+intptr_t Heap::PromotedSpaceSizeOfObjects() {
+  return old_pointer_space_->SizeOfObjects()
+      + old_data_space_->SizeOfObjects()
+      + code_space_->SizeOfObjects()
+      + map_space_->SizeOfObjects()
+      + cell_space_->SizeOfObjects()
+      + lo_space_->SizeOfObjects();
+}


 int Heap::PromotedExternalMemorySize() {
=======================================
--- /branches/bleeding_edge/src/heap.h  Tue Jan 24 00:43:12 2012
+++ /branches/bleeding_edge/src/heap.h  Wed Jan 25 05:46:42 2012
@@ -1382,6 +1382,7 @@
   void CheckNewSpaceExpansionCriteria();

   inline void IncrementYoungSurvivorsCounter(int survived) {
+    ASSERT(survived >= 0);
     young_survivors_after_last_gc_ = survived;
     survived_since_last_expansion_ += survived;
   }
@@ -1431,6 +1432,7 @@

   // Returns the size of objects residing in non new spaces.
   intptr_t PromotedSpaceSize();
+  intptr_t PromotedSpaceSizeOfObjects();

double total_regexp_code_generated() { return total_regexp_code_generated_; }
   void IncreaseTotalRegexpCodeGenerated(int size) {
@@ -1805,11 +1807,13 @@

   enum SurvivalRateTrend { INCREASING, STABLE, DECREASING, FLUCTUATING };

-  static const int kYoungSurvivalRateThreshold = 90;
+  static const int kYoungSurvivalRateHighThreshold = 90;
+  static const int kYoungSurvivalRateLowThreshold = 10;
   static const int kYoungSurvivalRateAllowedDeviation = 15;

   int young_survivors_after_last_gc_;
   int high_survival_rate_period_length_;
+  int low_survival_rate_period_length_;
   double survival_rate_;
   SurvivalRateTrend previous_survival_rate_trend_;
   SurvivalRateTrend survival_rate_trend_;
@@ -1841,18 +1845,28 @@
         return false;
     }
   }
+
+  bool IsStableOrDecreasingSurvivalTrend() {
+    switch (survival_rate_trend()) {
+      case STABLE:
+      case DECREASING:
+        return true;
+      default:
+        return false;
+    }
+  }

   bool IsIncreasingSurvivalTrend() {
     return survival_rate_trend() == INCREASING;
   }
-
-  bool IsDecreasingSurvivalTrend() {
-    return survival_rate_trend() == DECREASING;
-  }

   bool IsHighSurvivalRate() {
     return high_survival_rate_period_length_ > 0;
   }
+
+  bool IsLowSurvivalRate() {
+    return low_survival_rate_period_length_ > 0;
+  }

   void SelectScavengingVisitorsTable();

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

Reply via email to