| 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;
|
| }
|
|
|