Version 3.28.71.8 (merged r23404)

Handle empty allocation list in CodeRange properly.

BUG=407566,v8:3540
LOG=N
R=hpayer@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/3.28@23797 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
index 9be53e0..92f3f7f 100644
--- a/src/heap/spaces.cc
+++ b/src/heap/spaces.cc
@@ -193,8 +193,10 @@
                                      const size_t commit_size,
                                      size_t* allocated) {
   DCHECK(commit_size <= requested_size);
-  DCHECK(current_allocation_block_index_ < allocation_list_.length());
-  if (requested_size > allocation_list_[current_allocation_block_index_].size) {
+  DCHECK(allocation_list_.length() == 0 ||
+         current_allocation_block_index_ < allocation_list_.length());
+  if (allocation_list_.length() == 0 ||
+      requested_size > allocation_list_[current_allocation_block_index_].size) {
     // Find an allocation block large enough.
     if (!GetNextAllocationBlock(requested_size)) return NULL;
   }
@@ -218,7 +220,7 @@
   allocation_list_[current_allocation_block_index_].size -= *allocated;
   if (*allocated == current.size) {
     // This block is used up, get the next one.
-    if (!GetNextAllocationBlock(0)) return NULL;
+    GetNextAllocationBlock(0);
   }
   return current.start;
 }
diff --git a/src/version.cc b/src/version.cc
index fe385bf..92b9be1 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     28
 #define BUILD_NUMBER      71
-#define PATCH_LEVEL 7
+#define PATCH_LEVEL 8
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/test/cctest/test-spaces.cc b/test/cctest/test-spaces.cc
index 0062094..3c59610 100644
--- a/test/cctest/test-spaces.cc
+++ b/test/cctest/test-spaces.cc
@@ -203,6 +203,28 @@
 }
 
 
+TEST(Regress3540) {
+  Isolate* isolate = CcTest::i_isolate();
+  isolate->InitializeLoggingAndCounters();
+  Heap* heap = isolate->heap();
+  CHECK(heap->ConfigureHeapDefault());
+  MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
+  CHECK(
+      memory_allocator->SetUp(heap->MaxReserved(), heap->MaxExecutableSize()));
+  TestMemoryAllocatorScope test_allocator_scope(isolate, memory_allocator);
+  CodeRange* code_range = new CodeRange(isolate);
+  const size_t code_range_size = 4 * MB;
+  if (!code_range->SetUp(code_range_size)) return;
+  size_t allocated_size;
+  Address result;
+  for (int i = 0; i < 5; i++) {
+    result = code_range->AllocateRawMemory(
+        code_range_size - MB, code_range_size - MB, &allocated_size);
+    CHECK((result != NULL) == (i == 0));
+  }
+}
+
+
 static unsigned int Pseudorandom() {
   static uint32_t lo = 2345;
   lo = 18273 * (lo & 0xFFFFF) + (lo >> 16);