diff options
Diffstat (limited to 'deps/v8/test/mjsunit/compiler/escape-analysis.js')
-rw-r--r-- | deps/v8/test/mjsunit/compiler/escape-analysis.js | 141 |
1 files changed, 140 insertions, 1 deletions
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis.js b/deps/v8/test/mjsunit/compiler/escape-analysis.js index 9776f67ccf..74e638a538 100644 --- a/deps/v8/test/mjsunit/compiler/escape-analysis.js +++ b/deps/v8/test/mjsunit/compiler/escape-analysis.js @@ -25,7 +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: --allow-natives-syntax --use-escape-analysis +// Flags: --allow-natives-syntax --use-escape-analysis --expose-gc // Test stores on a join path. @@ -132,3 +132,142 @@ delete deopt.deopt; func(); func(); })(); + + +// Test deoptimization with captured objects on operand stack. +(function testDeoptOperand() { + var deopt = { deopt:false }; + function constructor1() { + this.a = 1.0; + this.b = 2.3; + deopt.deopt; + assertEquals(1.0, this.a); + assertEquals(2.3, this.b); + this.b = 2.7; + this.c = 3.0; + this.d = 4.5; + } + function constructor2() { + this.e = 5.0; + this.f = new constructor1(); + assertEquals(1.0, this.f.a); + assertEquals(2.7, this.f.b); + assertEquals(3.0, this.f.c); + assertEquals(4.5, this.f.d); + assertEquals(5.0, this.e); + this.e = 5.9; + this.g = 6.7; + } + function func() { + var o = new constructor2(); + assertEquals(1.0, o.f.a); + assertEquals(2.7, o.f.b); + assertEquals(3.0, o.f.c); + assertEquals(4.5, o.f.d); + assertEquals(5.9, o.e); + assertEquals(6.7, o.g); + } + func(); func(); + %OptimizeFunctionOnNextCall(func); + func(); func(); + delete deopt.deopt; + func(); func(); +})(); + + +// Test map checks on captured objects. +(function testMapCheck() { + var sum = 0; + function getter() { return 27; } + function setter(v) { sum += v; } + function constructor() { + this.x = 23; + this.y = 42; + } + function check(x, y) { + var o = new constructor(); + assertEquals(x, o.x); + assertEquals(y, o.y); + } + var monkey = Object.create(null, { + x: { get:getter, set:setter }, + y: { get:getter, set:setter } + }); + check(23, 42); check(23, 42); + %OptimizeFunctionOnNextCall(check); + check(23, 42); check(23, 42); + constructor.prototype = monkey; + check(27, 27); check(27, 27); + assertEquals(130, sum); +})(); + + +// Test OSR into a loop with captured objects. +(function testOSR() { + function constructor() { + this.a = 23; + } + function osr1(length) { + assertEquals(23, (new constructor()).a); + var result = 0; + for (var i = 0; i < length; i++) { + result = (result + i) % 99; + } + return result; + } + function osr2(length) { + var result = 0; + for (var i = 0; i < length; i++) { + result = (result + i) % 99; + } + assertEquals(23, (new constructor()).a); + return result; + } + function osr3(length) { + var result = 0; + var o = new constructor(); + for (var i = 0; i < length; i++) { + result = (result + i) % 99; + } + assertEquals(23, o.a); + return result; + } + function test(closure) { + assertEquals(45, closure(10)); + assertEquals(45, closure(10)); + assertEquals(10, closure(50000)); + } + test(osr1); + test(osr2); + test(osr3); +})(); + + +// Test out-of-bounds access on captured objects. +(function testOOB() { + function cons1() { + this.x = 1; + this.y = 2; + this.z = 3; + } + function cons2() { + this.a = 7; + } + function oob(constructor, branch) { + var o = new constructor(); + if (branch) { + return o.a; + } else { + return o.z; + } + } + assertEquals(3, oob(cons1, false)); + assertEquals(3, oob(cons1, false)); + assertEquals(7, oob(cons2, true)); + assertEquals(7, oob(cons2, true)); + gc(); // Clears type feedback of constructor call. + assertEquals(7, oob(cons2, true)); + assertEquals(7, oob(cons2, true)); + %OptimizeFunctionOnNextCall(oob); + assertEquals(7, oob(cons2, true)); +})(); |