GC. Delay/avoid entering high promotion mode
authorerikcorry <erikcorry@chromium.org>
Wed, 1 Jul 2015 17:42:15 +0000 (10:42 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 1 Jul 2015 17:42:25 +0000 (17:42 +0000)
R=hpayer@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1217813012

Cr-Commit-Position: refs/heads/master@{#29429}

src/heap/heap.cc
src/heap/heap.h

index 435b1b2..8c507d4 100644 (file)
@@ -117,6 +117,7 @@ Heap::Heap()
       total_regexp_code_generated_(0),
       tracer_(this),
       new_space_high_promotion_mode_active_(false),
+      gathering_lifetime_feedback_(0),
       high_survival_rate_period_length_(0),
       promoted_objects_size_(0),
       low_survival_rate_period_length_(0),
@@ -1253,7 +1254,9 @@ bool Heap::PerformGarbageCollection(
 
   // When pretenuring is collecting new feedback, we do not shrink the new space
   // right away.
-  if (!deopted) {
+  if (deopted) {
+    RecordDeoptForPretenuring();
+  } else {
     ConfigureNewGenerationSize();
   }
   ConfigureInitialOldGenerationSize();
@@ -2635,6 +2638,8 @@ void Heap::ConfigureInitialOldGenerationSize() {
 
 
 void Heap::ConfigureNewGenerationSize() {
+  bool still_gathering_lifetime_data = gathering_lifetime_feedback_ != 0;
+  if (gathering_lifetime_feedback_ != 0) gathering_lifetime_feedback_--;
   if (!new_space_high_promotion_mode_active_ &&
       new_space_.TotalCapacity() == new_space_.MaximumCapacity() &&
       IsStableOrIncreasingSurvivalTrend() && IsHighSurvivalRate()) {
@@ -2642,10 +2647,18 @@ void Heap::ConfigureNewGenerationSize() {
     // 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) {
-      PrintPID("Limited new space size due to high promotion rate: %d MB\n",
-               new_space_.InitialTotalCapacity() / MB);
+    if (still_gathering_lifetime_data) {
+      if (FLAG_trace_gc) {
+        PrintPID(
+            "Postpone entering high promotion mode as optimized pretenuring "
+            "code is still being generated\n");
+      }
+    } else {
+      new_space_high_promotion_mode_active_ = true;
+      if (FLAG_trace_gc) {
+        PrintPID("Limited new space size due to high promotion rate: %d MB\n",
+                 new_space_.InitialTotalCapacity() / MB);
+      }
     }
   } else if (new_space_high_promotion_mode_active_ &&
              IsStableOrDecreasingSurvivalTrend() && IsLowSurvivalRate()) {
index a57a46d..3ce381d 100644 (file)
@@ -1372,6 +1372,10 @@ class Heap {
     return PromotedSpaceSizeOfObjects() - old_generation_size_at_last_gc_;
   }
 
+  // Record the fact that we generated some optimized code since the last GC
+  // which will pretenure some previously unpretenured allocation.
+  void RecordDeoptForPretenuring() { gathering_lifetime_feedback_ = 2; }
+
   // Update GC statistics that are tracked on the Heap.
   void UpdateCumulativeGCStatistics(double duration, double spent_in_mutator,
                                     double marking_time);
@@ -2173,6 +2177,10 @@ class Heap {
   static const int kOldSurvivalRateLowThreshold = 10;
 
   bool new_space_high_promotion_mode_active_;
+  // If this is non-zero, then there is hope yet that the optimized code we
+  // have generated will solve our high promotion rate problems, so we don't
+  // need to go into high promotion mode just yet.
+  int gathering_lifetime_feedback_;
   int high_survival_rate_period_length_;
   intptr_t promoted_objects_size_;
   int low_survival_rate_period_length_;
@@ -2239,8 +2247,6 @@ class Heap {
 
   bool IsLowSurvivalRate() { return low_survival_rate_period_length_ > 0; }
 
-  // TODO(hpayer): Allocation site pretenuring may make this method obsolete.
-  // Re-visit incremental marking heuristics.
   bool IsHighSurvivalRate() { return high_survival_rate_period_length_ > 0; }
 
   void ConfigureInitialOldGenerationSize();