Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE

This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.

FPIIM-449

Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/test/mjsunit/compiler/debug-catch-prediction.js b/test/mjsunit/compiler/debug-catch-prediction.js
new file mode 100644
index 0000000..34d3afd
--- /dev/null
+++ b/test/mjsunit/compiler/debug-catch-prediction.js
@@ -0,0 +1,143 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug event catch prediction for thrown exceptions. We distinguish
+// between "caught" and "uncaught" based on the following assumptions:
+//  1) try-catch   : Will always catch the exception.
+//  2) try-finally : Will always re-throw the exception.
+
+Debug = debug.Debug;
+
+var log = [];
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Exception) {
+      log.push([event_data.exception(), event_data.uncaught()]);
+    }
+  } catch (e) {
+    %AbortJS(e + "\n" + e.stack);
+  }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+(function TryCatch() {
+  log = [];  // Clear log.
+  function f(a) {
+    try {
+      throw "boom" + a;
+    } catch(e) {
+      return e;
+    }
+  }
+  assertEquals("boom1", f(1));
+  assertEquals("boom2", f(2));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("boom3", f(3));
+  print("Collect log:", log);
+  assertEquals([["boom1",false], ["boom2",false], ["boom3",false]], log);
+})();
+
+(function TryFinally() {
+  log = [];  // Clear log.
+  function f(a) {
+    try {
+      throw "baem" + a;
+    } finally {
+      return a + 10;
+    }
+  }
+  assertEquals(11, f(1));
+  assertEquals(12, f(2));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(13, f(3));
+  print("Collect log:", log);
+  assertEquals([["baem1",true], ["baem2",true], ["baem3",true]], log);
+})();
+
+(function TryCatchFinally() {
+  log = [];  // Clear log.
+  function f(a) {
+    try {
+      throw "wosh" + a;
+    } catch(e) {
+      return e + a;
+    } finally {
+      // Nothing.
+    }
+  }
+  assertEquals("wosh11", f(1));
+  assertEquals("wosh22", f(2));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("wosh33", f(3));
+  print("Collect log:", log);
+  assertEquals([["wosh1",false], ["wosh2",false], ["wosh3",false]], log);
+})();
+
+(function TryCatchNestedFinally() {
+  log = [];  // Clear log.
+  function f(a) {
+    try {
+      try {
+        throw "bang" + a;
+      } finally {
+        // Nothing.
+      }
+    } catch(e) {
+      return e + a;
+    }
+  }
+  assertEquals("bang11", f(1));
+  assertEquals("bang22", f(2));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals("bang33", f(3));
+  print("Collect log:", log);
+  assertEquals([["bang1",false], ["bang2",false], ["bang3",false]], log);
+})();
+
+(function TryFinallyNestedCatch() {
+  log = [];  // Clear log.
+  function f(a) {
+    try {
+      try {
+        throw "peng" + a;
+      } catch(e) {
+        return e
+      }
+    } finally {
+      return a + 10;
+    }
+  }
+  assertEquals(11, f(1));
+  assertEquals(12, f(2));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(13, f(3));
+  print("Collect log:", log);
+  assertEquals([["peng1",false], ["peng2",false], ["peng3",false]], log);
+})();
+
+(function TryFinallyNestedFinally() {
+  log = [];  // Clear log.
+  function f(a) {
+    try {
+      try {
+        throw "oops" + a;
+      } finally {
+        // Nothing.
+      }
+    } finally {
+      return a + 10;
+    }
+  }
+  assertEquals(11, f(1));
+  assertEquals(12, f(2));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(13, f(3));
+  print("Collect log:", log);
+  assertEquals([["oops1",true], ["oops2",true], ["oops3",true]], log);
+})();
diff --git a/test/mjsunit/compiler/deopt-materialize-accumulator.js b/test/mjsunit/compiler/deopt-materialize-accumulator.js
new file mode 100644
index 0000000..c80e329
--- /dev/null
+++ b/test/mjsunit/compiler/deopt-materialize-accumulator.js
@@ -0,0 +1,41 @@
+// Copyright 2016 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
+//
+// Tests that Turbofan correctly materializes values which are in the
+// interpreters accumulator during deopt.
+
+var global = 3;
+function f(a) {
+  // This will trigger a deopt since global was previously a SMI, with the
+  // accumulator holding an unboxed double which needs materialized.
+  global = %_MathSqrt(a);
+}
+%OptimizeFunctionOnNextCall(f);
+f(0.25);
+assertEquals(0.5, global);
diff --git a/test/mjsunit/compiler/double-array-to-global.js b/test/mjsunit/compiler/double-array-to-global.js
new file mode 100644
index 0000000..e221d90
--- /dev/null
+++ b/test/mjsunit/compiler/double-array-to-global.js
@@ -0,0 +1,17 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var a = [-0, 0];
+var b;
+function foo(a) {
+  for (var i = 0; i < 2; ++i) {
+    b = a[i];
+  }
+}
+foo(a);
+foo(a);
+%OptimizeFunctionOnNextCall(foo);
+foo(a);
diff --git a/test/mjsunit/compiler/inline-arguments.js b/test/mjsunit/compiler/inline-arguments.js
index d52f31b..1337ab2 100644
--- a/test/mjsunit/compiler/inline-arguments.js
+++ b/test/mjsunit/compiler/inline-arguments.js
@@ -309,29 +309,3 @@
   delete forceDeopt.deopt;
   outer();
 })();
