[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 <verwaest@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83857}
This commit is contained in:
Toon Verwaest 2022-10-21 16:47:33 +02:00 committed by V8 LUCI CQ
parent b9caf49c9a
commit f150ead829
3 changed files with 40 additions and 8 deletions

View File

@ -1279,6 +1279,7 @@ bool MaglevGraphBuilder::TryBuildPropertyGetterCall(
? ConvertReceiverMode::kNotNullOrUndefined
: ConvertReceiverMode::kAny;
Call* call = CreateNewNode<Call>(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>(
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<Constant>()) {
AddNewNode<CheckValue>({function}, target);
} else if (!function->Cast<Constant>()->object().equals(target)) {
@ -2282,8 +2287,8 @@ void MaglevGraphBuilder::BuildCallFromRegisterList(
input_count++;
}
Call* call = CreateNewNode<Call>(input_count, receiver_mode, feedback_source,
function, context);
Call* call = CreateNewNode<Call>(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<Constant>()) {
AddNewNode<CheckValue>({function}, target);
} else if (!function->Cast<Constant>()->object().equals(target)) {
@ -2361,8 +2368,8 @@ void MaglevGraphBuilder::BuildCallFromRegisters(
int arg_index = 0;
int reg_count = argc_count_with_recv;
Call* call = CreateNewNode<Call>(input_count, receiver_mode, feedback_source,
function, context);
Call* call = CreateNewNode<Call>(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<Call>(input_count, ConvertReceiverMode::kNullOrUndefined,
Call::TargetType::kJSFunction,
compiler::FeedbackSource(), callee, GetContext());
int arg_index = 0;
call->set_arg(arg_index++, GetRootConstant(RootIndex::kUndefinedValue));

View File

@ -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);

View File

@ -3603,6 +3603,8 @@ class Call : public ValueNodeT<Call> {
using Base = ValueNodeT<Call>;
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<Call> {
// 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<Call> {
private:
ConvertReceiverMode receiver_mode_;
TargetType target_type_;
const compiler::FeedbackSource feedback_;
};