Improved performance of Array.prototype.concat by moving the implementation to C++ (issue 123).

Fixed heap growth policy to avoid growing old space to its maximum capacity before doing a garbage collection and fixed issue that would lead to artificial out of memory situations (issue 129).

Fixed Date.prototype.toLocaleDateString to return the date in the same format as WebKit.

Added missing initialization checks to debugger API.

Added removing of unused maps during GC.


git-svn-id: http://v8.googlecode.com/svn/trunk@655 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/spaces.cc b/src/spaces.cc
index 7894f24..63add7c 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -1530,8 +1530,14 @@
     return HeapObject::cast(result);
   }
 
-  // Free list allocation failed and there is no next page.  Try to expand
-  // the space and allocate in the new next page.
+  // 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.
   ASSERT(!current_page->next_page()->is_valid());
   if (Expand(current_page)) {
     return AllocateInNextPage(current_page, size_in_bytes);
@@ -2009,8 +2015,14 @@
     }
   }
 
-  // Free list allocation failed and there is no next page.  Try to expand
-  // the space and allocate in the new next page.
+  // 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.
   ASSERT(!current_page->next_page()->is_valid());
   if (Expand(current_page)) {
     return AllocateInNextPage(current_page, size_in_bytes);
@@ -2236,6 +2248,13 @@
                                               int object_size,
                                               Executability executable) {
   ASSERT(0 < object_size && object_size <= requested_size);
+
+  // Check if we want to force a GC before growing the old space further.
+  // If so, fail the allocation.
+  if (!Heap::always_allocate() && Heap::OldGenerationAllocationLimitReached()) {
+    return Failure::RetryAfterGC(requested_size, identity());
+  }
+
   size_t chunk_size;
   LargeObjectChunk* chunk =
       LargeObjectChunk::New(requested_size, &chunk_size, executable);