Be more willing to expand old space when evacuating new space at the end of
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 30 Nov 2011 10:38:16 +0000 (10:38 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 30 Nov 2011 10:38:16 +0000 (10:38 +0000)
a mark-sweep.  We have a soft limit on old space size, which is designed to
trigger an old-space collection when we hit it.  Unfortunately although the
soft limit had already triggered an old space collection, the soft limit was
preventing objects from new space from being promoted.  For every promotion
candidate we were checking 3 different ways to allocate in old space before
giving up and putting the object in the other semispace.  This change allows
the promoted objects to go to old space and also makes us more eager to
sweep a page before trying other ways to find space for an object.
Review URL: http://codereview.chromium.org/8748005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10092 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/mark-compact.cc
src/spaces.cc
src/spaces.h
test/cctest/test-mark-compact.cc

index 0aec949eeaa8b24e40d962eb3e4c13d6a984f4dd..fb3ac5697939b983e958bad7495356256e556413 100644 (file)
@@ -2582,6 +2582,10 @@ bool MarkCompactCollector::TryPromoteObject(HeapObject* object,
 
 
 void MarkCompactCollector::EvacuateNewSpace() {
+  // There are soft limits in the allocation code, designed trigger a mark
+  // sweep collection by failing allocations.  But since we are already in
+  // a mark-sweep allocation, there is no sense in trying to trigger one.
+  AlwaysAllocateScope scope;
   heap()->CheckNewSpaceExpansionCriteria();
 
   NewSpace* new_space = heap()->new_space();
index ee7c0916503865e8ed43806e507d275731137775..1be81dde33d6b64af862fbdfe07015920ccf74c7 100644 (file)
@@ -2142,29 +2142,22 @@ void PagedSpace::EvictEvacuationCandidatesFromFreeLists() {
 HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
   // Allocation in this space has failed.
 
-  // Free list allocation failed and there is no next page.  Fail if we have
-  // hit the old generation size limit that should cause a garbage
-  // collection.
-  if (!heap()->always_allocate() &&
-      heap()->OldGenerationAllocationLimitReached()) {
-    return NULL;
-  }
-
-  // If there are unswept pages advance lazy sweeper.
+  // If there are unswept pages advance lazy sweeper then sweep one page before
+  // allocating a new page.
   if (first_unswept_page_->is_valid()) {
     AdvanceSweeper(size_in_bytes);
 
     // Retry the free list allocation.
     HeapObject* object = free_list_.Allocate(size_in_bytes);
     if (object != NULL) return object;
+  }
 
-    if (!IsSweepingComplete()) {
-      AdvanceSweeper(kMaxInt);
-
-      // Retry the free list allocation.
-      object = free_list_.Allocate(size_in_bytes);
-      if (object != NULL) return object;
-    }
+  // Free list allocation failed and there is no next page.  Fail if we have
+  // hit the old generation size limit that should cause a garbage
+  // collection.
+  if (!heap()->always_allocate() &&
+      heap()->OldGenerationAllocationLimitReached()) {
+    return NULL;
   }
 
   // Try to expand the space and allocate in the new next page.
@@ -2172,6 +2165,16 @@ HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
     return free_list_.Allocate(size_in_bytes);
   }
 
+  // Last ditch, sweep all the remaining pages to try to find space.  This may
+  // cause a pause.
+  if (!IsSweepingComplete()) {
+    AdvanceSweeper(kMaxInt);
+
+    // Retry the free list allocation.
+    HeapObject* object = free_list_.Allocate(size_in_bytes);
+    if (object != NULL) return object;
+  }
+
   // Finally, fail.
   return NULL;
 }
index d2899fe10f21d56736b3f2a23c91c12097d7ab82..41bfec90f142797bdc295d622505ee963c6b05c6 100644 (file)
@@ -1650,7 +1650,8 @@ class PagedSpace : public Space {
   Page* first_unswept_page_;
 
   // Expands the space by allocating a fixed number of pages. Returns false if
-  // it cannot allocate requested number of pages from OS.
+  // it cannot allocate requested number of pages from OS, or if the hard heap
+  // size limit has been hit.
   bool Expand();
 
   // Generic fast case allocation function that tries linear allocation at the
index e99e1e5de0d513027f070849a2105fd8cba41f6a..6379f3e31805d6686c5149c223b803f592274a84 100644 (file)
@@ -142,9 +142,6 @@ TEST(NoPromotion) {
 
   // Call mark compact GC, and it should pass.
   HEAP->CollectGarbage(OLD_POINTER_SPACE);
-
-  // array should not be promoted because the old space is full.
-  CHECK(HEAP->InSpace(*array, NEW_SPACE));
 }