From f150ead8298f76d314c7dd9a682da2bfdb26e903 Mon Sep 17 00:00:00 2001 From: Toon Verwaest Date: Fri, 21 Oct 2022 16:47:33 +0200 Subject: [PATCH] [maglev] Use CallFunction_* where possible Basically when the feedback says it's a JSFunction. Bug: v8:7700 Change-Id: Ieb8484f3de44e2600aa8af9cb564b0f09f8531ff Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3971125 Commit-Queue: Toon Verwaest Reviewed-by: Leszek Swirski Auto-Submit: Toon Verwaest Cr-Commit-Position: refs/heads/main@{#83857} --- src/maglev/maglev-graph-builder.cc | 18 +++++++++++++----- src/maglev/maglev-ir.cc | 20 +++++++++++++++++++- src/maglev/maglev-ir.h | 10 ++++++++-- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc index 4bb4d4559c..f4f1982165 100644 --- a/src/maglev/maglev-graph-builder.cc +++ b/src/maglev/maglev-graph-builder.cc @@ -1279,6 +1279,7 @@ bool MaglevGraphBuilder::TryBuildPropertyGetterCall( ? ConvertReceiverMode::kNotNullOrUndefined : ConvertReceiverMode::kAny; Call* call = CreateNewNode(Call::kFixedInputCount + 1, receiver_mode, + Call::TargetType::kJSFunction, compiler::FeedbackSource(), GetConstant(constant), GetContext()); call->set_arg(0, receiver); @@ -1297,7 +1298,8 @@ bool MaglevGraphBuilder::TryBuildPropertySetterCall( if (constant.IsJSFunction()) { Call* call = CreateNewNode( Call::kFixedInputCount + 2, ConvertReceiverMode::kNotNullOrUndefined, - compiler::FeedbackSource(), GetConstant(constant), GetContext()); + Call::TargetType::kJSFunction, compiler::FeedbackSource(), + GetConstant(constant), GetContext()); call->set_arg(0, receiver); call->set_arg(1, value); SetAccumulator(AddNode(call)); @@ -2251,6 +2253,8 @@ void MaglevGraphBuilder::BuildCallFromRegisterList( interpreter::RegisterList args = iterator_.GetRegisterListOperand(1); ValueNode* context = GetContext(); + Call::TargetType target_type = Call::TargetType::kAny; + FeedbackSlot slot = GetSlotOperand(3); compiler::FeedbackSource feedback_source(feedback(), slot); const compiler::ProcessedFeedback& processed_feedback = @@ -2266,6 +2270,7 @@ void MaglevGraphBuilder::BuildCallFromRegisterList( if (target.IsJSFunction()) { // Reset the feedback source feedback_source = compiler::FeedbackSource(); + target_type = Call::TargetType::kJSFunction; if (!function->Is()) { AddNewNode({function}, target); } else if (!function->Cast()->object().equals(target)) { @@ -2282,8 +2287,8 @@ void MaglevGraphBuilder::BuildCallFromRegisterList( input_count++; } - Call* call = CreateNewNode(input_count, receiver_mode, feedback_source, - function, context); + Call* call = CreateNewNode(input_count, receiver_mode, target_type, + feedback_source, function, context); int arg_index = 0; if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { call->set_arg(arg_index++, GetRootConstant(RootIndex::kUndefinedValue)); @@ -2308,6 +2313,7 @@ void MaglevGraphBuilder::BuildCallFromRegisters( DCHECK_LE(argc_count, 2); ValueNode* function = LoadRegisterTagged(0); ValueNode* context = GetContext(); + Call::TargetType target_type = Call::TargetType::kAny; FeedbackSlot slot = GetSlotOperand(kSlotOperandIndex); compiler::FeedbackSource feedback_source(feedback(), slot); @@ -2342,6 +2348,7 @@ void MaglevGraphBuilder::BuildCallFromRegisters( // Reset the feedback source feedback_source = compiler::FeedbackSource(); + target_type = Call::TargetType::kJSFunction; if (!function->Is()) { AddNewNode({function}, target); } else if (!function->Cast()->object().equals(target)) { @@ -2361,8 +2368,8 @@ void MaglevGraphBuilder::BuildCallFromRegisters( int arg_index = 0; int reg_count = argc_count_with_recv; - Call* call = CreateNewNode(input_count, receiver_mode, feedback_source, - function, context); + Call* call = CreateNewNode(input_count, receiver_mode, target_type, + feedback_source, function, context); if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { reg_count = argc_count; call->set_arg(arg_index++, GetRootConstant(RootIndex::kUndefinedValue)); @@ -2449,6 +2456,7 @@ void MaglevGraphBuilder::VisitCallJSRuntime() { Call* call = CreateNewNode(input_count, ConvertReceiverMode::kNullOrUndefined, + Call::TargetType::kJSFunction, compiler::FeedbackSource(), callee, GetContext()); int arg_index = 0; call->set_arg(arg_index++, GetRootConstant(RootIndex::kUndefinedValue)); diff --git a/src/maglev/maglev-ir.cc b/src/maglev/maglev-ir.cc index 97d2b34855..48ee22fbe0 100644 --- a/src/maglev/maglev-ir.cc +++ b/src/maglev/maglev-ir.cc @@ -3285,6 +3285,7 @@ void Call::GenerateCode(MaglevAssembler* masm, const ProcessingState& state) { uint32_t arg_count = num_args(); if (feedback_.IsValid()) { + DCHECK_EQ(TargetType::kAny, target_type_); using D = CallTrampoline_WithFeedbackDescriptor; __ Move(D::GetRegisterParameter(D::kActualArgumentsCount), Immediate(arg_count)); @@ -3303,7 +3304,7 @@ void Call::GenerateCode(MaglevAssembler* masm, const ProcessingState& state) { __ CallBuiltin(Builtin::kCall_ReceiverIsAny_WithFeedback); break; } - } else { + } else if (target_type_ == TargetType::kAny) { using D = CallTrampolineDescriptor; __ Move(D::GetRegisterParameter(D::kActualArgumentsCount), Immediate(arg_count)); @@ -3319,6 +3320,23 @@ void Call::GenerateCode(MaglevAssembler* masm, const ProcessingState& state) { __ CallBuiltin(Builtin::kCall_ReceiverIsAny); break; } + } else { + DCHECK_EQ(TargetType::kJSFunction, target_type_); + using D = CallTrampolineDescriptor; + __ Move(D::GetRegisterParameter(D::kActualArgumentsCount), + Immediate(arg_count)); + + switch (receiver_mode_) { + case ConvertReceiverMode::kNullOrUndefined: + __ CallBuiltin(Builtin::kCallFunction_ReceiverIsNullOrUndefined); + break; + case ConvertReceiverMode::kNotNullOrUndefined: + __ CallBuiltin(Builtin::kCallFunction_ReceiverIsNotNullOrUndefined); + break; + case ConvertReceiverMode::kAny: + __ CallBuiltin(Builtin::kCallFunction_ReceiverIsAny); + break; + } } masm->DefineExceptionHandlerAndLazyDeoptPoint(this); diff --git a/src/maglev/maglev-ir.h b/src/maglev/maglev-ir.h index 97bf87f6ae..37fa78bfb5 100644 --- a/src/maglev/maglev-ir.h +++ b/src/maglev/maglev-ir.h @@ -3603,6 +3603,8 @@ class Call : public ValueNodeT { using Base = ValueNodeT; public: + enum class TargetType { kJSFunction, kAny }; + // We assume function and context as fixed inputs. static constexpr int kFunctionIndex = 0; static constexpr int kContextIndex = 1; @@ -3614,10 +3616,13 @@ class Call : public ValueNodeT { // This ctor is used when for variable input counts. // Inputs must be initialized manually. - Call(uint64_t bitfield, ConvertReceiverMode mode, + Call(uint64_t bitfield, ConvertReceiverMode mode, TargetType target_type, const compiler::FeedbackSource& feedback, ValueNode* function, ValueNode* context) - : Base(bitfield), receiver_mode_(mode), feedback_(feedback) { + : Base(bitfield), + receiver_mode_(mode), + target_type_(target_type), + feedback_(feedback) { set_input(kFunctionIndex, function); set_input(kContextIndex, context); } @@ -3641,6 +3646,7 @@ class Call : public ValueNodeT { private: ConvertReceiverMode receiver_mode_; + TargetType target_type_; const compiler::FeedbackSource feedback_; };