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);
+})();