Update V8 to r6122 (2.5 branch) as required by Chromium 9.0.597.55

Change-Id: Ia29dad551dd0cd7fa3c4d5084421f91d8b210271
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index ba5e70a..b948d81 100644
--- a/V8_MERGE_REVISION
+++ b/V8_MERGE_REVISION
@@ -1,4 +1,4 @@
 We use a V8 revision that has been used for a Chromium release.
 
-http://src.chromium.org/svn/releases/9.0.597.0/DEPS
-http://v8.googlecode.com/svn/trunk@5901
+http://src.chromium.org/svn/releases/9.0.597.55/DEPS
+http://v8.googlecode.com/svn/branches/2.5@6122
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 27e14df..06a4341 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -5672,6 +5672,12 @@
   __ tst(tmp2, Operand(kSmiTagMask));
   deferred->Branch(nz);
 
+  // Check that both indices are valid.
+  __ ldr(tmp2, FieldMemOperand(object, JSArray::kLengthOffset));
+  __ cmp(tmp2, index1);
+  __ cmp(tmp2, index2, hi);
+  deferred->Branch(ls);
+
   // Bring the offsets into the fixed array in tmp1 into index1 and
   // index2.
   __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index f04015b..0b6e13d 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -203,6 +203,11 @@
 }
 
 
+void FullCodeGenerator::ClearAccumulator() {
+  __ mov(r0, Operand(Smi::FromInt(0)));
+}
+
+
 void FullCodeGenerator::EmitReturnSequence() {
   Comment cmnt(masm_, "[ Return sequence");
   if (return_label_.is_bound()) {
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index a890f15..55aa230 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -795,6 +795,11 @@
   SetStatementPosition(stmt);
   NestedStatement* current = nesting_stack_;
   int stack_depth = 0;
+  // When continuing, we clobber the unpredictable value in the accumulator
+  // with one that's safe for GC.  If we hit an exit from the try block of
+  // try...finally on our way out, we will unconditionally preserve the
+  // accumulator on the stack.
+  ClearAccumulator();
   while (!current->IsContinueTarget(stmt->target())) {
     stack_depth = current->Exit(stack_depth);
     current = current->outer();
@@ -811,6 +816,11 @@
   SetStatementPosition(stmt);
   NestedStatement* current = nesting_stack_;
   int stack_depth = 0;
+  // When breaking, we clobber the unpredictable value in the accumulator
+  // with one that's safe for GC.  If we hit an exit from the try block of
+  // try...finally on our way out, we will unconditionally preserve the
+  // accumulator on the stack.
+  ClearAccumulator();
   while (!current->IsBreakTarget(stmt->target())) {
     stack_depth = current->Exit(stack_depth);
     current = current->outer();
@@ -1100,7 +1110,10 @@
     Visit(stmt->try_block());
     __ PopTryHandler();
   }
-  // Execute the finally block on the way out.
+  // Execute the finally block on the way out.  Clobber the unpredictable
+  // value in the accumulator with one that's safe for GC.  The finally
+  // block will unconditionally preserve the accumulator on the stack.
+  ClearAccumulator();
   __ Call(&finally_entry);
 }
 
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 97a56bd..02335a9 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -241,6 +241,10 @@
 
   static const InlineFunctionGenerator kInlineFunctionGenerators[];
 
+  // A platform-specific utility to overwrite the accumulator register
+  // with a GC-safe value.
+  void ClearAccumulator();
+
   // Compute the frame pointer relative offset for a given local or
   // parameter slot.
   int SlotOffset(Slot* slot);
diff --git a/src/heap.cc b/src/heap.cc
index 26859d7..16415ad 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3693,14 +3693,21 @@
   static const int kIdlesBeforeScavenge = 4;
   static const int kIdlesBeforeMarkSweep = 7;
   static const int kIdlesBeforeMarkCompact = 8;
+  static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1;
+  static const int kGCsBetweenCleanup = 4;
   static int number_idle_notifications = 0;
   static int last_gc_count = gc_count_;
 
   bool uncommit = true;
   bool finished = false;
 
-  if (last_gc_count == gc_count_) {
-    number_idle_notifications++;
+  // Reset the number of idle notifications received when a number of
+  // GCs have taken place. This allows another round of cleanup based
+  // on idle notifications if enough work has been carried out to
+  // provoke a number of garbage collections.
+  if (gc_count_ < last_gc_count + kGCsBetweenCleanup) {
+    number_idle_notifications =
+        Min(number_idle_notifications + 1, kMaxIdleCount);
   } else {
     number_idle_notifications = 0;
     last_gc_count = gc_count_;
@@ -3715,7 +3722,6 @@
     }
     new_space_.Shrink();
     last_gc_count = gc_count_;
-
   } else if (number_idle_notifications == kIdlesBeforeMarkSweep) {
     // Before doing the mark-sweep collections we clear the
     // compilation cache to avoid hanging on to source code and
@@ -3730,7 +3736,6 @@
     CollectAllGarbage(true);
     new_space_.Shrink();
     last_gc_count = gc_count_;
-    number_idle_notifications = 0;
     finished = true;
 
   } else if (contexts_disposed_ > 0) {
@@ -3749,6 +3754,11 @@
       number_idle_notifications = 0;
       uncommit = false;
     }
+  } else if (number_idle_notifications > kIdlesBeforeMarkCompact) {
+    // If we have received more than kIdlesBeforeMarkCompact idle
+    // notifications we do not perform any cleanup because we don't
+    // expect to gain much by doing so.
+    finished = true;
   }
 
   // Make sure that we have no pending context disposals and
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index f5ab357..e0e016c 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -7751,6 +7751,13 @@
   __ test(tmp2.reg(), Immediate(kSmiTagMask));
   deferred->Branch(not_zero);
 
+  // Check that both indices are valid.
+  __ mov(tmp2.reg(), FieldOperand(object.reg(), JSArray::kLengthOffset));
+  __ cmp(tmp2.reg(), Operand(index1.reg()));
+  deferred->Branch(below_equal);
+  __ cmp(tmp2.reg(), Operand(index2.reg()));
+  deferred->Branch(below_equal);
+
   // Bring addresses into index1 and index2.
   __ lea(index1.reg(), FixedArrayElementOperand(tmp1.reg(), index1.reg()));
   __ lea(index2.reg(), FixedArrayElementOperand(tmp1.reg(), index2.reg()));
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 3adc48a..8d6942d 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -197,6 +197,11 @@
 }
 
 
