Test for wrong arguments object materialization.

The test demonstrates a bad interaction between arguments object
materialization, escape analysis and exception handling.

We can return a wrong arguments object if we materialize arguments
object (using f.arguments) and then throw around f's frame so that f
does not clean up the materialized frame information (see the
MaterializedObjectStore in deoptimizer.h/.cc). If we enter another
function that has the same frame pointer and request an arguments object
of (or lazily deoptimize) that function, we can get the materialized
object of the original function.

We should clean up the materialized object store when we unwind the
stack.

BUG=v8:3985
LOG=n

Review URL: https://codereview.chromium.org/1032623003

Cr-Commit-Position: refs/heads/master@{#27406}
This commit is contained in:
jarin 2015-03-24 06:20:10 -07:00 committed by Commit bot
parent 01269228b8
commit 0f94c96cbc
2 changed files with 49 additions and 0 deletions

View File

@ -184,6 +184,10 @@
# nosse2. Also for arm novfp3.
'regress/regress-2989': [FAIL, NO_VARIANTS, ['system == linux and arch == x87 or arch == arm and simulator == True', PASS]],
# BUG(v8:3985). Wrong materialization of arguments object after throwing
# an exception.
'regress/regress-3985': [PASS, FAIL],
# Skip endain dependent test for mips due to different typed views of the same
# array buffer.
'nans': [PASS, ],

View File

@ -0,0 +1,45 @@
// 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 shouldThrow = false;
function h() {
try { // Prevent inlining in Crankshaft.
} catch(e) { }
var res = g.arguments[0].x;
if (shouldThrow) {
throw res;
}
return res;
}
function g(o) { h(); }
function f1() {
var o = { x : 1 };
g(o);
return o.x;
}
function f2() {
var o = { x : 2 };
g(o);
return o.x;
}
f1();
f2();
f1();
f2();
%OptimizeFunctionOnNextCall(f1);
%OptimizeFunctionOnNextCall(f2);
shouldThrow = true;
try { f1(); } catch(e) {
assertEquals(e, 1);
}
try { f2(); } catch(e) {
assertEquals(e, 2);
}