[maglev][arm64] Port CallWithSpread and CallWithArrayLike

Bug: v8:7700
Change-Id: I50a0a039409aafacca9f0d0c8ccd352adfa70631
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4111200
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84875}
This commit is contained in:
pthier 2022-12-15 15:17:14 +01:00 committed by V8 LUCI CQ
parent ef680d1b01
commit fbb72d259a
4 changed files with 105 additions and 96 deletions

View File

@ -115,8 +115,6 @@ UNIMPLEMENTED_NODE_WITH_CALL(Float64Ieee754Unary)
UNIMPLEMENTED_NODE_WITH_CALL(BuiltinStringFromCharCode)
UNIMPLEMENTED_NODE_WITH_CALL(CallBuiltin)
UNIMPLEMENTED_NODE_WITH_CALL(CallRuntime)
UNIMPLEMENTED_NODE_WITH_CALL(CallWithArrayLike)
UNIMPLEMENTED_NODE_WITH_CALL(CallWithSpread)
UNIMPLEMENTED_NODE_WITH_CALL(Construct)
UNIMPLEMENTED_NODE_WITH_CALL(ConstructWithSpread)
UNIMPLEMENTED_NODE_WITH_CALL(ConvertReceiver, mode_)

View File

@ -1654,6 +1654,100 @@ void CallKnownJSFunction::GenerateCode(MaglevAssembler* masm,
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
int CallWithSpread::MaxCallStackArgs() const {
int argc_no_spread = num_args() - 1;
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
return argc_no_spread + D::GetStackParameterCount();
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
return argc_no_spread + D::GetStackParameterCount();
}
}
void CallWithSpread::SetValueLocationConstraints() {
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
UseFixed(spread(), D::GetRegisterParameter(D::kSpread));
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
UseFixed(spread(), D::GetRegisterParameter(D::kSpread));
}
UseFixed(context(), kContextRegister);
for (int i = 0; i < num_args() - 1; i++) {
UseAny(arg(i));
}
DefineAsFixed(this, kReturnRegister0);
}
void CallWithSpread::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
#ifdef DEBUG
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget));
DCHECK_EQ(ToRegister(spread()), D::GetRegisterParameter(D::kSpread));
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget));
DCHECK_EQ(ToRegister(spread()), D::GetRegisterParameter(D::kSpread));
}
DCHECK_EQ(ToRegister(context()), kContextRegister);
#endif
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
static_assert(D::GetStackParameterIndex(D::kReceiver) == 0);
static_assert(D::GetStackParameterCount() == 1);
// Push the receiver twice, as we need it for CallCollectFeedback() and the
// actual call.
__ PushReverse(receiver(), base::make_iterator_range(args_no_spread_begin(),
args_no_spread_end()));
__ Move(D::GetRegisterParameter(D::kArgumentsCount), num_args_no_spread());
__ Move(D::GetRegisterParameter(D::kFeedbackVector), feedback().vector);
__ Move(D::GetRegisterParameter(D::kSlot), feedback().index());
__ CallBuiltin(Builtin::kCallWithSpread_WithFeedback);
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
__ PushReverse(base::make_iterator_range(args_no_spread_begin(),
args_no_spread_end()));
__ Move(D::GetRegisterParameter(D::kArgumentsCount), num_args_no_spread());
__ CallBuiltin(Builtin::kCallWithSpread);
}
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
int CallWithArrayLike::MaxCallStackArgs() const {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithArrayLike>::type;
return D::GetStackParameterCount();
}
void CallWithArrayLike::SetValueLocationConstraints() {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithArrayLike>::type;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
UseAny(receiver());
UseFixed(arguments_list(), D::GetRegisterParameter(D::kArgumentsList));
UseFixed(context(), kContextRegister);
DefineAsFixed(this, kReturnRegister0);
}
void CallWithArrayLike::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
#ifdef DEBUG
using D = CallInterfaceDescriptorFor<Builtin::kCallWithArrayLike>::type;
DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget));
DCHECK_EQ(ToRegister(arguments_list()),
D::GetRegisterParameter(D::kArgumentsList));
DCHECK_EQ(ToRegister(context()), kContextRegister);
#endif // DEBUG
__ Push(receiver());
__ CallBuiltin(Builtin::kCallWithArrayLike);
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
// ---
// Arch agnostic control nodes
// ---

View File

