ab3b3bec86
The idea here is to perform the handler lookup in the deoptimizer, and then take the information from the handler table to build the catch handler frame in the deoptimizer. Specifically, we use the pc offset, context location and stack height (in full-code) to tweak the output frame. Sadly, this still requires nasty voodoo for the liveness analyzer so that it keeps variables alive if they are used in the catch handler. Review URL: https://codereview.chromium.org/1416543006 Cr-Commit-Position: refs/heads/master@{#33936}
226 lines
3.9 KiB
JavaScript
226 lines
3.9 KiB
JavaScript
// 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);
|
|
})();
|