Revision: 8918
Author:   [email protected]
Date:     Fri Aug 12 02:21:47 2011
Log: Fix the thresholds so that the heap does not grow uncontrollably. This fixes the OOM on the 524 test, alllowing the underlying crash issue to become visible
again.
Review URL: http://codereview.chromium.org/7621014
http://code.google.com/p/v8/source/detail?r=8918

Modified:
 /branches/experimental/gc/src/heap.cc
 /branches/experimental/gc/src/heap.h
 /branches/experimental/gc/src/spaces.cc
 /branches/experimental/gc/src/spaces.h

=======================================
--- /branches/experimental/gc/src/heap.cc       Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/heap.cc       Fri Aug 12 02:21:47 2011
@@ -62,12 +62,6 @@
 namespace internal {


-static const intptr_t kMinimumPromotionLimit =
-    2 * (Page::kPageSize > MB ? Page::kPageSize : MB);
-static const intptr_t kMinimumAllocationLimit =
-    8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
-
-
 static Mutex* gc_initializer_mutex = OS::CreateMutex();


@@ -121,6 +115,8 @@
 #endif  // DEBUG
       old_gen_promotion_limit_(kMinimumPromotionLimit),
       old_gen_allocation_limit_(kMinimumAllocationLimit),
+      old_gen_limit_factor_(1),
+      size_of_old_gen_at_last_old_space_gc_(0),
       external_allocation_limit_(0),
       amount_of_external_allocated_memory_(0),
       amount_of_external_allocated_memory_at_last_global_gc_(0),
@@ -729,15 +725,7 @@

     UpdateSurvivalRateTrend(start_new_space_size);

-    intptr_t old_gen_size = PromotedSpaceSize();
-    old_gen_promotion_limit_ =
-        old_gen_size +
-        Max(kMinimumPromotionLimit, old_gen_size / 3) +
-        new_space()->Capacity();
-    old_gen_allocation_limit_ =
-        old_gen_size +
-        Max(kMinimumAllocationLimit, old_gen_size / 2) +
-        new_space()->Capacity();
+    size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize();

     if (high_survival_rate_during_scavenges &&
         IsStableOrIncreasingSurvivalTrend()) {
@@ -747,9 +735,15 @@
       // In this case we aggressively raise old generation memory limits to
       // postpone subsequent mark-sweep collection and thus trade memory
       // space for the mutation speed.
-      old_gen_promotion_limit_ *= 2;
-      old_gen_allocation_limit_ *= 2;
-    }
+      old_gen_limit_factor_ = 2;
+    } else {
+      old_gen_limit_factor_ = 1;
+    }
+
+    old_gen_promotion_limit_ =
+        OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_);
+    old_gen_allocation_limit_ =
+        OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_);

     old_gen_exhausted_ = false;
   } else {
@@ -4250,6 +4244,7 @@
          old_gen_promotion_limit_);
   PrintF("old_gen_allocation_limit_ %" V8_PTR_PREFIX "d\n",
          old_gen_allocation_limit_);
+  PrintF("old_gen_limit_factor_ %d\n", old_gen_limit_factor_);

   PrintF("\n");
   PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles());
=======================================
--- /branches/experimental/gc/src/heap.h        Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/heap.h        Fri Aug 12 02:21:47 2011
@@ -1209,9 +1209,38 @@
            (PromotedSpaceSize() + PromotedExternalMemorySize());
   }

-  inline void LowerOldGenLimits(intptr_t bytes) {
-    old_gen_promotion_limit_ -= bytes;
-    old_gen_allocation_limit_ -= bytes;
+  static const intptr_t kMinimumPromotionLimit =
+      2 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+  static const intptr_t kMinimumAllocationLimit =
+      8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+
+ // When we sweep lazily we initially guess that there is no garbage on the + // heap and set the limits for the next GC accordingly. As we sweep we find
+  // out that some of the pages contained garbage and we have to adjust
+ // downwards the size of the heap. This means the limits that control the
+  // timing of the next GC also need to be adjusted downwards.
+  void LowerOldGenLimits(intptr_t adjustment) {
+    size_of_old_gen_at_last_old_space_gc_ -= adjustment;
+    old_gen_promotion_limit_ =
+        OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_);
+    old_gen_allocation_limit_ =
+        OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_);
+  }
+
+  intptr_t OldGenPromotionLimit(intptr_t old_gen_size) {
+    intptr_t limit =
+        Max(old_gen_size + old_gen_size / 3, kMinimumPromotionLimit);
+    limit += new_space_.Capacity();
+    limit *= old_gen_limit_factor_;
+    return limit;
+  }
+
+  intptr_t OldGenAllocationLimit(intptr_t old_gen_size) {
+    intptr_t limit =
+        Max(old_gen_size + old_gen_size / 2, kMinimumAllocationLimit);
+    limit += new_space_.Capacity();
+    limit *= old_gen_limit_factor_;
+    return limit;
   }

   // Can be called when the embedding application is idle.
@@ -1458,6 +1487,13 @@
   // every allocation in large object space.
   intptr_t old_gen_allocation_limit_;

+ // Sometimes the heuristics dictate that those limits are increased. This
+  // variable records that fact.
+  int old_gen_limit_factor_;
+
+  // Used to adjust the limits that control the timing of the next GC.
+  intptr_t size_of_old_gen_at_last_old_space_gc_;
+
   // Limit on the amount of externally allocated memory allowed
   // between global GCs. If reached a global GC is forced.
   intptr_t external_allocation_limit_;
=======================================
--- /branches/experimental/gc/src/spaces.cc     Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/spaces.cc     Fri Aug 12 02:21:47 2011
@@ -1930,6 +1930,15 @@
   SetTop(NULL, NULL);

   // Stop lazy sweeping for the space.
+  if (FLAG_trace_gc && first_unswept_page_ != NULL) {
+    int pages = 0;
+    Page* p = last_unswept_page_;
+    do {
+      pages++;
+      p = p->next_page();
+    } while (p != last_unswept_page_);
+    PrintF("Abandoned %d unswept pages\n", pages);
+  }
   first_unswept_page_ = last_unswept_page_ = Page::FromAddress(NULL);

   // Clear the free list before a full GC---it will be rebuilt afterward.
=======================================
--- /branches/experimental/gc/src/spaces.h      Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/spaces.h      Fri Aug 12 02:21:47 2011
@@ -1434,6 +1434,7 @@
   void SetPagesToSweep(Page* first, Page* last) {
     first_unswept_page_ = first;
     last_unswept_page_ = last;
+    int unswept_pages = 0;

     Page* p = first;
     do {
@@ -1441,7 +1442,12 @@
       // page.  We have to set this flag on the pages to indicate this.
       p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
       p = p->next_page();
+      unswept_pages++;
     } while (p != last);
+
+    if (FLAG_trace_gc_verbose) {
+      PrintF("Postponing sweep for %d pages\n", unswept_pages);
+    }
   }

   bool AdvanceSweeper(intptr_t bytes_to_sweep);

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

Reply via email to