@ -5132,14 +5132,24 @@ class CallWithSpread : public ValueNodeT<CallWithSpread> {
Input& context() { return input(kContextIndex); }
const Input& context() const { return input(kContextIndex); }
int num_args() const { return input_count() - kFixedInputCount; }
int num_args_no_spread() const {
DCHECK_GT(num_args(), 0);
return num_args() - 1;
}
Input& arg(int i) { return input(i + kFixedInputCount); }
void set_arg(int i, ValueNode* node) {
set_input(i + kFixedInputCount, node);
}
auto args_no_spread_begin() { return std::make_reverse_iterator(&arg(-1)); }
auto args_no_spread_end() {
return std::make_reverse_iterator(&arg(num_args_no_spread() - 1));
}
Input& spread() {
// Spread is the last argument/input.
return input(input_count() - 1);
DCHECK_GT(num_args(), 0);
return arg(num_args() - 1);
}
Input& receiver() { return arg(0); }
compiler::FeedbackSource feedback() const { return feedback_; }
void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;

View File

@ -2808,99 +2808,6 @@ void CallRuntime::GenerateCode(MaglevAssembler* masm,
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
int CallWithSpread::MaxCallStackArgs() const {
int argc_no_spread = num_args() - 1;
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
return argc_no_spread + D::GetStackParameterCount();
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
return argc_no_spread + D::GetStackParameterCount();
}
}
void CallWithSpread::SetValueLocationConstraints() {
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
UseFixed(spread(), D::GetRegisterParameter(D::kSpread));
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
UseFixed(spread(), D::GetRegisterParameter(D::kSpread));
}
UseFixed(context(), kContextRegister);
for (int i = 0; i < num_args() - 1; i++) {
UseAny(arg(i));
}
DefineAsFixed(this, kReturnRegister0);
}
void CallWithSpread::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
#ifdef DEBUG
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget));
DCHECK_EQ(ToRegister(spread()), D::GetRegisterParameter(D::kSpread));
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget));
DCHECK_EQ(ToRegister(spread()), D::GetRegisterParameter(D::kSpread));
}
DCHECK_EQ(ToRegister(context()), kContextRegister);
#endif
// Push other arguments (other than the spread) to the stack.
int argc_no_spread = num_args() - 1;
for (int i = argc_no_spread - 1; i >= 0; --i) {
__ Push(arg(i));
}
if (feedback_.IsValid()) {
using D =
CallInterfaceDescriptorFor<Builtin::kCallWithSpread_WithFeedback>::type;
static_assert(D::GetStackParameterIndex(D::kReceiver) == 0);
static_assert(D::GetStackParameterCount() == 1);
__ Push(arg(0));
__ Move(D::GetRegisterParameter(D::kArgumentsCount), argc_no_spread);
__ Move(D::GetRegisterParameter(D::kFeedbackVector), feedback().vector);
__ Move(D::GetRegisterParameter(D::kSlot), feedback().index());
__ CallBuiltin(Builtin::kCallWithSpread_WithFeedback);
} else {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithSpread>::type;
__ Move(D::GetRegisterParameter(D::kArgumentsCount), argc_no_spread);
__ CallBuiltin(Builtin::kCallWithSpread);
}
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
int CallWithArrayLike::MaxCallStackArgs() const {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithArrayLike>::type;
return D::GetStackParameterCount();
}
void CallWithArrayLike::SetValueLocationConstraints() {
using D = CallInterfaceDescriptorFor<Builtin::kCallWithArrayLike>::type;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
UseAny(receiver());
UseFixed(arguments_list(), D::GetRegisterParameter(D::kArgumentsList));
UseFixed(context(), kContextRegister);
DefineAsFixed(this, kReturnRegister0);
}
void CallWithArrayLike::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
#ifdef DEBUG
using D = CallInterfaceDescriptorFor<Builtin::kCallWithArrayLike>::type;
DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget));
DCHECK_EQ(ToRegister(arguments_list()),
D::GetRegisterParameter(D::kArgumentsList));
DCHECK_EQ(ToRegister(context()), kContextRegister);
#endif // DEBUG
__ Push(receiver());
__ CallBuiltin(Builtin::kCallWithArrayLike);
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
int ConstructWithSpread::MaxCallStackArgs() const {
int argc_no_spread = num_args() - 1;
using D = CallInterfaceDescriptorFor<