-
-
-// Test inlining of functions with %_Arguments and %_ArgumentsLength intrinsic.
-(function () {
-  function inner(len,a,b,c) {
-    assertSame(len, %_ArgumentsLength());
-    for (var i = 1; i < len; ++i) {
-      var c = String.fromCharCode(96 + i);
-      assertSame(c, %_Arguments(i));
-    }
-  }
-
-  function outer() {
-    inner(1);
-    inner(2, 'a');
-    inner(3, 'a', 'b');
-    inner(4, 'a', 'b', 'c');
-    inner(5, 'a', 'b', 'c', 'd');
-    inner(6, 'a', 'b', 'c', 'd', 'e');
-  }
-
-  outer();
-  outer();
-  %OptimizeFunctionOnNextCall(outer);
-  outer();
-})();
diff --git a/test/mjsunit/compiler/minus-zero.js b/test/mjsunit/compiler/minus-zero.js
index c161257..ac66350 100644
--- a/test/mjsunit/compiler/minus-zero.js
+++ b/test/mjsunit/compiler/minus-zero.js
@@ -37,31 +37,8 @@
 assertEquals(-0, add(-0, -0));
 
 
-function test(x, y) {
-  assertTrue(%_IsMinusZero(-0));
-  assertTrue(%_IsMinusZero(1/(-Infinity)));
-  assertTrue(%_IsMinusZero(x));
-
-  assertFalse(%_IsMinusZero(0));
-  assertFalse(%_IsMinusZero(1/Infinity));
-  assertFalse(%_IsMinusZero(0.1));
-  assertFalse(%_IsMinusZero(-0.2));
-  assertFalse(%_IsMinusZero({}));
-  assertFalse(%_IsMinusZero(""));
-  assertFalse(%_IsMinusZero("-0"));
-  assertFalse(%_IsMinusZero(function() {}));
-  assertFalse(%_IsMinusZero(y));
-}
-
-test(-0, 1.2);
-test(-0, 1.2);
-%OptimizeFunctionOnNextCall(test);
-test(-0, 1.2);
-assertOptimized(test);
-
-
 function testsin() {
-  assertTrue(%_IsMinusZero(Math.sin(-0)));
+  assertEquals(-0, Math.sin(-0));
 }
 
 testsin();
@@ -71,8 +48,7 @@
 
 
 function testfloor() {
-  assertTrue(%_IsMinusZero(Math.floor(-0)));
-  assertFalse(%_IsMinusZero(Math.floor(2)));
+  assertEquals(-0, Math.floor(-0));
 }
 
 testfloor();
diff --git a/test/mjsunit/compiler/optimized-for-in.js b/test/mjsunit/compiler/optimized-for-in.js
index f3ff6be..d93344e 100644
--- a/test/mjsunit/compiler/optimized-for-in.js
+++ b/test/mjsunit/compiler/optimized-for-in.js
@@ -25,8 +25,7 @@
 // (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: --optimize-for-in --allow-natives-syntax
-// Flags: --no-concurrent-osr
+// Flags: --allow-natives-syntax --no-concurrent-osr
 
 // Test for-in support in Crankshaft.  For simplicity this tests assumes certain
 // fixed iteration order for properties and will have to be adjusted if V8
