Commit 7483dbd5 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Use Start as sentinel for frame states.

This simplifies inlining, in that we only need to update uses of Start
and inputs of End instead of walking the whole inlinee to update all
outer frame states.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/1146403008

Cr-Commit-Position: refs/heads/master@{#28649}
parent cc2d376f
......@@ -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) {
......
......@@ -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;
......
......@@ -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
......
......@@ -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
......
......@@ -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));
}
......
......@@ -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 () {"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment