am 9413bcbe: Merge V8 at 3.9.24.21

* commit '9413bcbe2192ed4d701281130490e0ba336debdc':
  Merge V8 at 3.9.24.21
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index ed1c0be..a80c7d8 100644
--- a/V8_MERGE_REVISION
+++ b/V8_MERGE_REVISION
@@ -1,2 +1,2 @@
-V8 3.9.24.17
-http://v8.googlecode.com/svn/branches/3.9@11450
+V8 3.9.24.21
+http://v8.googlecode.com/svn/branches/3.9@11511
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index 7b2a3c4..699e6aa 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -457,6 +457,8 @@
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -464,7 +466,7 @@
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 7 * kPointerSize;
+  unsigned fixed_frame_size = 8 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -529,6 +531,15 @@
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08x: [top + %d] <- 0x%08x ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -559,8 +570,6 @@
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   uint32_t pc = reinterpret_cast<uint32_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 852824f..98a3cdc 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -4429,6 +4429,8 @@
     // Increment the length of the array.
     __ mov(length_reg, Operand(Smi::FromInt(1)));
     __ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+    __ ldr(elements_reg,
+           FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
     __ jmp(&finish_store);
 
     __ bind(&check_capacity);
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 92d7cc1..6de2c81 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -548,6 +548,8 @@
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -555,7 +557,7 @@
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 6 * kPointerSize;
+  unsigned fixed_frame_size = 7 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -620,6 +622,15 @@
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08x: [top + %d] <- 0x%08x ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -641,8 +652,6 @@
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   uint32_t pc = reinterpret_cast<uint32_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc
index 51c2e46..62f3155 100644
--- a/src/mips/deoptimizer-mips.cc
+++ b/src/mips/deoptimizer-mips.cc
@@ -447,6 +447,8 @@
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -454,7 +456,7 @@
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 7 * kPointerSize;
+  unsigned fixed_frame_size = 8 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -519,6 +521,15 @@
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08x: [top + %d] <- 0x%08x ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -549,8 +560,6 @@
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   uint32_t pc = reinterpret_cast<uint32_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index f7b94b9..f1a8c89 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -4494,6 +4494,8 @@
     // Increment the length of the array.
     __ li(length_reg, Operand(Smi::FromInt(1)));
     __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+    __ lw(elements_reg,
+          FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
     __ jmp(&finish_store);
 
     __ bind(&check_capacity);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 6c2c73a..68feda4 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1383,7 +1383,9 @@
 
 
 void JSObject::initialize_elements() {
-  ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
+  ASSERT(map()->has_fast_elements() ||
+         map()->has_fast_smi_only_elements() ||
+         map()->has_fast_double_elements());
   ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
   WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
 }
diff --git a/src/spaces.cc b/src/spaces.cc
index 57b223f..929a45f 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -362,13 +362,20 @@
   if (base == NULL) return NULL;
 
   if (executable == EXECUTABLE) {
-    CommitCodePage(&reservation, base, size);
-  } else {
-    if (!reservation.Commit(base,
-                            size,
-                            executable == EXECUTABLE)) {
-      return NULL;
+    if (!CommitCodePage(&reservation, base, size)) {
+      base = NULL;
     }
+  } else {
+    if (!reservation.Commit(base, size, false)) {
+      base = NULL;
+    }
+  }
+
+  if (base == NULL) {
+    // Failed to commit the body. Release the mapping and any partially
+    // commited regions inside it.
+    reservation.Release();
+    return NULL;
   }
 
   controller->TakeControl(&reservation);
diff --git a/src/spaces.h b/src/spaces.h
index b614c3b..9e74a88 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1040,7 +1040,9 @@
     return CodePageAreaEndOffset() - CodePageAreaStartOffset();
   }
 
-  static bool CommitCodePage(VirtualMemory* vm, Address start, size_t size);
+  MUST_USE_RESULT static bool CommitCodePage(VirtualMemory* vm,
+                                             Address start,
+                                             size_t size);
 
  private:
   Isolate* isolate_;
diff --git a/src/version.cc b/src/version.cc
index a5b9279..d024048 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     9
 #define BUILD_NUMBER      24
-#define PATCH_LEVEL       17
+#define PATCH_LEVEL       21
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index 2adf587..f55ebfc 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -440,6 +440,8 @@
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -447,7 +449,7 @@
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 6 * kPointerSize;
+  unsigned fixed_frame_size = 7 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -516,6 +518,16 @@
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+           V8PRIxPTR " ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
@@ -539,8 +551,6 @@
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   intptr_t pc = reinterpret_cast<intptr_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index a275f55..7ce4568 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -3767,6 +3767,7 @@
 
     // Increment the length of the array.
     __ Move(FieldOperand(rdx, JSArray::kLengthOffset), Smi::FromInt(1));
+    __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset));
     __ jmp(&finish_store);
 
     __ bind(&check_capacity);
diff --git a/test/mjsunit/regress/regress-124594.js b/test/mjsunit/regress/regress-124594.js
new file mode 100644
index 0000000..d51e1f6
--- /dev/null
+++ b/test/mjsunit/regress/regress-124594.js
@@ -0,0 +1,50 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+// Test that a GC inside a constructor frame is correctly handled right
+// after we deoptimize from an inlined constructor to a constructor stub
+// stack frame.
+
+function f(deopt) {
+  var x = 1;
+  if (deopt) {
+    x = x + "foo";
+    gc();
+  }
+  this.x = x;
+}
+
+function g(deopt) {
+  return new f(deopt);
+}
+
+assertEquals({x:1}, g(false));
+assertEquals({x:1}, g(false));
+%OptimizeFunctionOnNextCall(g);
+assertEquals({x:"1foo"}, g(true));
diff --git a/test/mjsunit/regress/regress-125515.js b/test/mjsunit/regress/regress-125515.js
new file mode 100644
index 0000000..91650ce
--- /dev/null
+++ b/test/mjsunit/regress/regress-125515.js
@@ -0,0 +1,41 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-gc --debug-code
+
+function test(a) {
+  a[0] = 1.5;
+  assertEquals(0, a.length = 0);
+}
+a = new Array();
+test(a);
+test(a);
+// Make sure that a ends up in old space
+gc();
+gc();
+test(a);
+test(a);