Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Unified Diff: src/compiler/ast-graph-builder.cc

Issue 453383002: More lazy deoptimization in Turbofan (binops, loads/stores) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Attempt to fix the 64-bit Windows build Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/code-generator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 2c242cbe1434c28cf76f0ef8bfb583fa277fa69e..328156b551709315c023ddaea5bfb56bfc9bf119 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -238,8 +238,12 @@ Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id) {
AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
- Expression::Context kind)
- : kind_(kind), owner_(own), outer_(own->ast_context()) {
+ Expression::Context kind,
+ BailoutId bailout_id)
+ : bailout_id_(bailout_id),
+ kind_(kind),
+ owner_(own),
+ outer_(own->ast_context()) {
owner()->set_ast_context(this); // Push.
#ifdef DEBUG
original_height_ = environment()->stack_height();
@@ -267,6 +271,28 @@ AstGraphBuilder::AstTestContext::~AstTestContext() {
}
+void AstGraphBuilder::AstEffectContext::ProduceValueWithLazyBailout(
+ Node* value) {
+ ProduceValue(value);
+ owner()->BuildLazyBailout(value, bailout_id_);
+}
+
+
+void AstGraphBuilder::AstValueContext::ProduceValueWithLazyBailout(
+ Node* value) {
+ ProduceValue(value);
+ owner()->BuildLazyBailout(value, bailout_id_);
+}
+
+
+void AstGraphBuilder::AstTestContext::ProduceValueWithLazyBailout(Node* value) {
+ environment()->Push(value);
+ owner()->BuildLazyBailout(value, bailout_id_);
+ environment()->Pop();
+ ProduceValue(value);
+}
+
+
void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) {
// The value is ignored.
}
@@ -333,7 +359,7 @@ void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
void AstGraphBuilder::VisitForValue(Expression* expr) {
- AstValueContext for_value(this);
+ AstValueContext for_value(this, expr->id());
if (!HasStackOverflow()) {
expr->Accept(this);
}
@@ -341,7 +367,7 @@ void AstGraphBuilder::VisitForValue(Expression* expr) {
void AstGraphBuilder::VisitForEffect(Expression* expr) {
- AstEffectContext for_effect(this);
+ AstEffectContext for_effect(this, expr->id());
if (!HasStackOverflow()) {
expr->Accept(this);
}
@@ -349,7 +375,7 @@ void AstGraphBuilder::VisitForEffect(Expression* expr) {
void AstGraphBuilder::VisitForTest(Expression* expr) {
- AstTestContext for_condition(this);
+ AstTestContext for_condition(this, expr->id());
if (!HasStackOverflow()) {
expr->Accept(this);
}
@@ -686,6 +712,8 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
Node* index = environment()->Peek(0);
Node* exit_cond =
NewNode(javascript()->LessThan(), index, cache_length);
+ // TODO(jarin): provide real bailout id.
+ BuildLazyBailout(exit_cond, BailoutId::None());
for_loop.BreakUnless(exit_cond);
// TODO(dcarney): this runtime call should be a handful of
// simplified instructions that
@@ -724,6 +752,8 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
// is gone.
Node* res = ProcessArguments(
javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3);
+ // TODO(jarin): provide real bailout id.
+ BuildLazyBailout(res, BailoutId::None());
Node* property_missing = NewNode(javascript()->StrictEqual(), res,
jsgraph()->ZeroConstant());
{
@@ -829,7 +859,7 @@ void AstGraphBuilder::VisitConditional(Conditional* expr) {
void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
- Node* value = BuildVariableLoad(expr->var());
+ Node* value = BuildVariableLoad(expr->var(), expr->id());
ast_context()->ProduceValue(value);
}
@@ -896,7 +926,9 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForValue(property->value());
Node* value = environment()->Pop();
PrintableUnique<Name> name = MakeUnique(key->AsPropertyName());
- NewNode(javascript()->StoreNamed(name), literal, value);
+ Node* store =
+ NewNode(javascript()->StoreNamed(name), literal, value);
+ BuildLazyBailout(store, key->id());
} else {
VisitForEffect(property->value());
}
@@ -987,7 +1019,8 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
VisitForValue(subexpr);
Node* value = environment()->Pop();
Node* index = jsgraph()->Constant(i);
- NewNode(javascript()->StoreProperty(), literal, index, value);
+ Node* store = NewNode(javascript()->StoreProperty(), literal, index, value);
+ BuildLazyBailout(store, expr->GetIdForElement(i));
}
environment()->Pop(); // Array literal index.
@@ -1006,7 +1039,8 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
switch (assign_type) {
case VARIABLE: {
Variable* var = expr->AsVariableProxy()->var();
- BuildVariableAssignment(var, value, Token::ASSIGN);
+ // TODO(jarin) Fill in the correct bailout id.
+ BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None());
break;
}
case NAMED_PROPERTY: {
@@ -1016,7 +1050,9 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
value = environment()->Pop();
PrintableUnique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
- NewNode(javascript()->StoreNamed(name), object, value);
+ Node* store = NewNode(javascript()->StoreNamed(name), object, value);
+ // TODO(jarin) Fill in the correct bailout id.
+ BuildLazyBailout(store, BailoutId::None());
break;
}
case KEYED_PROPERTY: {
@@ -1026,7 +1062,9 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
Node* key = environment()->Pop();
Node* object = environment()->Pop();
value = environment()->Pop();
- NewNode(javascript()->StoreProperty(), object, key, value);
+ Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
+ // TODO(jarin) Fill in the correct bailout id.
+ BuildLazyBailout(store, BailoutId::None());
break;
}
}
@@ -1062,7 +1100,7 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->target()->AsVariableProxy()->var();
- old_value = BuildVariableLoad(variable);
+ old_value = BuildVariableLoad(variable, expr->target()->id());
break;
}
case NAMED_PROPERTY: {
@@ -1070,12 +1108,14 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
PrintableUnique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
old_value = NewNode(javascript()->LoadNamed(name), object);
+ BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
break;
}
case KEYED_PROPERTY: {
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
old_value = NewNode(javascript()->LoadProperty(), object, key);
+ BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
break;
}
}
@@ -1085,6 +1125,7 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
Node* left = environment()->Pop();
Node* value = BuildBinaryOp(left, right, expr->binary_op());
environment()->Push(value);
+ BuildLazyBailout(value, expr->binary_operation()->id());
} else {
VisitForValue(expr->value());
}
@@ -1094,20 +1135,23 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->target()->AsVariableProxy()->var();
- BuildVariableAssignment(variable, value, expr->op());
+ BuildVariableAssignment(variable, value, expr->op(),
+ expr->AssignmentId());
break;
}
case NAMED_PROPERTY: {
Node* object = environment()->Pop();
PrintableUnique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
- NewNode(javascript()->StoreNamed(name), object, value);
+ Node* store = NewNode(javascript()->StoreNamed(name), object, value);
+ BuildLazyBailout(store, expr->AssignmentId());
break;
}
case KEYED_PROPERTY: {
Node* key = environment()->Pop();
Node* object = environment()->Pop();
- NewNode(javascript()->StoreProperty(), object, key, value);
+ Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
+ BuildLazyBailout(store, expr->AssignmentId());
break;
}
}
@@ -1150,7 +1194,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
Node* object = environment()->Pop();
value = NewNode(javascript()->LoadProperty(), object, key);
}
- ast_context()->ProduceValue(value);
+ ast_context()->ProduceValueWithLazyBailout(value);
}
@@ -1167,7 +1211,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
switch (call_type) {
case Call::GLOBAL_CALL: {
Variable* variable = callee->AsVariableProxy()->var();
- callee_value = BuildVariableLoad(variable);
+ callee_value = BuildVariableLoad(variable, expr->expression()->id());
receiver_value = jsgraph()->UndefinedConstant();
break;
}
@@ -1194,6 +1238,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
Node* key = environment()->Pop();
callee_value = NewNode(javascript()->LoadProperty(), object, key);
}
+ BuildLazyBailoutWithPushedNode(callee_value, property->LoadId());
receiver_value = environment()->Pop();
// Note that a PROPERTY_CALL requires the receiver to be wrapped into an
// object for sloppy callees. This could also be modeled explicitly here,
@@ -1248,7 +1293,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
// Create node to perform the function call.
Operator* call = javascript()->Call(args->length() + 2, flags);
Node* value = ProcessArguments(call, args->length() + 2);
- ast_context()->ProduceValue(value);
+ ast_context()->ProduceValueWithLazyBailout(value);
}
@@ -1262,7 +1307,7 @@ void AstGraphBuilder::VisitCallNew(CallNew* expr) {
// Create node to perform the construct call.
Operator* call = javascript()->CallNew(args->length() + 1);
Node* value = ProcessArguments(call, args->length() + 1);
- ast_context()->ProduceValue(value);
+ ast_context()->ProduceValueWithLazyBailout(value);
}
@@ -1276,6 +1321,9 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
PrintableUnique<String> unique = MakeUnique(name);
Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
environment()->Push(callee_value);
+ // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
+ // refuses to optimize functions with jsruntime calls).
+ BuildLazyBailout(callee_value, BailoutId::None());
environment()->Push(receiver_value);
// Evaluate all arguments to the JS runtime call.
@@ -1285,7 +1333,7 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
// Create node to perform the JS runtime call.
Operator* call = javascript()->Call(args->length() + 2, flags);
Node* value = ProcessArguments(call, args->length() + 2);
- ast_context()->ProduceValue(value);
+ ast_context()->ProduceValueWithLazyBailout(value);
}
@@ -1307,9 +1355,7 @@ void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
Runtime::FunctionId functionId = function->function_id;
Operator* call = javascript()->Runtime(functionId, args->length());
Node* value = ProcessArguments(call, args->length());
- ast_context()->ProduceValue(value);
-
- BuildLazyBailout(value, expr->id());
+ ast_context()->ProduceValueWithLazyBailout(value);
}
@@ -1346,7 +1392,7 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->expression()->AsVariableProxy()->var();
- old_value = BuildVariableLoad(variable);
+ old_value = BuildVariableLoad(variable, expr->expression()->id());
stack_depth = 0;
break;
}
@@ -1356,6 +1402,7 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
PrintableUnique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
old_value = NewNode(javascript()->LoadNamed(name), object);
+ BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
stack_depth = 1;
break;
}
@@ -1365,6 +1412,7 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
old_value = NewNode(javascript()->LoadProperty(), object, key);
+ BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
stack_depth = 2;
break;
}
@@ -1379,25 +1427,31 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
// Create node to perform +1/-1 operation.
Node* value =
BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
+ // TODO(jarin) Insert proper bailout id here (will need to change
+ // full code generator).
+ BuildLazyBailout(value, BailoutId::None());
// Store the value.
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->expression()->AsVariableProxy()->var();
- BuildVariableAssignment(variable, value, expr->op());
+ BuildVariableAssignment(variable, value, expr->op(),
+ expr->AssignmentId());
break;
}
case NAMED_PROPERTY: {
Node* object = environment()->Pop();
PrintableUnique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
- NewNode(javascript()->StoreNamed(name), object, value);
+ Node* store = NewNode(javascript()->StoreNamed(name), object, value);
+ BuildLazyBailout(store, expr->AssignmentId());
break;
}
case KEYED_PROPERTY: {
Node* key = environment()->Pop();
Node* object = environment()->Pop();
- NewNode(javascript()->StoreProperty(), object, key, value);
+ Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
+ BuildLazyBailout(store, expr->AssignmentId());
break;
}
}
@@ -1422,7 +1476,7 @@ void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
Node* right = environment()->Pop();
Node* left = environment()->Pop();
Node* value = BuildBinaryOp(left, right, expr->op());
- ast_context()->ProduceValue(value);
+ ast_context()->ProduceValueWithLazyBailout(value);
}
}
}
@@ -1471,6 +1525,8 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
Node* left = environment()->Pop();
Node* value = NewNode(op, left, right);
ast_context()->ProduceValue(value);
+
+ BuildLazyBailout(value, expr->id());
}
@@ -1550,7 +1606,8 @@ void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
// Typeof does not throw a reference error on global variables, hence we
// perform a non-contextual load in case the operand is a variable proxy.
Variable* variable = expr->expression()->AsVariableProxy()->var();
- operand = BuildVariableLoad(variable, NOT_CONTEXTUAL);
+ operand =
+ BuildVariableLoad(variable, expr->expression()->id(), NOT_CONTEXTUAL);
} else {
VisitForValue(expr->expression());
operand = environment()->Pop();
@@ -1650,7 +1707,8 @@ Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
// Assign the object to the arguments variable.
DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
- BuildVariableAssignment(arguments, object, Token::ASSIGN);
+ // This should never lazy deopt, so it is fine to send invalid bailout id.
+ BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None());
return object;
}
@@ -1687,6 +1745,7 @@ Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable,
Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
+ BailoutId bailout_id,
ContextualMode contextual_mode) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
@@ -1696,7 +1755,9 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
Node* global = BuildLoadGlobalObject();
PrintableUnique<Name> name = MakeUnique(variable->name());
Operator* op = javascript()->LoadNamed(name, contextual_mode);
- return NewNode(op, global);
+ Node* node = NewNode(op, global);
+ BuildLazyBailoutWithPushedNode(node, bailout_id);
+ return node;
}
case Variable::PARAMETER:
case Variable::LOCAL: {
@@ -1785,7 +1846,8 @@ Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) {
Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
- Token::Value op) {
+ Token::Value op,
+ BailoutId bailout_id) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
switch (variable->location()) {
@@ -1794,7 +1856,9 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
Node* global = BuildLoadGlobalObject();
PrintableUnique<Name> name = MakeUnique(variable->name());
Operator* op = javascript()->StoreNamed(name);
- return NewNode(op, global, value);
+ Node* store = NewNode(op, global, value);
+ BuildLazyBailout(store, bailout_id);
+ return store;
}
case Variable::PARAMETER:
case Variable::LOCAL:
@@ -1958,6 +2022,10 @@ void AstGraphBuilder::BuildLazyBailout(Node* node, BailoutId ast_id) {
NewNode(common()->LazyDeoptimization());
+ // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty
+ // deopt block and make sure there is no patch entry for this (so
+ // that the deoptimizer dies when trying to deoptimize here).
+
Node* state_node = environment()->Checkpoint(ast_id);
Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node);
@@ -1970,6 +2038,14 @@ void AstGraphBuilder::BuildLazyBailout(Node* node, BailoutId ast_id) {
NewNode(common()->Continuation());
}
}
+
+
+void AstGraphBuilder::BuildLazyBailoutWithPushedNode(Node* node,
+ BailoutId ast_id) {
+ environment()->Push(node);
+ BuildLazyBailout(node, ast_id);
+ environment()->Pop();
+}
}
}
} // namespace v8::internal::compiler
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/code-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698