diff --git a/test/mjsunit/compiler/regress-1085.js b/test/mjsunit/compiler/regress-1085.js
index cea587f..533cf59 100644
--- a/test/mjsunit/compiler/regress-1085.js
+++ b/test/mjsunit/compiler/regress-1085.js
@@ -33,6 +33,5 @@
 
 for (var i = 0; i < 5; ++i) f(1);
 %OptimizeFunctionOnNextCall(f);
-%OptimizeFunctionOnNextCall(Math.min);
 
 assertEquals(-Infinity, f(-0));
diff --git a/test/mjsunit/compiler/regress-dead-throw-inlining.js b/test/mjsunit/compiler/regress-dead-throw-inlining.js
new file mode 100644
index 0000000..097a20b
--- /dev/null
+++ b/test/mjsunit/compiler/regress-dead-throw-inlining.js
@@ -0,0 +1,13 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function g() { if (false) throw 0; }
+function f() { g(); }
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/test/mjsunit/compiler/regress-max.js b/test/mjsunit/compiler/regress-max.js
index ee2fd58..7556f2f 100644
--- a/test/mjsunit/compiler/regress-max.js
+++ b/test/mjsunit/compiler/regress-max.js
@@ -29,7 +29,6 @@
 
 // Test Math.max with negative zero as input.
 for (var i = 0; i < 5; i++) Math.max(0, 0);
-%OptimizeFunctionOnNextCall(Math.max);
 Math.max(0, 0);
 
 var r = Math.max(-0, -0);
