Index: test/mjsunit/compiler/try-catch-deopt.js |
diff --git a/test/mjsunit/compiler/try-catch-deopt.js b/test/mjsunit/compiler/try-catch-deopt.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2b6372cf2813dc330fd07dd90fbc75a0197da082 |
--- /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); |
+})(); |