| Index: src/compiler/ast-graph-builder.cc
|
| diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
|
| index f4b8676730d0b7d80b1101bdf201551bf64ba5cd..3f61d5a29bc232e070cb8bdb26a8356515fa0fcf 100644
|
| --- a/src/compiler/ast-graph-builder.cc
|
| +++ b/src/compiler/ast-graph-builder.cc
|
| @@ -1175,7 +1175,9 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
|
| Node* index_inc =
|
| NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
|
| // TODO(jarin): provide real bailout id.
|
| - PrepareFrameState(index_inc, BailoutId::None());
|
| + PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
|
| + OutputFrameStateCombine::Ignore(),
|
| + jsgraph()->EmptyFrameState());
|
| environment()->Poke(0, index_inc);
|
| for_loop.Continue();
|
| is_property_missing.Else();
|
| @@ -1195,7 +1197,9 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
|
| Node* index_inc =
|
| NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
|
| // TODO(jarin): provide real bailout id.
|
| - PrepareFrameState(index_inc, BailoutId::None());
|
| + PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
|
| + OutputFrameStateCombine::Ignore(),
|
| + jsgraph()->EmptyFrameState());
|
| environment()->Poke(0, index_inc);
|
| for_loop.EndLoop();
|
| environment()->Drop(5);
|
| @@ -1816,11 +1820,13 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
|
| }
|
| environment()->Push(old_value);
|
| VisitForValue(expr->value());
|
| + Node* frame_state_before = environment()->Checkpoint(expr->value()->id());
|
| Node* right = environment()->Pop();
|
| Node* left = environment()->Pop();
|
| Node* value = BuildBinaryOp(left, right, expr->binary_op());
|
| - PrepareFrameState(value, expr->binary_operation()->id(),
|
| - OutputFrameStateCombine::Push());
|
| + PrepareFrameStateAfterAndBefore(value, expr->binary_operation()->id(),
|
| + OutputFrameStateCombine::Push(),
|
| + frame_state_before);
|
| environment()->Push(value);
|
| } else {
|
| VisitForValue(expr->value());
|
| @@ -2168,9 +2174,11 @@ 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).
|
| - PrepareFrameState(value, BailoutId::None());
|
| + // This should never deoptimize because we have converted to number
|
| + // before.
|
| + PrepareFrameStateAfterAndBefore(value, BailoutId::None(),
|
| + OutputFrameStateCombine::Ignore(),
|
| + jsgraph()->EmptyFrameState());
|
|
|
| // Store the value.
|
| switch (assign_type) {
|
| @@ -2222,10 +2230,13 @@ void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
|
| default: {
|
| VisitForValue(expr->left());
|
| VisitForValue(expr->right());
|
| + Node* frame_state_before = environment()->Checkpoint(expr->right()->id());
|
| Node* right = environment()->Pop();
|
| Node* left = environment()->Pop();
|
| Node* value = BuildBinaryOp(left, right, expr->op());
|
| - PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
|
| + PrepareFrameStateAfterAndBefore(value, expr->id(),
|
| + ast_context()->GetStateCombine(),
|
| + frame_state_before);
|
| ast_context()->ProduceValue(value);
|
| }
|
| }
|
| @@ -2960,11 +2971,31 @@ bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
|
|
|
| void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
|
| OutputFrameStateCombine combine) {
|
| - if (OperatorProperties::HasFrameStateInput(node->op())) {
|
| - DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() ==
|
| - IrOpcode::kDead);
|
| + if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
|
| + DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
|
| +
|
| + DCHECK_EQ(IrOpcode::kDead,
|
| + NodeProperties::GetFrameStateInput(node, 0)->opcode());
|
| NodeProperties::ReplaceFrameStateInput(
|
| - node, environment()->Checkpoint(ast_id, combine));
|
| + node, 0, environment()->Checkpoint(ast_id, combine));
|
| + }
|
| +}
|
| +
|
| +
|
| +void AstGraphBuilder::PrepareFrameStateAfterAndBefore(
|
| + Node* node, BailoutId ast_id, OutputFrameStateCombine combine,
|
| + Node* frame_state_before) {
|
| + if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
|
| + DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
|
| +
|
| + DCHECK_EQ(IrOpcode::kDead,
|
| + NodeProperties::GetFrameStateInput(node, 0)->opcode());
|
| + NodeProperties::ReplaceFrameStateInput(
|
| + node, 0, environment()->Checkpoint(ast_id, combine));
|
| +
|
| + DCHECK_EQ(IrOpcode::kDead,
|
| + NodeProperties::GetFrameStateInput(node, 1)->opcode());
|
| + NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before);
|
| }
|
| }
|
|
|
| @@ -2991,7 +3022,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
|
| DCHECK(op->ValueInputCount() == value_input_count);
|
|
|
| bool has_context = OperatorProperties::HasContextInput(op);
|
| - bool has_framestate = OperatorProperties::HasFrameStateInput(op);
|
| + int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
|
| bool has_control = op->ControlInputCount() == 1;
|
| bool has_effect = op->EffectInputCount() == 1;
|
|
|
| @@ -2999,13 +3030,13 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
|
| DCHECK(op->EffectInputCount() < 2);
|
|
|
| Node* result = NULL;
|
| - if (!has_context && !has_framestate && !has_control && !has_effect) {
|
| + if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
|
| result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
|
| } else {
|
| bool inside_try_scope = try_nesting_level_ > 0;
|
| int input_count_with_deps = value_input_count;
|
| if (has_context) ++input_count_with_deps;
|
| - if (has_framestate) ++input_count_with_deps;
|
| + input_count_with_deps += frame_state_count;
|
| if (has_control) ++input_count_with_deps;
|
| if (has_effect) ++input_count_with_deps;
|
| Node** buffer = EnsureInputBufferSize(input_count_with_deps);
|
| @@ -3014,7 +3045,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
|
| if (has_context) {
|
| *current_input++ = current_context();
|
| }
|
| - if (has_framestate) {
|
| + for (int i = 0; i < frame_state_count; i++) {
|
| // The frame state will be inserted later. Here we misuse
|
| // the {DeadControl} node as a sentinel to be later overwritten
|
| // with the real frame state.
|
|
|