Chromium Code Reviews| Index: src/compiler/js-inlining.cc |
| diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc |
| index 2244f9bbfe9294651d70edc6870839f3979d1780..0184751f2d103c0a720234df44b4a2ae5805638f 100644 |
| --- a/src/compiler/js-inlining.cc |
| +++ b/src/compiler/js-inlining.cc |
| @@ -263,6 +263,35 @@ Node* JSInliner::CreateArtificialFrameState(Node* node, Node* outer_frame_state, |
| node->InputAt(0), outer_frame_state); |
| } |
| +Node* JSInliner::CreateTailCallerFrameState(Node* node, Node* frame_state) { |
| + FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state); |
| + Handle<SharedFunctionInfo> shared = |
| + frame_info.shared_info().ToHandleChecked(); |
| + |
| + Node* function = frame_state->InputAt(kFrameStateFunctionInput); |
| + |
| + // If we are inlining a tail call drop caller's frame state and an |
| + // arguments adaptor if it exists. |
| + frame_state = NodeProperties::GetFrameStateInput(frame_state, 0); |
| + if (frame_state->opcode() == IrOpcode::kFrameState) { |
| + FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
| + if (state_info.type() == FrameStateType::kArgumentsAdaptor) { |
| + frame_state = NodeProperties::GetFrameStateInput(frame_state, 0); |
| + } |
| + } |
| + |
| + const FrameStateFunctionInfo* state_info = |
| + jsgraph_->common()->CreateFrameStateFunctionInfo( |
| + FrameStateType::kTailCallerFunction, 0, 0, shared); |
| + |
| + const Operator* op = jsgraph_->common()->FrameState( |
| + BailoutId(-1), OutputFrameStateCombine::Ignore(), state_info); |
| + const Operator* op0 = jsgraph_->common()->StateValues(0); |
| + Node* node0 = jsgraph_->graph()->NewNode(op0); |
| + return jsgraph_->graph()->NewNode(op, node0, node0, node0, |
| + jsgraph_->UndefinedConstant(), function, |
| + frame_state); |
| +} |
| namespace { |
| @@ -491,6 +520,13 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
| // type feedback in the compiler. |
| Node* context = jsgraph_->Constant(handle(function->context())); |
| + if (node->opcode() == IrOpcode::kJSCallFunction) { |
|
Michael Starzinger
2016/03/08 16:25:08
This definitely needs a comment explaining the rea
Igor Sheludko
2016/03/08 18:03:40
Done. Please review the comment.
|
| + const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); |
| + if (p.tail_call_mode() == TailCallMode::kAllow) { |
| + frame_state = CreateTailCallerFrameState(node, frame_state); |
| + } |
| + } |
| + |
| // Insert a JSConvertReceiver node for sloppy callees. Note that the context |
| // passed into this node has to be the callees context (loaded above). Note |
| // that the frame state passed to the JSConvertReceiver must be the frame |