[turbofan] Fix various bailout points for AstGraphBuilder.

This introduces a bunch of new tests that test various aspects of
accessor inlining in TurboFan (without the actual inlining), and does
the appropriate fixes to the AstGraphBuilder. The actual inlining CL
will land separately (so we don't need to revert the tests and fixes
if the accessor CL has to be reverted).

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2197913002
Cr-Commit-Position: refs/heads/master@{#38191}
This commit is contained in:
bmeurer 2016-07-31 23:17:21 -07:00 committed by Commit bot
parent 3e3ff89d4b
commit 986b04a62a
10 changed files with 245 additions and 18 deletions

View File

@ -2240,14 +2240,16 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
Node* object = environment()->Pop(); Node* object = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedStore(object, name, value, feedback); Node* store = BuildNamedStore(object, name, value, feedback);
PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); PrepareFrameState(store, expr->AssignmentId(),
OutputFrameStateCombine::Push());
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
Node* key = environment()->Pop(); Node* key = environment()->Pop();
Node* object = environment()->Pop(); Node* object = environment()->Pop();
Node* store = BuildKeyedStore(object, key, value, feedback); Node* store = BuildKeyedStore(object, key, value, feedback);
PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); PrepareFrameState(store, expr->AssignmentId(),
OutputFrameStateCombine::Push());
break; break;
} }
case NAMED_SUPER_PROPERTY: { case NAMED_SUPER_PROPERTY: {
@ -2300,7 +2302,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
Node* object = environment()->Pop(); Node* object = environment()->Pop();
Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
value = BuildNamedLoad(object, name, pair); value = BuildNamedLoad(object, name, pair);
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
@ -2309,7 +2311,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
Node* key = environment()->Pop(); Node* key = environment()->Pop();
Node* object = environment()->Pop(); Node* object = environment()->Pop();
value = BuildKeyedLoad(object, key, pair); value = BuildKeyedLoad(object, key, pair);
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
break; break;
} }
case NAMED_SUPER_PROPERTY: { case NAMED_SUPER_PROPERTY: {
@ -2319,7 +2321,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
Node* receiver = environment()->Pop(); Node* receiver = environment()->Pop();
Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
value = BuildNamedSuperLoad(receiver, home_object, name, pair); value = BuildNamedSuperLoad(receiver, home_object, name, pair);
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
break; break;
} }
case KEYED_SUPER_PROPERTY: { case KEYED_SUPER_PROPERTY: {
@ -2330,7 +2332,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
Node* home_object = environment()->Pop(); Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop(); Node* receiver = environment()->Pop();
value = BuildKeyedSuperLoad(receiver, home_object, key, pair); value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
break; break;
} }
} }
@ -2754,20 +2756,16 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* object = environment()->Pop(); Node* object = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedStore(object, name, value, feedback); Node* store = BuildNamedStore(object, name, value, feedback);
environment()->Push(value);
PrepareFrameState(store, expr->AssignmentId(), PrepareFrameState(store, expr->AssignmentId(),
OutputFrameStateCombine::Ignore()); OutputFrameStateCombine::Push());
environment()->Pop();
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
Node* key = environment()->Pop(); Node* key = environment()->Pop();
Node* object = environment()->Pop(); Node* object = environment()->Pop();
Node* store = BuildKeyedStore(object, key, value, feedback); Node* store = BuildKeyedStore(object, key, value, feedback);
environment()->Push(value);
PrepareFrameState(store, expr->AssignmentId(), PrepareFrameState(store, expr->AssignmentId(),
OutputFrameStateCombine::Ignore()); OutputFrameStateCombine::Push());
environment()->Pop();
break; break;
} }
case NAMED_SUPER_PROPERTY: { case NAMED_SUPER_PROPERTY: {
@ -2775,10 +2773,8 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* receiver = environment()->Pop(); Node* receiver = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedSuperStore(receiver, home_object, name, value); Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
environment()->Push(value);
PrepareFrameState(store, expr->AssignmentId(), PrepareFrameState(store, expr->AssignmentId(),
OutputFrameStateCombine::Ignore()); OutputFrameStateCombine::Push());
environment()->Pop();
break; break;
} }
case KEYED_SUPER_PROPERTY: { case KEYED_SUPER_PROPERTY: {
@ -2786,10 +2782,8 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* home_object = environment()->Pop(); Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop(); Node* receiver = environment()->Pop();
Node* store = BuildKeyedSuperStore(receiver, home_object, key, value); Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
environment()->Push(value);
PrepareFrameState(store, expr->AssignmentId(), PrepareFrameState(store, expr->AssignmentId(),
OutputFrameStateCombine::Ignore()); OutputFrameStateCombine::Push());
environment()->Pop();
break; break;
} }
} }

