Version 3.27.34.11 (merged r22007, r22019, r22090)

Wait for sweeper threads when expansion of old generation fails.

Collect garbage with kReduceMemoryFootprintMask in IdleNotification.

Waiting for sweeper threads is last resort in SlowAllocateRaw.

BUG=350720
LOG=N
R=machenbach@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/3.27@22822 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap.cc b/src/heap.cc
index 5137570..dd3946f 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -4245,7 +4245,8 @@
       isolate_->compilation_cache()->Clear();
       uncommit = true;
     }
-    CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
+    CollectAllGarbage(kReduceMemoryFootprintMask,
+                      "idle notification: finalize incremental");
     mark_sweeps_since_idle_round_started_++;
     gc_count_at_last_idle_gc_ = gc_count_;
     if (uncommit) {
diff --git a/src/spaces.cc b/src/spaces.cc
index 1ffc314..69a0145 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -2577,6 +2577,22 @@
 }
 
 
+HeapObject* PagedSpace::WaitForSweeperThreadsAndRetryAllocation(
+    int size_in_bytes) {
+  MarkCompactCollector* collector = heap()->mark_compact_collector();
+
+  // If sweeper threads are still running, wait for them.
+  if (collector->IsConcurrentSweepingInProgress()) {
+    collector->WaitUntilSweepingCompleted();
+
+    // After waiting for the sweeper threads, there may be new free-list
+    // entries.
+    return free_list_.Allocate(size_in_bytes);
+  }
+  return NULL;
+}
+
+
 HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
   // Allocation in this space has failed.
 
@@ -2593,9 +2609,12 @@
   // 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 (!heap()->always_allocate()
+      && heap()->OldGenerationAllocationLimitReached()) {
+    // If sweeper threads are active, wait for them at that point and steal
+    // elements form their free-lists.
+    HeapObject* object = WaitForSweeperThreadsAndRetryAllocation(size_in_bytes);
+    if (object != NULL) return object;
   }
 
   // Try to expand the space and allocate in the new next page.
@@ -2604,18 +2623,10 @@
     return free_list_.Allocate(size_in_bytes);
   }
 
-  // If sweeper threads are active, wait for them at that point.
-  if (collector->IsConcurrentSweepingInProgress()) {
-    collector->WaitUntilSweepingCompleted();
-
-    // After waiting for the sweeper threads, there may be new free-list
-    // entries.
-    HeapObject* object = free_list_.Allocate(size_in_bytes);
-    if (object != NULL) return object;
-  }
-
-  // Finally, fail.
-  return NULL;
+  // If sweeper threads are active, wait for them at that point and steal
+  // elements form their free-lists. Allocation may still fail their which
+  // would indicate that there is not enough memory for the given allocation.
+  return WaitForSweeperThreadsAndRetryAllocation(size_in_bytes);
 }
 
 
diff --git a/src/spaces.h b/src/spaces.h
index 96a1a90..a8c981d 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -2003,8 +2003,11 @@
   // address denoted by top in allocation_info_.
   inline HeapObject* AllocateLinearly(int size_in_bytes);
 
+  MUST_USE_RESULT HeapObject*
+      WaitForSweeperThreadsAndRetryAllocation(int size_in_bytes);
+
   // Slow path of AllocateRaw.  This function is space-dependent.
-  MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes);
+  MUST_USE_RESULT HeapObject* SlowAllocateRaw(int size_in_bytes);
 
   friend class PageIterator;
   friend class MarkCompactCollector;
diff --git a/src/version.cc b/src/version.cc
index f4b4664..c11fb5a 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     27
 #define BUILD_NUMBER      34
-#define PATCH_LEVEL       10
+#define PATCH_LEVEL       11
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0