From fbb72d259aef63af9d255e759d6d6c501a745974 Mon Sep 17 00:00:00 2001 From: pthier Date: Thu, 15 Dec 2022 15:17:14 +0100 Subject: [PATCH] [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 Commit-Queue: Patrick Thier Cr-Commit-Position: refs/heads/main@{#84875} --- src/maglev/arm64/maglev-ir-arm64.cc | 2 - src/maglev/maglev-ir.cc | 94 +++++++++++++++++++++++++++++ src/maglev/maglev-ir.h | 12 +++- src/maglev/x64/maglev-ir-x64.cc | 93 ---------------------------- 4 files changed, 105 insertions(+), 96 deletions(-) diff --git a/src/maglev/arm64/maglev-ir-arm64.cc b/src/maglev/arm64/maglev-ir-arm64.cc index 0f25a96af2..ffcfd50bce 100644 --- a/src/maglev/arm64/maglev-ir-arm64.cc +++ b/src/maglev/arm64/maglev-ir-arm64.cc @@ -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_) diff --git a/src/maglev/maglev-ir.cc b/src/maglev/maglev-ir.cc index 8874280e75..da78be4892 100644 --- a/src/maglev/maglev-ir.cc +++ b/src/maglev/maglev-ir.cc @@ -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::type; + return argc_no_spread + D::GetStackParameterCount(); + } else { + using D = CallInterfaceDescriptorFor::type; + return argc_no_spread + D::GetStackParameterCount(); + } +} +void CallWithSpread::SetValueLocationConstraints() { + if (feedback_.IsValid()) { + using D = + CallInterfaceDescriptorFor::type; + UseFixed(function(), D::GetRegisterParameter(D::kTarget)); + UseFixed(spread(), D::GetRegisterParameter(D::kSpread)); + } else { + using D = CallInterfaceDescriptorFor::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::type; + DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget)); + DCHECK_EQ(ToRegister(spread()), D::GetRegisterParameter(D::kSpread)); + } else { + using D = CallInterfaceDescriptorFor::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::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::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::type; + return D::GetStackParameterCount(); +} +void CallWithArrayLike::SetValueLocationConstraints() { + using D = CallInterfaceDescriptorFor::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::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 // --- diff --git a/src/maglev/maglev-ir.h b/src/maglev/maglev-ir.h index d1d4fb07e6..b9702eec2a 100644 --- a/src/maglev/maglev-ir.h +++ b/src/maglev/maglev-ir.h @@ -5132,14 +5132,24 @@ class CallWithSpread : public ValueNodeT { 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; diff --git a/src/maglev/x64/maglev-ir-x64.cc b/src/maglev/x64/maglev-ir-x64.cc index c93a711de8..838c00d032 100644 --- a/src/maglev/x64/maglev-ir-x64.cc +++ b/src/maglev/x64/maglev-ir-x64.cc @@ -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::type; - return argc_no_spread + D::GetStackParameterCount(); - } else { - using D = CallInterfaceDescriptorFor::type; - return argc_no_spread + D::GetStackParameterCount(); - } -} -void CallWithSpread::SetValueLocationConstraints() { - if (feedback_.IsValid()) { - using D = - CallInterfaceDescriptorFor::type; - UseFixed(function(), D::GetRegisterParameter(D::kTarget)); - UseFixed(spread(), D::GetRegisterParameter(D::kSpread)); - } else { - using D = CallInterfaceDescriptorFor::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::type; - DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget)); - DCHECK_EQ(ToRegister(spread()), D::GetRegisterParameter(D::kSpread)); - } else { - using D = CallInterfaceDescriptorFor::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::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::type; - __ Move(D::GetRegisterParameter(D::kArgumentsCount), argc_no_spread); - __ CallBuiltin(Builtin::kCallWithSpread); - } - - masm->DefineExceptionHandlerAndLazyDeoptPoint(this); -} - -int CallWithArrayLike::MaxCallStackArgs() const { - using D = CallInterfaceDescriptorFor::type; - return D::GetStackParameterCount(); -} -void CallWithArrayLike::SetValueLocationConstraints() { - using D = CallInterfaceDescriptorFor::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::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<