Index: src/compiler/ast-graph-builder.cc |
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc |
index 63696e45cd2e7f2dbe932a2ac415e1c76e30053e..b5a89dac947678a997380821fd959c11415f6482 100644 |
--- a/src/compiler/ast-graph-builder.cc |
+++ b/src/compiler/ast-graph-builder.cc |
@@ -1737,10 +1737,14 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
VisitForValue(subexpr); |
+ Node* frame_state_before = environment()->Checkpoint( |
+ subexpr->id(), OutputFrameStateCombine::PokeAt(0)); |
Node* value = environment()->Pop(); |
Node* index = jsgraph()->Constant(i); |
Node* store = BuildKeyedStore(literal, index, value); |
- PrepareFrameState(store, expr->GetIdForElement(i)); |
+ PrepareFrameStateAfterAndBefore(store, expr->GetIdForElement(i), |
+ OutputFrameStateCombine::Ignore(), |
+ frame_state_before); |
} |
environment()->Pop(); // Array literal index. |
@@ -1781,7 +1785,10 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
Node* object = environment()->Pop(); |
value = environment()->Pop(); |
Node* store = BuildKeyedStore(object, key, value); |
- PrepareFrameState(store, bailout_id); |
+ // TODO(jarin) Provide a real frame state before. |
+ PrepareFrameStateAfterAndBefore(store, bailout_id, |
+ OutputFrameStateCombine::Ignore(), |
+ jsgraph()->EmptyFrameState()); |
break; |
} |
} |
@@ -1812,6 +1819,8 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
// Evaluate the value and potentially handle compound assignments by loading |
// the left-hand side value and performing a binary operation. |
+ Node* frame_state_before_store = nullptr; |
+ bool needs_frame_state_before = (assign_type == KEYED_PROPERTY); |
if (expr->is_compound()) { |
Node* old_value = NULL; |
switch (assign_type) { |
@@ -1853,8 +1862,21 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
OutputFrameStateCombine::Push(), |
frame_state_before); |
environment()->Push(value); |
+ if (needs_frame_state_before) { |
+ frame_state_before_store = environment()->Checkpoint( |
+ expr->binary_operation()->id(), OutputFrameStateCombine::PokeAt(0)); |
+ } |
} else { |
VisitForValue(expr->value()); |
+ if (needs_frame_state_before) { |
+ // This frame state can be used for lazy-deopting from a to-number |
+ // conversion if we are storing into a typed array. It is important |
+ // that the frame state is usable for such lazy deopt (i.e., it has |
+ // to specify how to override the value before the conversion, in this |
+ // case, it overwrites the stack top). |
+ frame_state_before_store = environment()->Checkpoint( |
+ expr->value()->id(), OutputFrameStateCombine::PokeAt(0)); |
+ } |
} |
// Store the value. |
@@ -1877,7 +1899,9 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
Node* key = environment()->Pop(); |
Node* object = environment()->Pop(); |
Node* store = BuildKeyedStore(object, key, value); |
- PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); |
+ PrepareFrameStateAfterAndBefore(store, expr->id(), |
+ ast_context()->GetStateCombine(), |
+ frame_state_before_store); |
break; |
} |
} |
@@ -2176,6 +2200,11 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) { |
PrepareFrameState(old_value, expr->ToNumberId(), |
OutputFrameStateCombine::Push()); |
+ Node* frame_state_before_store = |
+ assign_type == KEYED_PROPERTY |
+ ? environment()->Checkpoint(expr->ToNumberId()) |
+ : nullptr; |
+ |
// Save result for postfix expressions at correct stack depth. |
if (is_postfix) environment()->Poke(stack_depth, old_value); |
@@ -2212,7 +2241,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) { |
Node* object = environment()->Pop(); |
Node* store = BuildKeyedStore(object, key, value); |
environment()->Push(value); |
- PrepareFrameState(store, expr->AssignmentId()); |
+ PrepareFrameStateAfterAndBefore(store, expr->AssignmentId(), |
+ OutputFrameStateCombine::Ignore(), |
+ frame_state_before_store); |
environment()->Pop(); |
break; |
} |