diff --git a/test/mjsunit/compiler/try-catch-deopt.js b/test/mjsunit/compiler/try-catch-deopt.js
new file mode 100644
index 0000000..2b6372c
--- /dev/null
+++ b/test/mjsunit/compiler/try-catch-deopt.js
@@ -0,0 +1,225 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+(function LazyDeoptFromTryBlock() {
+  function g(dummy) {
+    %DeoptimizeFunction(f);
+    throw 42;
+  }
+
+  function f() {
+    var a = 1;
+    try {
+      var dummy = 2;  // perturb the stack height.
+      g(dummy);
+    } catch (e) {
+      return e + a;
+    }
+  }
+
+  assertEquals(43, f());
+  assertEquals(43, f());
+  %NeverOptimizeFunction(g);
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(43, f());
+})();
+
+
+(function LazyDeoptDoublyNestedTryBlock() {
+  function g(dummy) {
+    %DeoptimizeFunction(f);
+    throw 42;
+  }
+
+  function f() {
+    var b;
+    try {
+      var a = 1;
+      try {
+        var dummy = 2;  // perturb the stack height.
+        g(dummy);
+      } catch (e) {
+        b = e + a;
+      }
+    } catch (e) {
+      return 0;
+    }
+    return b;
+  }
+
+  assertEquals(43, f());
+  assertEquals(43, f());
+  %NeverOptimizeFunction(g);
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(43, f());
+})();
+
+(function LazyDeoptInlinedTry() {
+  function g(dummy) {
+    %DeoptimizeFunction(f);
+    %DeoptimizeFunction(h);
+    throw 42;
+  }
+
+  function h() {
+    var a = 1;
+    try {
+      var dummy = 2;  // perturb the stack height.
+      g(dummy);
+    } catch (e) {
+      b = e + a;
+    }
+    return b;
+  }
+
+  function f() {
+    var c = 1;
+    return h() + 1;
+  }
+
+  assertEquals(44, f());
+  assertEquals(44, f());
+  %NeverOptimizeFunction(g);
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(44, f());
+})();
+
+(function LazyDeoptInlinedIntoTry() {
+  function g(c) {
+    %DeoptimizeFunction(f);
+    %DeoptimizeFunction(h);
+    throw c;
+  }
+
+  function h(c) {
+    return g(c);
+  }
+
+  function f() {
+    var a = 1;
+    try {
+      var c = 42;  // perturb the stack height.
+      h(c);
+    } catch (e) {
+      a += e;
+    }
+    return a;
+  }
+
+  assertEquals(43, f());
+  assertEquals(43, f());
+  %NeverOptimizeFunction(g);
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(43, f());
+})();
+
+(function LazyDeoptTryBlockContextCatch() {
+  var global = 0;
+
+  function g() {
+    %DeoptimizeFunction(f);
+    throw "boom!";
+  }
+
+  function f(a) {
+    var x = a + 23
+    try {
+      let y = a + 42;
+      function capture() { return x + y }
+      g();
+    } catch(e) {
+      global = x;
+    }
+    return x;
+  }
+  assertEquals(23, f(0));
+  assertEquals(24, f(1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(25, f(2));
+  assertEquals(25, global);
+})();
+
+(function LazyDeoptTryBlockFinally() {
+  var global = 0;
+
+  function g() {
+    %DeoptimizeFunction(f);
+    throw "boom!";
+  }
+
+  function f(a) {
+    var x = a + 23
+    try {
+      let y = a + 42;
+      function capture() { return x + y }
+      g();
+    } finally {
+      global = x;
+    }
+    return x;
+  }
+  assertThrows(function() { f(0) });
+  assertThrows(function() { f(1) });
+  %OptimizeFunctionOnNextCall(f);
+  assertThrowsEquals(function() { f(2) }, "boom!");
+  assertEquals(25, global);
+})();
+
+(function LazyDeoptTryCatchContextCatch() {
+  var global = 0;
+
+  function g() {
+    %DeoptimizeFunction(f);
+    throw 5;
+  }
+
+  function f(a) {
+    var x = a + 23
+    try {
+      try {
+        throw 1;
+      } catch(e2) {
+        function capture() { return x + y }
+        g();
+      }
+    } catch(e) {
+      global = x + e;
+    }
+    return x;
+  }
+  assertEquals(23, f(0));
+  assertEquals(24, f(1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(25, f(2));
+  assertEquals(30, global);
+})();
+
+(function LazyDeoptTryWithContextCatch() {
+  var global = 0;
+
+  function g() {
+    %DeoptimizeFunction(f);
+    throw 5;
+  }
+
+  function f(a) {
+    var x = a + 23
+    try {
+      with ({ y : a + 42 }) {
+        function capture() { return x + y }
+        g();
+      }
+    } catch(e) {
+      global = x + e;
+    }
+    return x;
+  }
+  assertEquals(23, f(0));
+  assertEquals(24, f(1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(25, f(2));
+  assertEquals(30, global);
+})();
diff --git a/test/mjsunit/compiler/try-context.js b/test/mjsunit/compiler/try-context.js
new file mode 100644
index 0000000..4e6d9b0
--- /dev/null
+++ b/test/mjsunit/compiler/try-context.js
@@ -0,0 +1,89 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+(function TryBlockCatch() {
+  var global = 0;
+  function f(a) {
+    var x = a + 23
+    try {
+      let y = a + 42;
+      function capture() { return x + y }
+      throw "boom!";
+    } catch(e) {
+      global = x;
+    }
+    return x;
+  }
+  assertEquals(23, f(0));
+  assertEquals(24, f(1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(25, f(2));
+  assertEquals(25, global);
+})();
+
+(function TryBlockFinally() {
+  var global = 0;
+  function f(a) {
+    var x = a + 23
+    try {
+      let y = a + 42;
+      function capture() { return x + y }
+      throw "boom!";
+    } finally {
+      global = x;
+    }
+    return x;
+  }
+  assertThrows(function() { f(0) });
+  assertThrows(function() { f(1) });
+  %OptimizeFunctionOnNextCall(f);
+  assertThrows(function() { f(2) });
+  assertEquals(25, global);
+})();
+
+(function TryCatchCatch() {
+  var global = 0;
+  function f(a) {
+    var x = a + 23
+    try {
+      try {
+        throw "boom!";
+      } catch(e2) {
+        function capture() { return x + y }
+        throw "boom!";
+      }
+    } catch(e) {
+      global = x;
+    }
+    return x;
+  }
+  assertEquals(23, f(0));
+  assertEquals(24, f(1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(25, f(2));
+  assertEquals(25, global);
+})();
+
+(function TryWithCatch() {
+  var global = 0;
+  function f(a) {
+    var x = a + 23
+    try {
+      with ({ y : a + 42 }) {
+        function capture() { return x + y }
+        throw "boom!";
+      }
+    } catch(e) {
+      global = x;
+    }
+    return x;
+  }
+  assertEquals(23, f(0));
+  assertEquals(24, f(1));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(25, f(2));
+  assertEquals(25, global);
+})();
diff --git a/test/mjsunit/compiler/try-finally-deopt.js b/test/mjsunit/compiler/try-finally-deopt.js
new file mode 100644
index 0000000..455bf34
--- /dev/null
+++ b/test/mjsunit/compiler/try-finally-deopt.js
@@ -0,0 +1,249 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+(function DeoptimizeFinallyFallThrough() {
+  var global = 0;
+  function f() {
+    var a = 1;
+    try {
+      global = 1;
+    } finally {
+      global = 42;
+      %DeoptimizeNow();
+    }
+    return global + a;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(43, f());
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyReturn() {
+  var global = 0;
+  function f() {
+    try {
+      return 10;
+    } finally {
+      global = 42;
+      %DeoptimizeNow();
+    }
+    return 1;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(10, f());
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyReturnDoublyNested() {
+  var global = 0;
+  function f() {
+    try {
+      try {
+        return 10;
+      } finally {
+        global += 21;
+        %DeoptimizeNow();
+      }
+    } finally {
+      global += 21;
+    }
+    return 1;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  global = 0;
+  assertEquals(10, f());
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeOuterFinallyReturnDoublyNested() {
+  var global = 0;
+  function f() {
+    try {
+      try {
+        return 10;
+      } finally {
+        global += 21;
+      }
+    } finally {
+      global += 21;
+      %DeoptimizeNow();
+    }
+    return 1;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  global = 0;
+  assertEquals(10, f());
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyThrow() {
+  var global = 0;
+  function f() {
+    try {
+      global = 21;
+      throw 1;
+      global = 2;
+    } finally {
+      global += 21;
+      %DeoptimizeNow();
+    }
+    global = 3;
+    return 1;
+  }
+
+  try { f(); } catch(e) {}
+  try { f(); } catch(e) {}
+  %OptimizeFunctionOnNextCall(f);
+  assertThrowsEquals(f, 1);
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyThrowNested() {
+  var global = 0;
+  function f() {
+    try {
+      try {
+        global = 10;
+        throw 1;
+        global = 2;
+      } finally {
+        global += 11;
+        %DeoptimizeNow();
+      }
+      global = 4;
+    } finally {
+      global += 21;
+    }
+    global = 3;
+    return 1;
+  }
+
+  try { f(); } catch(e) {}
+  try { f(); } catch(e) {}
+  %OptimizeFunctionOnNextCall(f);
+  assertThrowsEquals(f, 1);
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyContinue() {
+  var global = 0;
+  function f() {
+    global = 0;
+    for (var i = 0; i < 2; i++) {
+      try {
+        if (i == 0) continue;
+        global += 10;
+      } finally {
+        global += 6;
+        %DeoptimizeNow();
+      }
+      global += 20;
+    }
+    return 1;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(1, f());
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyContinueNestedTry() {
+  var global = 0;
+  function f() {
+    global = 0;
+    for (var i = 0; i < 2; i++) {
+      try {
+        try {
+          if (i == 0) continue;
+          global += 5;
+        } finally {
+          global += 4;
+          %DeoptimizeNow();
+        }
+        global += 5;
+      } finally {
+        global += 2;
+      }
+      global += 20;
+    }
+    return 1;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(1, f());
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyBreak() {
+  var global = 0;
+  function f() {
+    global = 0;
+    for (var i = 0; i < 2; i++) {
+      try {
+        global += 20;
+        if (i == 0) break;
+        global += 5;
+      } finally {
+        global += 22;
+        %DeoptimizeNow();
+      }
+      global += 5;
+    }
+    return 1;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(1, f());
+  assertEquals(42, global);
+})();
+
+(function DeoptimizeFinallyBreakNested() {
+  var global = 0;
+  function f() {
+    global = 0;
+    for (var i = 0; i < 2; i++) {
+      try {
+        try {
+          global += 20;
+          if (i == 0) break;
+          global += 5;
+        } finally {
+          global += 12;
+          %DeoptimizeNow();
+        }
+        global += 8;
+      } finally {
+        global += 10;
+      }
+      global += 5;
+    }
+    return 1;
+  }
+
+  f();
+  f();
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(1, f());
+  assertEquals(42, global);
+})();