| Index: src/compiler/js-inlining.cc
|
| diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc
|
| index 518a8746c07830b6da3a21c16bf4d5ffcbe16d5a..c2cdf5f6dd46cd0a011ebf98b70abffefaf7342f 100644
|
| --- a/src/compiler/js-inlining.cc
|
| +++ b/src/compiler/js-inlining.cc
|
| @@ -133,22 +133,23 @@ class CopyVisitor {
|
| };
|
|
|
|
|
| -Reduction JSInliner::InlineCall(Node* call, Node* context, Node* frame_state,
|
| - Node* start, Node* end) {
|
| +Reduction JSInliner::InlineCall(Node* call, Node* new_target, Node* context,
|
| + 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.
|
| Node* control = NodeProperties::GetControlInput(call);
|
| Node* effect = NodeProperties::GetEffectInput(call);
|
|
|
| + int const inlinee_new_target_index =
|
| + static_cast<int>(start->op()->ValueOutputCount()) - 3;
|
| int const inlinee_arity_index =
|
| static_cast<int>(start->op()->ValueOutputCount()) - 2;
|
| - // Context is last parameter.
|
| int const inlinee_context_index =
|
| static_cast<int>(start->op()->ValueOutputCount()) - 1;
|
|
|
| - // {inliner_inputs} counts JSFunction, Receiver, arguments, but not
|
| - // context, effect, control.
|
| + // {inliner_inputs} counts JSFunction, receiver, arguments, but not
|
| + // new target value, argument count, context, effect or control.
|
| int inliner_inputs = call->op()->ValueInputCount();
|
| // Iterate over all uses of the start node.
|
| for (Edge edge : start->use_edges()) {
|
| @@ -157,10 +158,13 @@ Reduction JSInliner::InlineCall(Node* call, Node* context, Node* frame_state,
|
| case IrOpcode::kParameter: {
|
| int index = 1 + ParameterIndexOf(use->op());
|
| DCHECK_LE(index, inlinee_context_index);
|
| - if (index < inliner_inputs && index < inlinee_arity_index) {
|
| + if (index < inliner_inputs && index < inlinee_new_target_index) {
|
| // There is an input from the call, and the index is a value
|
| // projection but not the context, so rewire the input.
|
| Replace(use, call->InputAt(index));
|
| + } else if (index == inlinee_new_target_index) {
|
| + // The projection is requesting the new target value.
|
| + Replace(use, new_target);
|
| } else if (index == inlinee_arity_index) {
|
| // The projection is requesting the number of arguments.
|
| Replace(use, jsgraph_->Int32Constant(inliner_inputs - 2));
|
| @@ -409,6 +413,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
|
| Node* start = visitor.GetCopy(graph.start());
|
| Node* end = visitor.GetCopy(graph.end());
|
| Node* frame_state = call.frame_state_after();
|
| + Node* new_target = jsgraph_->UndefinedConstant();
|
|
|
| // Insert nodes around the call that model the behavior required for a
|
| // constructor dispatch and turn the constructor call into a regular call.
|
| @@ -430,7 +435,8 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
|
| // Swizzle the inputs of the {JSCallConstruct} node to look like inputs to
|
| // any {JSCallFunction} node so that the rest of the inlining machinery
|
| // behaves as if we were dealing with a regular function invocation.
|
| - node->RemoveInput(call.formal_arguments() + 1); // Drop new.target.
|
| + new_target = call.new_target(); // Retrieve new target value input.
|
| + node->RemoveInput(call.formal_arguments() + 1); // Drop new target.
|
| node->InsertInput(jsgraph_->graph()->zone(), 1, create);
|
| // Insert a check of the return value to determine whether the return value
|
| // or the implicit receiver should be selected as a result of the call.
|
| @@ -474,16 +480,17 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
|
| }
|
|
|
| // Insert argument adaptor frame if required. The callees formal parameter
|
| - // count (i.e. value outputs of start node minus target, receiver, num args
|
| - // and context) have to match the number of arguments passed to the call.
|
| - DCHECK_EQ(parameter_count, start->op()->ValueOutputCount() - 4);
|
| + // count (i.e. value outputs of start node minus target, receiver, new target,
|
| + // arguments count and context) have to match the number of arguments passed
|
| + // to the call.
|
| + DCHECK_EQ(parameter_count, start->op()->ValueOutputCount() - 5);
|
| if (call.formal_arguments() != parameter_count) {
|
| frame_state = CreateArtificialFrameState(
|
| node, frame_state, call.formal_arguments(),
|
| FrameStateType::kArgumentsAdaptor, info.shared_info());
|
| }
|
|
|
| - return InlineCall(node, context, frame_state, start, end);
|
| + return InlineCall(node, new_target, context, frame_state, start, end);
|
| }
|
|
|
| } // namespace compiler
|
|
|