diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 9778c79b1e..bc96c4c91a 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -856,7 +856,7 @@ Node* AstGraphBuilder::Environment::Checkpoint( Node* result = graph()->NewNode(op, parameters_node_, locals_node_, stack_node_, builder()->current_context(), builder()->GetFunctionClosure(), - builder()->jsgraph()->UndefinedConstant()); + builder()->graph()->start()); DCHECK(IsLivenessBlockConsistent()); if (liveness_block() != nullptr) { diff --git a/src/compiler/js-graph.cc b/src/compiler/js-graph.cc index 44d5c52772..4d83c86eeb 100644 --- a/src/compiler/js-graph.cc +++ b/src/compiler/js-graph.cc @@ -191,7 +191,7 @@ Node* JSGraph::EmptyFrameState() { common()->FrameState(JS_FRAME, BailoutId::None(), OutputFrameStateCombine::Ignore()), state_values, state_values, state_values, NoContextConstant(), - UndefinedConstant(), UndefinedConstant()); + UndefinedConstant(), graph()->start()); cached_nodes_[kEmptyFrameState] = empty_frame_state; } return empty_frame_state; diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc index 72f12fc7e0..6964e5eb4d 100644 --- a/src/compiler/js-inlining.cc +++ b/src/compiler/js-inlining.cc @@ -116,7 +116,8 @@ class CopyVisitor { }; -Reduction JSInliner::InlineCall(Node* call, Node* start, Node* end) { +Reduction JSInliner::InlineCall(Node* call, Node* frame_state, Node* start, + Node* end) { // The scheduler is smart enough to place our code; we just ensure {control} // becomes the control input of the start of the inlinee, and {effect} becomes // the effect input of the start of the inlinee. @@ -158,6 +159,8 @@ Reduction JSInliner::InlineCall(Node* call, Node* start, Node* end) { edge.UpdateTo(effect); } else if (NodeProperties::IsControlEdge(edge)) { edge.UpdateTo(control); + } else if (NodeProperties::IsFrameStateEdge(edge)) { + edge.UpdateTo(frame_state); } else { UNREACHABLE(); } @@ -284,7 +287,7 @@ Reduction JSInliner::Reduce(Node* node) { Node* start = visitor.GetCopy(graph.start()); Node* end = visitor.GetCopy(graph.end()); - Node* outer_frame_state = call.frame_state(); + Node* frame_state = call.frame_state(); size_t const inlinee_formal_parameters = start->op()->ValueOutputCount() - 3; // Insert argument adaptor frame if required. if (call.formal_arguments() != inlinee_formal_parameters) { @@ -294,22 +297,10 @@ Reduction JSInliner::Reduce(Node* node) { call.formal_arguments() < inlinee_formal_parameters) { return NoChange(); } - outer_frame_state = CreateArgumentsAdaptorFrameState(&call, info.zone()); + frame_state = CreateArgumentsAdaptorFrameState(&call, info.zone()); } - // Fix up all outer frame states from the inlinee. - for (Node* const node : visitor.copies()) { - if (node->opcode() == IrOpcode::kFrameState) { - DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); - // Don't touch this frame state, if it already has an "outer frame state". - if (NodeProperties::GetFrameStateInput(node, 0)->opcode() != - IrOpcode::kFrameState) { - NodeProperties::ReplaceFrameStateInput(node, 0, outer_frame_state); - } - } - } - - return InlineCall(node, start, end); + return InlineCall(node, frame_state, start, end); } } // namespace compiler diff --git a/src/compiler/js-inlining.h b/src/compiler/js-inlining.h index f7a0ba3a97..af82ed6638 100644 --- a/src/compiler/js-inlining.h +++ b/src/compiler/js-inlining.h @@ -37,7 +37,7 @@ class JSInliner final : public AdvancedReducer { Node* CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call, Zone* temp_zone); - Reduction InlineCall(Node* call, Node* start, Node* end); + Reduction InlineCall(Node* call, Node* frame_state, Node* start, Node* end); }; } // namespace compiler diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index da94390879..d2582038ad 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -118,9 +118,9 @@ void Verifier::Visitor::Check(Node* node) { for (int i = 0; i < frame_state_count; i++) { Node* frame_state = NodeProperties::GetFrameStateInput(node, i); CHECK(frame_state->opcode() == IrOpcode::kFrameState || - // kFrameState uses undefined as a sentinel. + // kFrameState uses Start as a sentinel. (node->opcode() == IrOpcode::kFrameState && - frame_state->opcode() == IrOpcode::kHeapConstant)); + frame_state->opcode() == IrOpcode::kStart)); CHECK(IsDefUseChainLinkPresent(frame_state, node)); CHECK(IsUseDefChainLinkPresent(frame_state, node)); } diff --git a/test/cctest/compiler/test-run-inlining.cc b/test/cctest/compiler/test-run-inlining.cc index 2ab7217227..3de929cbc8 100644 --- a/test/cctest/compiler/test-run-inlining.cc +++ b/test/cctest/compiler/test-run-inlining.cc @@ -78,6 +78,20 @@ TEST(SimpleInliningDeopt) { } +TEST(SimpleInliningDeoptSelf) { + FunctionTester T( + "(function(){" + " function foo(s) { %_DeoptimizeNow(); return s; };" + " function bar(s, t) { return foo(s); };" + " return bar;" + "})();", + kInlineFlags); + + InstallAssertInlineCountHelper(CcTest::isolate()); + T.CheckCall(T.Val(1), T.Val(1), T.Val(2)); +} + + TEST(SimpleInliningContext) { FunctionTester T( "(function () {"