+void FullCodeGenerator::ClearAccumulator() {
+  __ Set(eax, Immediate(Smi::FromInt(0)));
+}
+
+
 void FullCodeGenerator::EmitReturnSequence() {
   Comment cmnt(masm_, "[ Return sequence");
   if (return_label_.is_bound()) {
diff --git a/src/runtime.cc b/src/runtime.cc
index c43a1ab..7214cb9 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -6792,7 +6792,7 @@
   // extension object itself.
   if ((attributes & READ_ONLY) == 0 ||
       (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
-    Handle<Object> set = SetProperty(context_ext, name, value, attributes);
+    Handle<Object> set = SetProperty(context_ext, name, value, NONE);
     if (set.is_null()) {
       // Failure::Exception is converted to a null handle in the
       // handle-based methods such as SetProperty.  We therefore need
diff --git a/src/version.cc b/src/version.cc
index 6e5b68f..d9be907 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     2
 #define MINOR_VERSION     5
 #define BUILD_NUMBER      9
-#define PATCH_LEVEL       1
+#define PATCH_LEVEL       6
 #define CANDIDATE_VERSION false
 
 // Define SONAME to have the SCons build the put a specific SONAME into the
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 5abf3c8..e9f29f0 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -6863,6 +6863,13 @@
   Condition both_smi = masm()->CheckBothSmi(index1.reg(), index2.reg());
   deferred->Branch(NegateCondition(both_smi));
 
+  // Check that both indices are valid.
+  __ movq(tmp2.reg(), FieldOperand(object.reg(), JSArray::kLengthOffset));
+  __ cmpl(tmp2.reg(), index1.reg());
+  deferred->Branch(below_equal);
+  __ cmpl(tmp2.reg(), index2.reg());
+  deferred->Branch(below_equal);
+
   // Bring addresses into index1 and index2.
   __ SmiToInteger32(index1.reg(), index1.reg());
   __ lea(index1.reg(), FieldOperand(tmp1.reg(),
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index ee80169..a1aa976 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -197,6 +197,11 @@
 }
 
 
+void FullCodeGenerator::ClearAccumulator() {
+  __ xor_(rax, rax);
+}
+
+
 void FullCodeGenerator::EmitReturnSequence() {
   Comment cmnt(masm_, "[ Return sequence");
   if (return_label_.is_bound()) {
diff --git a/test/mjsunit/regress/regress-974.js b/test/mjsunit/regress/regress-974.js
new file mode 100644
index 0000000..d6362cd
--- /dev/null
+++ b/test/mjsunit/regress/regress-974.js
@@ -0,0 +1,32 @@
+// Copyright 2010 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
+
+// Verify that GC is safe in a finally block entered by falling off the try
+// block.
+eval("(function(){try {  } catch(x) {  } finally { gc() }})")();
diff --git a/test/mjsunit/regress/regress-swapelements.js b/test/mjsunit/regress/regress-swapelements.js
new file mode 100644
index 0000000..7c7a683
--- /dev/null
+++ b/test/mjsunit/regress/regress-swapelements.js
@@ -0,0 +1,55 @@
+// Copyright 2010 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.
+
+// Check that modifying an array while sorting it does not segfault. See
+// http://code.google.com/p/chromium/issues/detail?id=66099.
+
+function Item(val) {
+  this.value = val;
+}
+
+
+var size = 23;
+var array1 = new Array(size);
+
+
+function myToString() {
+  array1.splice(0, 1);
+  return this.value.toString();
+}
+
+
+function test() {
+  for (var i = 0; i < size; i++) {
+    array1[i] = new Item(i);
+    array1[i].toString = myToString;
+  }
+  array1.sort();
+}
+
+
+test();
diff --git a/test/mjsunit/with-readonly.js b/test/mjsunit/with-readonly.js
new file mode 100644
index 0000000..e29520a
--- /dev/null
+++ b/test/mjsunit/with-readonly.js
@@ -0,0 +1,43 @@
+// Copyright 2010 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.
+
+// Test that readonly variables are treated correctly.
+
+// Create an object with a read-only length property in the prototype
+// chain by putting the string split function in the prototype chain.
+var o = {};
+o.__proto__ = String.prototype.split;
+
+function f() {
+  with (o) {
+    length = 23;
+    length = 24;
+    assertEquals(24, length);
+  }
+}
+f();
+