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 0aec949..fb3ac56 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 ee7c091..1be81dd 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 d2899fe..41bfec9 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 e99e1e5..6379f3e 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));
 }