Commit 458c07a7 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[compiler] Clarify ConstructParameters::arity()

... and CallParameters::arity().

The construct arity contains the actual argument count, plus 2 for the
target  (the first input) and new target (the last input). This CL adds
a named constant and a helper method for accessing arity without extra
args. In the future we may want to remove the extra args from arity()
altogether.

Call arity is similar but includes the target and receiver.

Bug: v8:10542,v8:8888
Change-Id: I850fa314f88c2bee9d4dcd87eac9295b2bf88281
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2208850
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67963}
parent d91e8d8f
...@@ -2210,10 +2210,7 @@ void BytecodeGraphBuilder::VisitGetTemplateObject() { ...@@ -2210,10 +2210,7 @@ void BytecodeGraphBuilder::VisitGetTemplateObject() {
Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters( Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
Node* callee, Node* receiver, interpreter::Register first_arg, Node* callee, Node* receiver, interpreter::Register first_arg,
int arg_count) { int arg_count) {
// The arity of the Call node -- includes the callee, receiver and function int arity = kTargetAndReceiver + arg_count;
// arguments.
int arity = 2 + arg_count;
Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity)); Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
all[0] = callee; all[0] = callee;
...@@ -2222,7 +2219,7 @@ Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters( ...@@ -2222,7 +2219,7 @@ Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
// The function arguments are in consecutive registers. // The function arguments are in consecutive registers.
int arg_base = first_arg.index(); int arg_base = first_arg.index();
for (int i = 0; i < arg_count; ++i) { for (int i = 0; i < arg_count; ++i) {
all[2 + i] = all[kTargetAndReceiver + i] =
environment()->LookupRegister(interpreter::Register(arg_base + i)); environment()->LookupRegister(interpreter::Register(arg_base + i));
} }
...@@ -2247,7 +2244,8 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, ...@@ -2247,7 +2244,8 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node, Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
first_arg, arg_count); first_arg, arg_count);
return ProcessCallArguments(call_op, call_args, 2 + arg_count); return ProcessCallArguments(call_op, call_args,
kTargetAndReceiver + arg_count);
} }
void BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode, void BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode,
...@@ -2318,8 +2316,8 @@ void BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) { ...@@ -2318,8 +2316,8 @@ void BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) {
: static_cast<int>(reg_count) - 1; : static_cast<int>(reg_count) - 1;
Node* const* call_args = Node* const* call_args =
ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count); ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count);
BuildCall(receiver_mode, call_args, static_cast<size_t>(2 + arg_count), BuildCall(receiver_mode, call_args,
slot_id); static_cast<size_t>(kTargetAndReceiver + arg_count), slot_id);
} }
void BytecodeGraphBuilder::VisitCallAnyReceiver() { void BytecodeGraphBuilder::VisitCallAnyReceiver() {
...@@ -2341,9 +2339,7 @@ void BytecodeGraphBuilder::VisitCallNoFeedback() { ...@@ -2341,9 +2339,7 @@ void BytecodeGraphBuilder::VisitCallNoFeedback() {
// The receiver is the first register, followed by the arguments in the // The receiver is the first register, followed by the arguments in the
// consecutive registers. // consecutive registers.
int arg_count = static_cast<int>(reg_count) - 1; int arg_count = static_cast<int>(reg_count) - 1;
// The arity of the Call node -- includes the callee, receiver and function int arity = kTargetAndReceiver + arg_count;
// arguments.
int arity = 2 + arg_count;
// Setting call frequency to a value less than min_inlining frequency to // Setting call frequency to a value less than min_inlining frequency to
// prevent inlining of one-shot call node. // prevent inlining of one-shot call node.
...@@ -2459,7 +2455,7 @@ void BytecodeGraphBuilder::VisitCallWithSpread() { ...@@ -2459,7 +2455,7 @@ void BytecodeGraphBuilder::VisitCallWithSpread() {
node = lowering.value(); node = lowering.value();
} else { } else {
DCHECK(!lowering.Changed()); DCHECK(!lowering.Changed());
node = ProcessCallArguments(op, args, 2 + arg_count); node = ProcessCallArguments(op, args, kTargetAndReceiver + arg_count);
} }
environment()->BindAccumulator(node, Environment::kAttachFrameState); environment()->BindAccumulator(node, Environment::kAttachFrameState);
} }
...@@ -2472,10 +2468,11 @@ void BytecodeGraphBuilder::VisitCallJSRuntime() { ...@@ -2472,10 +2468,11 @@ void BytecodeGraphBuilder::VisitCallJSRuntime() {
size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
int arg_count = static_cast<int>(reg_count); int arg_count = static_cast<int>(reg_count);
const Operator* call = javascript()->Call(2 + arg_count); const Operator* call = javascript()->Call(kTargetAndReceiver + arg_count);
Node* const* call_args = ProcessCallVarArgs( Node* const* call_args = ProcessCallVarArgs(
ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count); ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count);
Node* value = ProcessCallArguments(call, call_args, 2 + arg_count); Node* value =
ProcessCallArguments(call, call_args, kTargetAndReceiver + arg_count);
environment()->BindAccumulator(value, Environment::kAttachFrameState); environment()->BindAccumulator(value, Environment::kAttachFrameState);
} }
...@@ -2532,8 +2529,7 @@ void BytecodeGraphBuilder::VisitCallRuntimeForPair() { ...@@ -2532,8 +2529,7 @@ void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister( Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
Node* target, Node* new_target, interpreter::Register first_arg, Node* target, Node* new_target, interpreter::Register first_arg,
int arg_count) { int arg_count) {
// arity is args + callee and new target. int arity = kTargetAndNewTarget + arg_count;
int arity = arg_count + 2;
Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity)); Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
all[0] = target; all[0] = target;
int first_arg_index = first_arg.index(); int first_arg_index = first_arg.index();
...@@ -2563,9 +2559,10 @@ void BytecodeGraphBuilder::VisitConstruct() { ...@@ -2563,9 +2559,10 @@ void BytecodeGraphBuilder::VisitConstruct() {
Node* callee = environment()->LookupRegister(callee_reg); Node* callee = environment()->LookupRegister(callee_reg);
CallFrequency frequency = ComputeCallFrequency(slot_id); CallFrequency frequency = ComputeCallFrequency(slot_id);
const Operator* op = javascript()->Construct( const uint32_t arg_count = static_cast<uint32_t>(reg_count);
static_cast<uint32_t>(reg_count + 2), frequency, feedback); const uint32_t arg_count_with_extra_args = kTargetAndNewTarget + arg_count;
int arg_count = static_cast<int>(reg_count); const Operator* op =
javascript()->Construct(arg_count_with_extra_args, frequency, feedback);
Node* const* args = GetConstructArgumentsFromRegister(callee, new_target, Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
first_reg, arg_count); first_reg, arg_count);
JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct( JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
...@@ -2577,7 +2574,7 @@ void BytecodeGraphBuilder::VisitConstruct() { ...@@ -2577,7 +2574,7 @@ void BytecodeGraphBuilder::VisitConstruct() {
node = lowering.value(); node = lowering.value();
} else { } else {
DCHECK(!lowering.Changed()); DCHECK(!lowering.Changed());
node = ProcessConstructArguments(op, args, 2 + arg_count); node = ProcessConstructArguments(op, args, arg_count_with_extra_args);
} }
environment()->BindAccumulator(node, Environment::kAttachFrameState); environment()->BindAccumulator(node, Environment::kAttachFrameState);
} }
...@@ -2594,9 +2591,10 @@ void BytecodeGraphBuilder::VisitConstructWithSpread() { ...@@ -2594,9 +2591,10 @@ void BytecodeGraphBuilder::VisitConstructWithSpread() {
Node* callee = environment()->LookupRegister(callee_reg); Node* callee = environment()->LookupRegister(callee_reg);
CallFrequency frequency = ComputeCallFrequency(slot_id); CallFrequency frequency = ComputeCallFrequency(slot_id);
const uint32_t arg_count = static_cast<uint32_t>(reg_count);
const uint32_t arg_count_with_extra_args = kTargetAndNewTarget + arg_count;
const Operator* op = javascript()->ConstructWithSpread( const Operator* op = javascript()->ConstructWithSpread(
static_cast<uint32_t>(reg_count + 2), frequency, feedback); arg_count_with_extra_args, frequency, feedback);
int arg_count = static_cast<int>(reg_count);
Node* const* args = GetConstructArgumentsFromRegister(callee, new_target, Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
first_reg, arg_count); first_reg, arg_count);
JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct( JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
...@@ -2608,7 +2606,7 @@ void BytecodeGraphBuilder::VisitConstructWithSpread() { ...@@ -2608,7 +2606,7 @@ void BytecodeGraphBuilder::VisitConstructWithSpread() {
node = lowering.value(); node = lowering.value();
} else { } else {
DCHECK(!lowering.Changed()); DCHECK(!lowering.Changed());
node = ProcessConstructArguments(op, args, 2 + arg_count); node = ProcessConstructArguments(op, args, arg_count_with_extra_args);
} }
environment()->BindAccumulator(node, Environment::kAttachFrameState); environment()->BindAccumulator(node, Environment::kAttachFrameState);
} }
......
...@@ -793,11 +793,7 @@ class PromiseBuiltinReducerAssembler : public JSCallReducerAssembler { ...@@ -793,11 +793,7 @@ class PromiseBuiltinReducerAssembler : public JSCallReducerAssembler {
int ConstructArity() const { int ConstructArity() const {
DCHECK_EQ(IrOpcode::kJSConstruct, node_ptr()->opcode()); DCHECK_EQ(IrOpcode::kJSConstruct, node_ptr()->opcode());
ConstructParameters const& p = ConstructParametersOf(node_ptr()->op()); ConstructParameters const& p = ConstructParametersOf(node_ptr()->op());
static constexpr int kTarget = 1; // The first input. return p.arity_without_implicit_args();
static constexpr int kNewTarget = 1; // The last input.
static constexpr int kExtraArgs = kTarget + kNewTarget;
DCHECK_GE(p.arity(), kExtraArgs);
return static_cast<int>(p.arity() - kExtraArgs);
} }
TNode<Object> NewTargetInput() const { TNode<Object> NewTargetInput() const {
...@@ -846,7 +842,8 @@ class PromiseBuiltinReducerAssembler : public JSCallReducerAssembler { ...@@ -846,7 +842,8 @@ class PromiseBuiltinReducerAssembler : public JSCallReducerAssembler {
FeedbackSource no_feedback_source{}; FeedbackSource no_feedback_source{};
MayThrow(_ { MayThrow(_ {
return AddNode<Object>(graph()->NewNode( return AddNode<Object>(graph()->NewNode(
javascript()->Call(4, p.frequency(), no_feedback_source, javascript()->Call(2 + kTargetAndReceiver, p.frequency(),
no_feedback_source,
ConvertReceiverMode::kNullOrUndefined), ConvertReceiverMode::kNullOrUndefined),
executor, UndefinedConstant(), resolve, reject, ContextInput(), executor, UndefinedConstant(), resolve, reject, ContextInput(),
frame_state, effect(), control())); frame_state, effect(), control()));
...@@ -859,7 +856,8 @@ class PromiseBuiltinReducerAssembler : public JSCallReducerAssembler { ...@@ -859,7 +856,8 @@ class PromiseBuiltinReducerAssembler : public JSCallReducerAssembler {
FeedbackSource no_feedback_source{}; FeedbackSource no_feedback_source{};
MayThrow(_ { MayThrow(_ {
return AddNode<Object>(graph()->NewNode( return AddNode<Object>(graph()->NewNode(
javascript()->Call(3, p.frequency(), no_feedback_source, javascript()->Call(1 + kTargetAndReceiver, p.frequency(),
no_feedback_source,
ConvertReceiverMode::kNullOrUndefined), ConvertReceiverMode::kNullOrUndefined),
reject, UndefinedConstant(), exception, ContextInput(), frame_state, reject, UndefinedConstant(), exception, ContextInput(), frame_state,
effect(), control())); effect(), control()));
...@@ -1012,7 +1010,7 @@ TNode<Object> JSCallReducerAssembler::JSCall3( ...@@ -1012,7 +1010,7 @@ TNode<Object> JSCallReducerAssembler::JSCall3(
CallParameters const& p = CallParametersOf(node_ptr()->op()); CallParameters const& p = CallParametersOf(node_ptr()->op());
return MayThrow(_ { return MayThrow(_ {
return AddNode<Object>(graph()->NewNode( return AddNode<Object>(graph()->NewNode(
javascript()->Call(5, p.frequency(), p.feedback(), javascript()->Call(3 + kTargetAndReceiver, p.frequency(), p.feedback(),
ConvertReceiverMode::kAny, p.speculation_mode(), ConvertReceiverMode::kAny, p.speculation_mode(),
CallFeedbackRelation::kUnrelated), CallFeedbackRelation::kUnrelated),
function, this_arg, arg0, arg1, arg2, ContextInput(), frame_state, function, this_arg, arg0, arg1, arg2, ContextInput(), frame_state,
...@@ -1027,7 +1025,7 @@ TNode<Object> JSCallReducerAssembler::JSCall4( ...@@ -1027,7 +1025,7 @@ TNode<Object> JSCallReducerAssembler::JSCall4(
CallParameters const& p = CallParametersOf(node_ptr()->op()); CallParameters const& p = CallParametersOf(node_ptr()->op());
return MayThrow(_ { return MayThrow(_ {
return AddNode<Object>(graph()->NewNode( return AddNode<Object>(graph()->NewNode(
javascript()->Call(6, p.frequency(), p.feedback(), javascript()->Call(4 + kTargetAndReceiver, p.frequency(), p.feedback(),
ConvertReceiverMode::kAny, p.speculation_mode(), ConvertReceiverMode::kAny, p.speculation_mode(),
CallFeedbackRelation::kUnrelated), CallFeedbackRelation::kUnrelated),
function, this_arg, arg0, arg1, arg2, arg3, ContextInput(), frame_state, function, this_arg, arg0, arg1, arg2, arg3, ContextInput(), frame_state,
...@@ -2340,8 +2338,7 @@ Reduction JSCallReducer::ReduceArrayConstructor(Node* node) { ...@@ -2340,8 +2338,7 @@ Reduction JSCallReducer::ReduceArrayConstructor(Node* node) {
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
// Turn the {node} into a {JSCreateArray} call. // Turn the {node} into a {JSCreateArray} call.
DCHECK_LE(2u, p.arity()); size_t const arity = p.arity_without_implicit_args();
size_t const arity = p.arity() - 2;
NodeProperties::ReplaceValueInput(node, target, 0); NodeProperties::ReplaceValueInput(node, target, 0);
NodeProperties::ReplaceValueInput(node, target, 1); NodeProperties::ReplaceValueInput(node, target, 1);
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
...@@ -2355,9 +2352,9 @@ Reduction JSCallReducer::ReduceBooleanConstructor(Node* node) { ...@@ -2355,9 +2352,9 @@ Reduction JSCallReducer::ReduceBooleanConstructor(Node* node) {
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
// Replace the {node} with a proper {ToBoolean} operator. // Replace the {node} with a proper {ToBoolean} operator.
DCHECK_LE(2u, p.arity()); Node* value = (p.arity_without_implicit_args() == 0)
Node* value = (p.arity() == 2) ? jsgraph()->UndefinedConstant() ? jsgraph()->UndefinedConstant()
: NodeProperties::GetValueInput(node, 2); : NodeProperties::GetValueInput(node, 2);
value = graph()->NewNode(simplified()->ToBoolean(), value); value = graph()->NewNode(simplified()->ToBoolean(), value);
ReplaceWithValue(node, value); ReplaceWithValue(node, value);
return Replace(value); return Replace(value);
...@@ -2367,9 +2364,8 @@ Reduction JSCallReducer::ReduceBooleanConstructor(Node* node) { ...@@ -2367,9 +2364,8 @@ Reduction JSCallReducer::ReduceBooleanConstructor(Node* node) {
Reduction JSCallReducer::ReduceObjectConstructor(Node* node) { Reduction JSCallReducer::ReduceObjectConstructor(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
if (p.arity() < 3) return NoChange(); if (p.arity_without_implicit_args() < 1) return NoChange();
Node* value = (p.arity() >= 3) ? NodeProperties::GetValueInput(node, 2) Node* value = NodeProperties::GetValueInput(node, 2);
: jsgraph()->UndefinedConstant();
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
// We can fold away the Object(x) call if |x| is definitely not a primitive. // We can fold away the Object(x) call if |x| is definitely not a primitive.
...@@ -2394,15 +2390,14 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) { ...@@ -2394,15 +2390,14 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
size_t arity = p.arity(); size_t arity = p.arity_without_implicit_args();
DCHECK_LE(2u, arity);
ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny; ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny;
if (arity == 2) { if (arity == 0) {
// Neither thisArg nor argArray was provided. // Neither thisArg nor argArray was provided.
convert_mode = ConvertReceiverMode::kNullOrUndefined; convert_mode = ConvertReceiverMode::kNullOrUndefined;
node->ReplaceInput(0, node->InputAt(1)); node->ReplaceInput(0, node->InputAt(1));
node->ReplaceInput(1, jsgraph()->UndefinedConstant()); node->ReplaceInput(1, jsgraph()->UndefinedConstant());
} else if (arity == 3) { } else if (arity == 1) {
// The argArray was not provided, just remove the {target}. // The argArray was not provided, just remove the {target}.
node->RemoveInput(0); node->RemoveInput(0);
--arity; --arity;
...@@ -2423,7 +2418,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) { ...@@ -2423,7 +2418,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) {
node->ReplaceInput(0, target); node->ReplaceInput(0, target);
node->ReplaceInput(1, this_argument); node->ReplaceInput(1, this_argument);
node->ReplaceInput(2, arguments_list); node->ReplaceInput(2, arguments_list);
while (arity-- > 3) node->RemoveInput(3); while (arity-- > 1) node->RemoveInput(3);
// Morph the {node} to a {JSCallWithArrayLike}. // Morph the {node} to a {JSCallWithArrayLike}.
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
...@@ -2465,9 +2460,9 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) { ...@@ -2465,9 +2460,9 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) {
Node* effect1 = effect; Node* effect1 = effect;
Node* control1 = Node* control1 =
graph()->NewNode(common()->Merge(2), if_null, if_undefined); graph()->NewNode(common()->Merge(2), if_null, if_undefined);
Node* value1 = effect1 = control1 = Node* value1 = effect1 = control1 = graph()->NewNode(
graph()->NewNode(javascript()->Call(2), target, this_argument, javascript()->Call(0 + kTargetAndReceiver), target, this_argument,
context, frame_state, effect1, control1); context, frame_state, effect1, control1);
// Rewire potential exception edges. // Rewire potential exception edges.
Node* if_exception = nullptr; Node* if_exception = nullptr;
...@@ -2504,8 +2499,8 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) { ...@@ -2504,8 +2499,8 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) {
} }
// Change {node} to the new {JSCall} operator. // Change {node} to the new {JSCall} operator.
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(arity, p.frequency(), p.feedback(), convert_mode, node, javascript()->Call(arity + kTargetAndReceiver, p.frequency(),
p.speculation_mode(), p.feedback(), convert_mode, p.speculation_mode(),
CallFeedbackRelation::kUnrelated)); CallFeedbackRelation::kUnrelated));
// Try to further reduce the JSCall {node}. // Try to further reduce the JSCall {node}.
return Changed(node).FollowedBy(ReduceJSCall(node)); return Changed(node).FollowedBy(ReduceJSCall(node));
...@@ -2625,17 +2620,19 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) { ...@@ -2625,17 +2620,19 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) {
control, p.feedback()); control, p.feedback());
// Replace the {node} with a JSCreateBoundFunction. // Replace the {node} with a JSCreateBoundFunction.
int const arity = std::max(0, node->op()->ValueInputCount() - 3); static constexpr int kContextEffectAndControl = 3;
int const input_count = 2 + arity + 3; int const arity =
std::max(0, node->op()->ValueInputCount() - kContextEffectAndControl);
int const input_count = kTargetAndReceiver + arity + kContextEffectAndControl;
Node** inputs = graph()->zone()->NewArray<Node*>(input_count); Node** inputs = graph()->zone()->NewArray<Node*>(input_count);
inputs[0] = receiver; inputs[0] = receiver;
inputs[1] = bound_this; inputs[1] = bound_this;
for (int i = 0; i < arity; ++i) { for (int i = 0; i < arity; ++i) {
inputs[2 + i] = NodeProperties::GetValueInput(node, 3 + i); inputs[kTargetAndReceiver + i] = NodeProperties::GetValueInput(node, 3 + i);
} }
inputs[2 + arity + 0] = context; inputs[kTargetAndReceiver + arity + 0] = context;
inputs[2 + arity + 1] = effect; inputs[kTargetAndReceiver + arity + 1] = effect;
inputs[2 + arity + 2] = control; inputs[kTargetAndReceiver + arity + 2] = control;
Node* value = effect = Node* value = effect =
graph()->NewNode(javascript()->CreateBoundFunction(arity, map.object()), graph()->NewNode(javascript()->CreateBoundFunction(arity, map.object()),
input_count, inputs); input_count, inputs);
...@@ -2675,10 +2672,9 @@ Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) { ...@@ -2675,10 +2672,9 @@ Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) {
// Remove the target from {node} and use the receiver as target instead, and // Remove the target from {node} and use the receiver as target instead, and
// the thisArg becomes the new target. If thisArg was not provided, insert // the thisArg becomes the new target. If thisArg was not provided, insert
// undefined instead. // undefined instead.
size_t arity = p.arity(); size_t arity = p.arity_without_implicit_args();
DCHECK_LE(2u, arity);
ConvertReceiverMode convert_mode; ConvertReceiverMode convert_mode;
if (arity == 2) { if (arity == 0) {
// The thisArg was not provided, use undefined as receiver. // The thisArg was not provided, use undefined as receiver.
convert_mode = ConvertReceiverMode::kNullOrUndefined; convert_mode = ConvertReceiverMode::kNullOrUndefined;
node->ReplaceInput(0, node->InputAt(1)); node->ReplaceInput(0, node->InputAt(1));
...@@ -2690,8 +2686,8 @@ Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) { ...@@ -2690,8 +2686,8 @@ Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) {
--arity; --arity;
} }
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(arity, p.frequency(), p.feedback(), convert_mode, node, javascript()->Call(arity + kTargetAndReceiver, p.frequency(),
p.speculation_mode(), p.feedback(), convert_mode, p.speculation_mode(),
CallFeedbackRelation::kUnrelated)); CallFeedbackRelation::kUnrelated));
// Try to further reduce the JSCall {node}. // Try to further reduce the JSCall {node}.
return Changed(node).FollowedBy(ReduceJSCall(node)); return Changed(node).FollowedBy(ReduceJSCall(node));
...@@ -2780,7 +2776,7 @@ Reduction JSCallReducer::ReduceObjectGetPrototypeOf(Node* node) { ...@@ -2780,7 +2776,7 @@ Reduction JSCallReducer::ReduceObjectGetPrototypeOf(Node* node) {
Reduction JSCallReducer::ReduceObjectIs(Node* node) { Reduction JSCallReducer::ReduceObjectIs(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& params = CallParametersOf(node->op()); CallParameters const& params = CallParametersOf(node->op());
int const argc = static_cast<int>(params.arity() - 2); int const argc = params.arity_without_implicit_args();
Node* lhs = (argc >= 1) ? NodeProperties::GetValueInput(node, 2) Node* lhs = (argc >= 1) ? NodeProperties::GetValueInput(node, 2)
: jsgraph()->UndefinedConstant(); : jsgraph()->UndefinedConstant();
Node* rhs = (argc >= 2) ? NodeProperties::GetValueInput(node, 3) Node* rhs = (argc >= 2) ? NodeProperties::GetValueInput(node, 3)
...@@ -2801,7 +2797,7 @@ Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { ...@@ -2801,7 +2797,7 @@ Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) {
Reduction JSCallReducer::ReduceObjectPrototypeHasOwnProperty(Node* node) { Reduction JSCallReducer::ReduceObjectPrototypeHasOwnProperty(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& params = CallParametersOf(node->op()); CallParameters const& params = CallParametersOf(node->op());
int const argc = static_cast<int>(params.arity() - 2); int const argc = params.arity_without_implicit_args();
Node* receiver = NodeProperties::GetValueInput(node, 1); Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* name = (argc >= 1) ? NodeProperties::GetValueInput(node, 2) Node* name = (argc >= 1) ? NodeProperties::GetValueInput(node, 2)
: jsgraph()->UndefinedConstant(); : jsgraph()->UndefinedConstant();
...@@ -2911,8 +2907,7 @@ Reduction JSCallReducer::ReduceObjectPrototypeIsPrototypeOf(Node* node) { ...@@ -2911,8 +2907,7 @@ Reduction JSCallReducer::ReduceObjectPrototypeIsPrototypeOf(Node* node) {
Reduction JSCallReducer::ReduceReflectApply(Node* node) { Reduction JSCallReducer::ReduceReflectApply(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
DCHECK_LE(0, arity);
// Massage value inputs appropriately. // Massage value inputs appropriately.
node->RemoveInput(0); node->RemoveInput(0);
node->RemoveInput(0); node->RemoveInput(0);
...@@ -2933,8 +2928,7 @@ Reduction JSCallReducer::ReduceReflectApply(Node* node) { ...@@ -2933,8 +2928,7 @@ Reduction JSCallReducer::ReduceReflectApply(Node* node) {
Reduction JSCallReducer::ReduceReflectConstruct(Node* node) { Reduction JSCallReducer::ReduceReflectConstruct(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
DCHECK_LE(0, arity);
// Massage value inputs appropriately. // Massage value inputs appropriately.
node->RemoveInput(0); node->RemoveInput(0);
node->RemoveInput(0); node->RemoveInput(0);
...@@ -2988,7 +2982,7 @@ Reduction JSCallReducer::ReduceObjectCreate(Node* node) { ...@@ -2988,7 +2982,7 @@ Reduction JSCallReducer::ReduceObjectCreate(Node* node) {
Reduction JSCallReducer::ReduceReflectGet(Node* node) { Reduction JSCallReducer::ReduceReflectGet(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
if (arity != 2) return NoChange(); if (arity != 2) return NoChange();
Node* target = NodeProperties::GetValueInput(node, 2); Node* target = NodeProperties::GetValueInput(node, 2);
Node* key = NodeProperties::GetValueInput(node, 3); Node* key = NodeProperties::GetValueInput(node, 3);
...@@ -3063,8 +3057,7 @@ Reduction JSCallReducer::ReduceReflectGet(Node* node) { ...@@ -3063,8 +3057,7 @@ Reduction JSCallReducer::ReduceReflectGet(Node* node) {
Reduction JSCallReducer::ReduceReflectHas(Node* node) { Reduction JSCallReducer::ReduceReflectHas(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
DCHECK_LE(0, arity);
Node* target = (arity >= 1) ? NodeProperties::GetValueInput(node, 2) Node* target = (arity >= 1) ? NodeProperties::GetValueInput(node, 2)
: jsgraph()->UndefinedConstant(); : jsgraph()->UndefinedConstant();
Node* key = (arity >= 2) ? NodeProperties::GetValueInput(node, 3) Node* key = (arity >= 2) ? NodeProperties::GetValueInput(node, 3)
...@@ -3403,7 +3396,7 @@ Reduction JSCallReducer::ReduceCallApiFunction( ...@@ -3403,7 +3396,7 @@ Reduction JSCallReducer::ReduceCallApiFunction(
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int const argc = static_cast<int>(p.arity()) - 2; int const argc = p.arity_without_implicit_args();
Node* target = NodeProperties::GetValueInput(node, 0); Node* target = NodeProperties::GetValueInput(node, 0);
Node* global_proxy = Node* global_proxy =
jsgraph()->Constant(native_context().global_proxy_object()); jsgraph()->Constant(native_context().global_proxy_object());
...@@ -3681,14 +3674,14 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread( ...@@ -3681,14 +3674,14 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread(
case IrOpcode::kJSCallWithSpread: { case IrOpcode::kJSCallWithSpread: {
// Ignore uses as spread input to calls with spread. // Ignore uses as spread input to calls with spread.
CallParameters p = CallParametersOf(user->op()); CallParameters p = CallParametersOf(user->op());
int const arity = static_cast<int>(p.arity() - 1); int const arity = p.arity_without_implicit_args();
if (user->InputAt(arity) == arguments_list) continue; if (user->InputAt(arity + 1) == arguments_list) continue;
break; break;
} }
case IrOpcode::kJSConstructWithSpread: { case IrOpcode::kJSConstructWithSpread: {
// Ignore uses as spread input to construct with spread. // Ignore uses as spread input to construct with spread.
ConstructParameters p = ConstructParametersOf(user->op()); ConstructParameters p = ConstructParametersOf(user->op());
int const arity = static_cast<int>(p.arity() - 2); int const arity = p.arity_without_implicit_args();
if (user->InputAt(arity) == arguments_list) continue; if (user->InputAt(arity) == arguments_list) continue;
break; break;
} }
...@@ -3779,7 +3772,8 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread( ...@@ -3779,7 +3772,8 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread(
return Changed(node).FollowedBy(ReduceJSCall(node)); return Changed(node).FollowedBy(ReduceJSCall(node));
} else { } else {
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Construct(arity + 2, frequency, feedback)); node, javascript()->Construct(arity + kTargetAndNewTarget, frequency,
feedback));
Node* new_target = NodeProperties::GetValueInput(node, arity + 1); Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
Node* frame_state = NodeProperties::GetFrameStateInput(node); Node* frame_state = NodeProperties::GetFrameStateInput(node);
Node* context = NodeProperties::GetContextInput(node); Node* context = NodeProperties::GetContextInput(node);
...@@ -3879,8 +3873,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -3879,8 +3873,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
Node* target = NodeProperties::GetValueInput(node, 0); Node* target = NodeProperties::GetValueInput(node, 0);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
size_t arity = p.arity(); size_t arity = p.arity_without_implicit_args();
DCHECK_LE(2u, arity);
// Try to specialize JSCall {node}s with constant {target}s. // Try to specialize JSCall {node}s with constant {target}s.
HeapObjectMatcher m(target); HeapObjectMatcher m(target);
...@@ -3927,9 +3920,10 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -3927,9 +3920,10 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
} }
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(arity, p.frequency(), p.feedback(), node,
convert_mode, p.speculation_mode(), javascript()->Call(arity + kTargetAndReceiver, p.frequency(),
CallFeedbackRelation::kUnrelated)); p.feedback(), convert_mode, p.speculation_mode(),
CallFeedbackRelation::kUnrelated));
// Try to further reduce the JSCall {node}. // Try to further reduce the JSCall {node}.
return Changed(node).FollowedBy(ReduceJSCall(node)); return Changed(node).FollowedBy(ReduceJSCall(node));
...@@ -3980,9 +3974,10 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -3980,9 +3974,10 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
? ConvertReceiverMode::kAny ? ConvertReceiverMode::kAny
: ConvertReceiverMode::kNotNullOrUndefined; : ConvertReceiverMode::kNotNullOrUndefined;
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(arity, p.frequency(), p.feedback(), node,
convert_mode, p.speculation_mode(), javascript()->Call(arity + kTargetAndReceiver, p.frequency(),
CallFeedbackRelation::kUnrelated)); p.feedback(), convert_mode, p.speculation_mode(),
CallFeedbackRelation::kUnrelated));
// Try to further reduce the JSCall {node}. // Try to further reduce the JSCall {node}.
return Changed(node).FollowedBy(ReduceJSCall(node)); return Changed(node).FollowedBy(ReduceJSCall(node));
...@@ -4420,30 +4415,29 @@ Reduction JSCallReducer::ReduceJSCall(Node* node, ...@@ -4420,30 +4415,29 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
Reduction JSCallReducer::ReduceJSCallWithArrayLike(Node* node) { Reduction JSCallReducer::ReduceJSCallWithArrayLike(Node* node) {
DCHECK_EQ(IrOpcode::kJSCallWithArrayLike, node->opcode()); DCHECK_EQ(IrOpcode::kJSCallWithArrayLike, node->opcode());
const CallParameters& p = CallParametersOf(node->op()); const CallParameters& p = CallParametersOf(node->op());
int arity = static_cast<int>(p.arity()); int arity = p.arity_without_implicit_args();
DCHECK_EQ(arity, 2); DCHECK_EQ(arity, 0);
return ReduceCallOrConstructWithArrayLikeOrSpread( return ReduceCallOrConstructWithArrayLikeOrSpread(
node, arity, p.frequency(), p.feedback(), p.speculation_mode(), node, arity + kTargetAndReceiver, p.frequency(), p.feedback(),
p.feedback_relation()); p.speculation_mode(), p.feedback_relation());
} }
Reduction JSCallReducer::ReduceJSCallWithSpread(Node* node) { Reduction JSCallReducer::ReduceJSCallWithSpread(Node* node) {
DCHECK_EQ(IrOpcode::kJSCallWithSpread, node->opcode()); DCHECK_EQ(IrOpcode::kJSCallWithSpread, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
DCHECK_LE(3u, p.arity()); int arity = p.arity_without_implicit_args();
int arity = static_cast<int>(p.arity() - 1); DCHECK_GE(p.arity(), 1);
CallFrequency frequency = p.frequency(); CallFrequency frequency = p.frequency();
FeedbackSource feedback = p.feedback(); FeedbackSource feedback = p.feedback();
return ReduceCallOrConstructWithArrayLikeOrSpread( return ReduceCallOrConstructWithArrayLikeOrSpread(
node, arity, frequency, feedback, p.speculation_mode(), node, arity + kTargetAndReceiver - 1, frequency, feedback,
p.feedback_relation()); p.speculation_mode(), p.feedback_relation());
} }
Reduction JSCallReducer::ReduceJSConstruct(Node* node) { Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode()); DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode());
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
DCHECK_LE(2u, p.arity()); int arity = p.arity_without_implicit_args();
int arity = static_cast<int>(p.arity() - 2);
Node* target = NodeProperties::GetValueInput(node, 0); Node* target = NodeProperties::GetValueInput(node, 0);
Node* new_target = NodeProperties::GetValueInput(node, arity + 1); Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
...@@ -4619,8 +4613,8 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -4619,8 +4613,8 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
// Update the JSConstruct operator on {node}. // Update the JSConstruct operator on {node}.
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, node, javascript()->Construct(arity + kTargetAndNewTarget,
javascript()->Construct(arity + 2, p.frequency(), FeedbackSource())); p.frequency(), FeedbackSource()));
// Try to further reduce the JSConstruct {node}. // Try to further reduce the JSConstruct {node}.
return Changed(node).FollowedBy(ReduceJSConstruct(node)); return Changed(node).FollowedBy(ReduceJSConstruct(node));
...@@ -4659,8 +4653,8 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -4659,8 +4653,8 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
// Update the JSConstruct operator on {node}. // Update the JSConstruct operator on {node}.
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, node, javascript()->Construct(arity + kTargetAndNewTarget,
javascript()->Construct(arity + 2, p.frequency(), FeedbackSource())); p.frequency(), FeedbackSource()));
// Try to further reduce the JSConstruct {node}. // Try to further reduce the JSConstruct {node}.
return Changed(node).FollowedBy(ReduceJSConstruct(node)); return Changed(node).FollowedBy(ReduceJSConstruct(node));
...@@ -4840,7 +4834,7 @@ Reduction JSCallReducer::ReduceStringPrototypeSubstr(Node* node) { ...@@ -4840,7 +4834,7 @@ Reduction JSCallReducer::ReduceStringPrototypeSubstr(Node* node) {
Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) { Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) {
DCHECK_EQ(IrOpcode::kJSConstructWithArrayLike, node->opcode()); DCHECK_EQ(IrOpcode::kJSConstructWithArrayLike, node->opcode());
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
const int arity = static_cast<int>(p.arity() - 2); const int arity = p.arity_without_implicit_args();
DCHECK_EQ(arity, 1); DCHECK_EQ(arity, 1);
return ReduceCallOrConstructWithArrayLikeOrSpread( return ReduceCallOrConstructWithArrayLikeOrSpread(
node, arity, p.frequency(), p.feedback(), node, arity, p.frequency(), p.feedback(),
...@@ -4850,8 +4844,8 @@ Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) { ...@@ -4850,8 +4844,8 @@ Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) {
Reduction JSCallReducer::ReduceJSConstructWithSpread(Node* node) { Reduction JSCallReducer::ReduceJSConstructWithSpread(Node* node) {
DCHECK_EQ(IrOpcode::kJSConstructWithSpread, node->opcode()); DCHECK_EQ(IrOpcode::kJSConstructWithSpread, node->opcode());
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
DCHECK_LE(3u, p.arity()); int arity = p.arity_without_implicit_args();
int arity = static_cast<int>(p.arity() - 2); DCHECK_LE(1u, arity);
CallFrequency frequency = p.frequency(); CallFrequency frequency = p.frequency();
FeedbackSource feedback = p.feedback(); FeedbackSource feedback = p.feedback();
return ReduceCallOrConstructWithArrayLikeOrSpread( return ReduceCallOrConstructWithArrayLikeOrSpread(
...@@ -6267,7 +6261,7 @@ Reduction JSCallReducer::ReducePromisePrototypeCatch(Node* node) { ...@@ -6267,7 +6261,7 @@ Reduction JSCallReducer::ReducePromisePrototypeCatch(Node* node) {
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) { if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
return NoChange(); return NoChange();
} }
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
Node* receiver = NodeProperties::GetValueInput(node, 1); Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
...@@ -6291,10 +6285,10 @@ Reduction JSCallReducer::ReducePromisePrototypeCatch(Node* node) { ...@@ -6291,10 +6285,10 @@ Reduction JSCallReducer::ReducePromisePrototypeCatch(Node* node) {
node->InsertInput(graph()->zone(), 2, jsgraph()->UndefinedConstant()); node->InsertInput(graph()->zone(), 2, jsgraph()->UndefinedConstant());
} }
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(2 + arity, p.frequency(), p.feedback(), node, javascript()->Call(
ConvertReceiverMode::kNotNullOrUndefined, arity + kTargetAndReceiver, p.frequency(), p.feedback(),
p.speculation_mode(), ConvertReceiverMode::kNotNullOrUndefined, p.speculation_mode(),
CallFeedbackRelation::kUnrelated)); CallFeedbackRelation::kUnrelated));
return Changed(node).FollowedBy(ReducePromisePrototypeThen(node)); return Changed(node).FollowedBy(ReducePromisePrototypeThen(node));
} }
...@@ -6315,7 +6309,7 @@ Reduction JSCallReducer::ReducePromisePrototypeFinally(Node* node) { ...@@ -6315,7 +6309,7 @@ Reduction JSCallReducer::ReducePromisePrototypeFinally(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
Node* receiver = NodeProperties::GetValueInput(node, 1); Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* on_finally = arity >= 1 ? NodeProperties::GetValueInput(node, 2) Node* on_finally = arity >= 1 ? NodeProperties::GetValueInput(node, 2)
: jsgraph()->UndefinedConstant(); : jsgraph()->UndefinedConstant();
...@@ -6420,10 +6414,10 @@ Reduction JSCallReducer::ReducePromisePrototypeFinally(Node* node) { ...@@ -6420,10 +6414,10 @@ Reduction JSCallReducer::ReducePromisePrototypeFinally(Node* node) {
node->ReplaceInput(2, then_finally); node->ReplaceInput(2, then_finally);
node->ReplaceInput(3, catch_finally); node->ReplaceInput(3, catch_finally);
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(2 + arity, p.frequency(), p.feedback(), node, javascript()->Call(
ConvertReceiverMode::kNotNullOrUndefined, arity + kTargetAndReceiver, p.frequency(), p.feedback(),
p.speculation_mode(), ConvertReceiverMode::kNotNullOrUndefined, p.speculation_mode(),
CallFeedbackRelation::kUnrelated)); CallFeedbackRelation::kUnrelated));
return Changed(node).FollowedBy(ReducePromisePrototypeThen(node)); return Changed(node).FollowedBy(ReducePromisePrototypeThen(node));
} }
...@@ -6531,7 +6525,7 @@ Reduction JSCallReducer::ReduceTypedArrayConstructor( ...@@ -6531,7 +6525,7 @@ Reduction JSCallReducer::ReduceTypedArrayConstructor(
Node* node, const SharedFunctionInfoRef& shared) { Node* node, const SharedFunctionInfoRef& shared) {
DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode()); DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode());
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
Node* target = NodeProperties::GetValueInput(node, 0); Node* target = NodeProperties::GetValueInput(node, 0);
Node* arg1 = (arity >= 1) ? NodeProperties::GetValueInput(node, 1) Node* arg1 = (arity >= 1) ? NodeProperties::GetValueInput(node, 1)
: jsgraph()->UndefinedConstant(); : jsgraph()->UndefinedConstant();
......
...@@ -722,9 +722,7 @@ void JSGenericLowering::LowerJSConstructForwardVarargs(Node* node) { ...@@ -722,9 +722,7 @@ void JSGenericLowering::LowerJSConstructForwardVarargs(Node* node) {
void JSGenericLowering::LowerJSConstruct(Node* node) { void JSGenericLowering::LowerJSConstruct(Node* node) {
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
// TODO(jgruber): Document or refactor the magic `- 2` (target and int const arg_count = p.arity_without_implicit_args();
// new_target) here and elsewhere.
int const arg_count = static_cast<int>(p.arity() - 2);
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
// TODO(jgruber): Understand and document how stack_argument_count is // TODO(jgruber): Understand and document how stack_argument_count is
...@@ -780,7 +778,7 @@ void JSGenericLowering::LowerJSConstruct(Node* node) { ...@@ -780,7 +778,7 @@ void JSGenericLowering::LowerJSConstruct(Node* node) {
void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) { void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) {
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
const int arg_count = static_cast<int>(p.arity() - 2); const int arg_count = p.arity_without_implicit_args();
DCHECK_EQ(arg_count, 1); DCHECK_EQ(arg_count, 1);
static constexpr int kReceiver = 1; static constexpr int kReceiver = 1;
...@@ -834,7 +832,7 @@ void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) { ...@@ -834,7 +832,7 @@ void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) {
void JSGenericLowering::LowerJSConstructWithSpread(Node* node) { void JSGenericLowering::LowerJSConstructWithSpread(Node* node) {
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
int const arg_count = static_cast<int>(p.arity() - 2); int const arg_count = p.arity_without_implicit_args();
int const spread_index = arg_count; int const spread_index = arg_count;
int const new_target_index = arg_count + 1; int const new_target_index = arg_count + 1;
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
...@@ -916,7 +914,7 @@ void JSGenericLowering::LowerJSCallForwardVarargs(Node* node) { ...@@ -916,7 +914,7 @@ void JSGenericLowering::LowerJSCallForwardVarargs(Node* node) {
void JSGenericLowering::LowerJSCall(Node* node) { void JSGenericLowering::LowerJSCall(Node* node) {
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int const arg_count = static_cast<int>(p.arity() - 2); int const arg_count = p.arity_without_implicit_args();
ConvertReceiverMode const mode = p.convert_mode(); ConvertReceiverMode const mode = p.convert_mode();
if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) { if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) {
...@@ -948,7 +946,7 @@ void JSGenericLowering::LowerJSCall(Node* node) { ...@@ -948,7 +946,7 @@ void JSGenericLowering::LowerJSCall(Node* node) {
void JSGenericLowering::LowerJSCallWithArrayLike(Node* node) { void JSGenericLowering::LowerJSCallWithArrayLike(Node* node) {
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
const int arg_count = static_cast<int>(p.arity() - 2); const int arg_count = p.arity_without_implicit_args();
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
DCHECK_EQ(arg_count, 0); DCHECK_EQ(arg_count, 0);
...@@ -986,7 +984,7 @@ void JSGenericLowering::LowerJSCallWithArrayLike(Node* node) { ...@@ -986,7 +984,7 @@ void JSGenericLowering::LowerJSCallWithArrayLike(Node* node) {
void JSGenericLowering::LowerJSCallWithSpread(Node* node) { void JSGenericLowering::LowerJSCallWithSpread(Node* node) {
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int const arg_count = static_cast<int>(p.arity() - 2); int const arg_count = p.arity_without_implicit_args();
int const spread_index = arg_count + 1; int const spread_index = arg_count + 1;
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
......
...@@ -488,7 +488,8 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) { ...@@ -488,7 +488,8 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
node->ReplaceInput(4, continuation_frame_state); node->ReplaceInput(4, continuation_frame_state);
node->ReplaceInput(5, effect); node->ReplaceInput(5, effect);
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(3, CallFrequency(), FeedbackSource(), node, javascript()->Call(1 + kTargetAndReceiver, CallFrequency(),
FeedbackSource(),
ConvertReceiverMode::kNotNullOrUndefined)); ConvertReceiverMode::kNotNullOrUndefined));
// Rewire the value uses of {node} to ToBoolean conversion of the result. // Rewire the value uses of {node} to ToBoolean conversion of the result.
...@@ -1428,10 +1429,10 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) { ...@@ -1428,10 +1429,10 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) {
SpeculationMode mode = feedback.IsInsufficient() SpeculationMode mode = feedback.IsInsufficient()
? SpeculationMode::kDisallowSpeculation ? SpeculationMode::kDisallowSpeculation
: feedback.AsCall().speculation_mode(); : feedback.AsCall().speculation_mode();
const Operator* call_op = const Operator* call_op = javascript()->Call(
javascript()->Call(2, CallFrequency(), p.callFeedback(), 0 + kTargetAndReceiver, CallFrequency(), p.callFeedback(),
ConvertReceiverMode::kNotNullOrUndefined, mode, ConvertReceiverMode::kNotNullOrUndefined, mode,
CallFeedbackRelation::kRelated); CallFeedbackRelation::kRelated);
Node* call_property = graph()->NewNode(call_op, load_property, receiver, Node* call_property = graph()->NewNode(call_op, load_property, receiver,
context, frame_state, effect, control); context, frame_state, effect, control);
...@@ -2048,7 +2049,8 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall( ...@@ -2048,7 +2049,8 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
Node* value; Node* value;
if (constant.IsJSFunction()) { if (constant.IsJSFunction()) {
value = *effect = *control = graph()->NewNode( value = *effect = *control = graph()->NewNode(
jsgraph()->javascript()->Call(2, CallFrequency(), FeedbackSource(), jsgraph()->javascript()->Call(0 + kTargetAndReceiver, CallFrequency(),
FeedbackSource(),
ConvertReceiverMode::kNotNullOrUndefined), ConvertReceiverMode::kNotNullOrUndefined),
target, receiver, context, frame_state, *effect, *control); target, receiver, context, frame_state, *effect, *control);
} else { } else {
...@@ -2085,7 +2087,8 @@ void JSNativeContextSpecialization::InlinePropertySetterCall( ...@@ -2085,7 +2087,8 @@ void JSNativeContextSpecialization::InlinePropertySetterCall(
// Introduce the call to the setter function. // Introduce the call to the setter function.
if (constant.IsJSFunction()) { if (constant.IsJSFunction()) {
*effect = *control = graph()->NewNode( *effect = *control = graph()->NewNode(
jsgraph()->javascript()->Call(3, CallFrequency(), FeedbackSource(), jsgraph()->javascript()->Call(1 + kTargetAndReceiver, CallFrequency(),
FeedbackSource(),
ConvertReceiverMode::kNotNullOrUndefined), ConvertReceiverMode::kNotNullOrUndefined),
target, receiver, value, context, frame_state, *effect, *control); target, receiver, value, context, frame_state, *effect, *control);
} else { } else {
......
...@@ -95,16 +95,32 @@ std::ostream& operator<<(std::ostream&, ...@@ -95,16 +95,32 @@ std::ostream& operator<<(std::ostream&,
ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf( ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf(
Operator const*) V8_WARN_UNUSED_RESULT; Operator const*) V8_WARN_UNUSED_RESULT;
// Defines the arity and the feedback for a JavaScript constructor call. This is // Part of ConstructParameters::arity.
// used as a parameter by JSConstruct, JSConstructWithArrayLike, and static constexpr int kTargetAndNewTarget = 2;
// JSConstructWithSpread operators.
// Defines the arity (parameters plus the target and new target) and the
// feedback for a JavaScript constructor call. This is used as a parameter by
// JSConstruct, JSConstructWithArrayLike, and JSConstructWithSpread operators.
class ConstructParameters final { class ConstructParameters final {
public: public:
ConstructParameters(uint32_t arity, CallFrequency const& frequency, ConstructParameters(uint32_t arity, CallFrequency const& frequency,
FeedbackSource const& feedback) FeedbackSource const& feedback)
: arity_(arity), frequency_(frequency), feedback_(feedback) {} : arity_(arity), frequency_(frequency), feedback_(feedback) {
DCHECK_GE(arity, kTargetAndNewTarget);
DCHECK(is_int32(arity));
}
// TODO(jgruber): Consider removing `arity()` and just storing the arity
// without extra args in ConstructParameters. Every spot that creates
// ConstructParameters artifically adds the extra args. Every spot that uses
// ConstructParameters artificially subtracts the extra args.
// We keep them for now for consistency with other spots
// that expect `arity()` to include extra args.
uint32_t arity() const { return arity_; } uint32_t arity() const { return arity_; }
int arity_without_implicit_args() const {
return static_cast<int>(arity_ - kTargetAndNewTarget);
}
CallFrequency const& frequency() const { return frequency_; } CallFrequency const& frequency() const { return frequency_; }
FeedbackSource const& feedback() const { return feedback_; } FeedbackSource const& feedback() const { return feedback_; }
...@@ -157,8 +173,12 @@ std::ostream& operator<<(std::ostream&, CallForwardVarargsParameters const&); ...@@ -157,8 +173,12 @@ std::ostream& operator<<(std::ostream&, CallForwardVarargsParameters const&);
CallForwardVarargsParameters const& CallForwardVarargsParametersOf( CallForwardVarargsParameters const& CallForwardVarargsParametersOf(
Operator const*) V8_WARN_UNUSED_RESULT; Operator const*) V8_WARN_UNUSED_RESULT;
// Defines the arity and the call flags for a JavaScript function call. This is // Part of CallParameters::arity.
// used as a parameter by JSCall and JSCallWithSpread operators. static constexpr int kTargetAndReceiver = 2;
// Defines the arity (parameters plus the target and receiver) and the call
// flags for a JavaScript function call. This is used as a parameter by JSCall,
// JSCallWithArrayLike and JSCallWithSpread operators.
class CallParameters final { class CallParameters final {
public: public:
CallParameters(size_t arity, CallFrequency const& frequency, CallParameters(size_t arity, CallFrequency const& frequency,
...@@ -177,9 +197,17 @@ class CallParameters final { ...@@ -177,9 +197,17 @@ class CallParameters final {
feedback.IsValid()); feedback.IsValid());
DCHECK_IMPLIES(!feedback.IsValid(), DCHECK_IMPLIES(!feedback.IsValid(),
feedback_relation == CallFeedbackRelation::kUnrelated); feedback_relation == CallFeedbackRelation::kUnrelated);
DCHECK_GE(arity, kTargetAndReceiver);
DCHECK(is_int32(arity));
} }
// TODO(jgruber): Consider removing `arity()` and just storing the arity
// without extra args in CallParameters.
size_t arity() const { return ArityField::decode(bit_field_); } size_t arity() const { return ArityField::decode(bit_field_); }
int arity_without_implicit_args() const {
return static_cast<int>(arity() - kTargetAndReceiver);
}
CallFrequency const& frequency() const { return frequency_; } CallFrequency const& frequency() const { return frequency_; }
ConvertReceiverMode convert_mode() const { ConvertReceiverMode convert_mode() const {
return ConvertReceiverModeField::decode(bit_field_); return ConvertReceiverModeField::decode(bit_field_);
......
...@@ -1577,8 +1577,7 @@ Reduction JSTypedLowering::ReduceJSConstructForwardVarargs(Node* node) { ...@@ -1577,8 +1577,7 @@ Reduction JSTypedLowering::ReduceJSConstructForwardVarargs(Node* node) {
Reduction JSTypedLowering::ReduceJSConstruct(Node* node) { Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode()); DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode());
ConstructParameters const& p = ConstructParametersOf(node->op()); ConstructParameters const& p = ConstructParametersOf(node->op());
DCHECK_LE(2u, p.arity()); int const arity = p.arity_without_implicit_args();
int const arity = static_cast<int>(p.arity() - 2);
Node* target = NodeProperties::GetValueInput(node, 0); Node* target = NodeProperties::GetValueInput(node, 0);
Type target_type = NodeProperties::GetType(target); Type target_type = NodeProperties::GetType(target);
Node* new_target = NodeProperties::GetValueInput(node, arity + 1); Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
...@@ -1649,7 +1648,7 @@ Reduction JSTypedLowering::ReduceJSCallForwardVarargs(Node* node) { ...@@ -1649,7 +1648,7 @@ Reduction JSTypedLowering::ReduceJSCallForwardVarargs(Node* node) {
Reduction JSTypedLowering::ReduceJSCall(Node* node) { Reduction JSTypedLowering::ReduceJSCall(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int arity = static_cast<int>(p.arity() - 2); int arity = p.arity_without_implicit_args();
ConvertReceiverMode convert_mode = p.convert_mode(); ConvertReceiverMode convert_mode = p.convert_mode();
Node* target = NodeProperties::GetValueInput(node, 0); Node* target = NodeProperties::GetValueInput(node, 0);
Type target_type = NodeProperties::GetType(target); Type target_type = NodeProperties::GetType(target);
......
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