View File

@ -0,0 +1,21 @@
// 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
var o = {}
Object.defineProperty(o, "x", {
get: function() { throw 7; }
});
function foo(o) {
var x = 1;
try { o.x; } catch (e) { x = e; }
return x;
}
assertEquals(7, foo(o));
assertEquals(7, foo(o));
%OptimizeFunctionOnNextCall(foo);
assertEquals(7, foo(o));

View File

@ -0,0 +1,21 @@
// 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
var o = {}
Object.defineProperty(o, "x", {
set: function(v) { throw 7; }
});
function foo(o) {
var x = 1;
try { o.x = 2; } catch (e) { x = e; }
return x;
}
assertEquals(7, foo(o));
assertEquals(7, foo(o));
%OptimizeFunctionOnNextCall(foo);
assertEquals(7, foo(o));

View File

@ -0,0 +1,28 @@
// 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
var o = {v:1};
var deopt = false;
Object.defineProperty(o, "x", {
get: function() { return this.v; },
set: function(v) {
this.v = v;
if (deopt) {
%DeoptimizeFunction(foo);
}
}
});
function foo(o) {
return o.x++;
}
assertEquals(1, foo(o));
assertEquals(2, foo(o));
%OptimizeFunctionOnNextCall(foo);
deopt = true;
assertEquals(3, foo(o));

View File

@ -0,0 +1,28 @@
// 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
var o = {v:1};
var deopt = false;
Object.defineProperty(o, "x", {
get: function() { return this.v; },
set: function(v) {
this.v = v;
if (deopt) {
%DeoptimizeFunction(foo);
}
}
});
function foo(o) {
return ++o.x;
}
assertEquals(2, foo(o));
assertEquals(3, foo(o));
%OptimizeFunctionOnNextCall(foo);
deopt = true;
assertEquals(4, foo(o));

View File

@ -0,0 +1,29 @@
// 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
var o = {v:1};
var deopt = false;
Object.defineProperty(o, "x", {
get: function() { return this.v; },
set: function(v) {
this.v = v;
if (deopt) {
%DeoptimizeFunction(foo);
}
}
});
function foo(o) {
var x = "x";
return o[x]++;
}
assertEquals(1, foo(o));
assertEquals(2, foo(o));
%OptimizeFunctionOnNextCall(foo);
deopt = true;
assertEquals(3, foo(o));

View File

@ -0,0 +1,29 @@
// 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
var o = {v:1};
var deopt = false;
Object.defineProperty(o, "x", {
get: function() { return this.v; },
set: function(v) {
this.v = v;
if (deopt) {
%DeoptimizeFunction(foo);
}
}
});
function foo(o) {
var x = "x";
return ++o[x];
}
assertEquals(2, foo(o));
assertEquals(3, foo(o));
%OptimizeFunctionOnNextCall(foo);
deopt = true;
assertEquals(4, foo(o));

View File

@ -0,0 +1,23 @@
// 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 --harmony-tailcalls
"use strict";
function f(v) {
%DeoptimizeFunction(test);
return 153;
}
function test() {
var o = {};
o.__defineSetter__('q', f);
assertEquals(1, o.q = 1);
}
test();
test();
%OptimizeFunctionOnNextCall(test);
test();

View File

@ -0,0 +1,24 @@
// 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 --harmony-tailcalls
"use strict";
function f(v) {
%DeoptimizeFunction(test);
return 153;
}
function test() {
var o = {};
var q = "q";
o.__defineSetter__(q, f);
assertEquals(1, o[q] = 1);
}
test();
test();
%OptimizeFunctionOnNextCall(test);
test();

View File

@ -0,0 +1,30 @@
// 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
var o = {v:1};
var deopt = false;
Object.defineProperty(o, "x", {
get: function() {
if (deopt) %DeoptimizeFunction(foo);
return 1;
}
});
function bar(x, y, z) {
return x + z;
}
function foo(o, x) {
return bar(1, (o[x], 2), 3);
}
assertEquals(4, foo(o, "v"));
assertEquals(4, foo(o, "v"));
assertEquals(4, foo(o, "x"));
assertEquals(4, foo(o, "x"));
%OptimizeFunctionOnNextCall(foo);
deopt = true;
assertEquals(4, foo(o, "x"));