[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:
parent
ef680d1b01
commit
fbb72d259a
@ -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_)
|
||||
|
@ -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
|
||||
// ---
|
||||
|
@ -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;
|
||||
|
@ -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<
|
||||
|
Loading…
Reference in New Issue
Block a user