Revert "[maglev] Skip CallFunction stub when we know the target"

This reverts commit 5d2cb9bdd2.

Reason for revert: Test failure for mjsunit/regress/regress-crbug-762472 in maglev variant.
https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Linux64%20-%20debug/43512/overview

Original change's description:
> [maglev] Skip CallFunction stub when we know the target
>
> Bug: v8:7700
> Change-Id: Ie896f8dc40892c16995947b90b612a8091569929
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3986726
> Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
> Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
> Commit-Queue: Victor Gomes <victorgomes@chromium.org>
> Reviewed-by: Toon Verwaest <verwaest@chromium.org>
> Auto-Submit: Victor Gomes <victorgomes@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#83973}

Bug: v8:7700
Change-Id: I20f7a76df4721fc9e26b36984003921f2b47646e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3990751
Owners-Override: Matthias Liedtke <mliedtke@chromium.org>
Auto-Submit: Matthias Liedtke <mliedtke@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#83978}
This commit is contained in:
Matthias Liedtke 2022-10-28 12:32:54 +00:00 committed by V8 LUCI CQ
parent 1e199f11a6
commit 9e2b7c683f
6 changed files with 0 additions and 211 deletions

View File

@ -289,10 +289,6 @@ inline bool operator==(const ObjectRef& lhs, const ObjectRef& rhs) {
return lhs.equals(rhs);
}
inline bool operator!=(const ObjectRef& lhs, const ObjectRef& rhs) {
return !lhs.equals(rhs);
}
inline bool operator<(const ObjectRef& lhs, const ObjectRef& rhs) {
return lhs.data_ < rhs.data_;
}
@ -888,7 +884,6 @@ class ScopeInfoRef : public HeapObjectRef {
};
#define BROKER_SFI_FIELDS(V) \
V(int, internal_formal_parameter_count_with_receiver) \
V(int, internal_formal_parameter_count_without_receiver) \
V(bool, IsDontAdaptArguments) \
V(bool, has_simple_parameters) \

View File

@ -2588,52 +2588,6 @@ bool MaglevGraphBuilder::TryInlineBuiltin(base::Optional<int> receiver_index,
}
}
ValueNode* MaglevGraphBuilder::GetConvertReceiver(
compiler::JSFunctionRef function, ConvertReceiverMode mode,
int operand_index) {
compiler::SharedFunctionInfoRef shared = function.shared();
if (shared.native() || shared.language_mode() == LanguageMode::kStrict) {
if (mode == ConvertReceiverMode::kNullOrUndefined) {
return GetRootConstant(RootIndex::kUndefinedValue);
} else {
return LoadRegisterTagged(operand_index);
}
}
if (mode == ConvertReceiverMode::kNullOrUndefined) {
return GetConstant(function.native_context().global_proxy_object());
}
ValueNode* receiver = LoadRegisterTagged(operand_index);
if (Constant* constant = receiver->TryCast<Constant>()) {
const Handle<HeapObject> object = constant->object().object();
if (object->IsUndefined()) {
return GetConstant(function.native_context().global_proxy_object());
} else if (object->IsJSReceiver()) {
return constant;
}
}
return AddNewNode<ConvertReceiver>({receiver}, function, mode);
}
bool MaglevGraphBuilder::TryBuildCallKnownJSFunction(
compiler::JSFunctionRef function, int argc_count,
ConvertReceiverMode receiver_mode) {
// Don't inline CallFunction stub across native contexts.
if (function.native_context() != broker()->target_native_context()) {
return false;
}
ValueNode* receiver = GetConvertReceiver(function, receiver_mode, 1);
size_t input_count = argc_count + CallKnownJSFunction::kFixedInputCount;
CallKnownJSFunction* call =
CreateNewNode<CallKnownJSFunction>(input_count, function, receiver);
const int first_arg_operand_index =
(receiver_mode == ConvertReceiverMode::kNullOrUndefined) ? 0 : 1;
for (int i = 0; i < argc_count; i++) {
call->set_arg(i, LoadRegisterTagged(first_arg_operand_index + i + 1));
}
SetAccumulator(AddNode(call));
return true;
}
void MaglevGraphBuilder::BuildCallFromRegisters(
int argc_count, ConvertReceiverMode receiver_mode) {
// Indices and counts of operands on the bytecode.
@ -2703,10 +2657,6 @@ void MaglevGraphBuilder::BuildCallFromRegisters(
}
}
if (TryBuildCallKnownJSFunction(target.AsJSFunction(), argc_count,
receiver_mode)) {
return;
}
break;
}

View File

@ -983,12 +983,6 @@ class MaglevGraphBuilder {
ConvertReceiverMode receiver_mode,
compiler::JSFunctionRef function);
ValueNode* GetConvertReceiver(compiler::JSFunctionRef function,
ConvertReceiverMode mode, int operand_index);
bool TryBuildCallKnownJSFunction(compiler::JSFunctionRef function,
int argc_count,
ConvertReceiverMode receiver_mode);
void BuildCallFromRegisterList(ConvertReceiverMode receiver_mode);
void BuildCallFromRegisters(int argc_count,
ConvertReceiverMode receiver_mode);

View File

@ -126,7 +126,6 @@ class MaglevGraphVerifier {
case Opcode::kCheckSymbol:
case Opcode::kCheckedInternalizedString:
case Opcode::kCheckedObjectToIndex:
case Opcode::kConvertReceiver:
// TODO(victorgomes): Can we check that the input is Boolean?
case Opcode::kBranchIfToBooleanTrue:
case Opcode::kBranchIfRootConstant:
@ -269,7 +268,6 @@ class MaglevGraphVerifier {
CheckValueInputIs(node, 1, ValueRepresentation::kFloat64);
break;
case Opcode::kCall:
case Opcode::kCallKnownJSFunction:
case Opcode::kCallRuntime:
case Opcode::kCallWithSpread:
case Opcode::kConstruct:

View File

@ -13,7 +13,6 @@
#include "src/codegen/register.h"
#include "src/codegen/reglist.h"
#include "src/codegen/x64/assembler-x64.h"
#include "src/codegen/x64/register-x64.h"
#include "src/common/globals.h"
#include "src/compiler/backend/instruction.h"
#include "src/deoptimizer/deoptimize-reason.h"
@ -3601,47 +3600,6 @@ void Call::GenerateCode(MaglevAssembler* masm, const ProcessingState& state) {
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
void CallKnownJSFunction::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseAny(receiver());
for (int i = 0; i < num_args(); i++) {
UseAny(arg(i));
}
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void CallKnownJSFunction::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
int expected_parameter_count =
shared_function_info().internal_formal_parameter_count_with_receiver();
int actual_parameter_count = num_args() + 1;
if (actual_parameter_count < expected_parameter_count) {
int number_of_undefineds =
expected_parameter_count - actual_parameter_count;
__ LoadRoot(kScratchRegister, RootIndex::kUndefinedValue);
for (int i = 0; i < number_of_undefineds; i++) {
__ Push(kScratchRegister);
}
}
for (int i = num_args() - 1; i >= 0; --i) {
__ PushInput(arg(i));
}
__ PushInput(receiver());
__ Move(kContextRegister, function_.context().object());
__ Move(kJavaScriptCallTargetRegister, function_.object());
__ LoadRoot(kJavaScriptCallNewTargetRegister, RootIndex::kUndefinedValue);
__ Move(kJavaScriptCallArgCountRegister, Immediate(actual_parameter_count));
if (shared_function_info().HasBuiltinId()) {
__ CallBuiltin(shared_function_info().builtin_id());
} else {
__ Move(kJavaScriptCallCodeStartRegister, function_.code().object());
__ CallCodeTObject(kJavaScriptCallCodeStartRegister);
}
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
void CallKnownJSFunction::PrintParams(
std::ostream& os, MaglevGraphLabeller* graph_labeller) const {
os << "(" << function_.object() << ")";
}
void Construct::AllocateVreg(MaglevVregAllocationState* vreg_state) {
using D = Construct_WithFeedbackDescriptor;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
@ -3873,45 +3831,6 @@ void ConstructWithSpread::GenerateCode(MaglevAssembler* masm,
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
void ConvertReceiver::AllocateVreg(MaglevVregAllocationState* vreg_state) {
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
UseFixed(receiver_input(), D::GetRegisterParameter(D::kInput));
set_temporaries_needed(1);
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void ConvertReceiver::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Label convert_to_object, done;
Register receiver = ToRegister(receiver_input());
Register scratch = general_temporaries().first();
__ JumpIfSmi(receiver, &convert_to_object, Label::kNear);
static_assert(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CmpObjectType(receiver, FIRST_JS_RECEIVER_TYPE, scratch);
__ j(above_equal, &done);
if (mode_ != ConvertReceiverMode::kNotNullOrUndefined) {
Label convert_global_proxy;
__ JumpIfRoot(receiver, RootIndex::kUndefinedValue, &convert_global_proxy,
Label::kNear);
__ JumpIfNotRoot(receiver, RootIndex::kNullValue, &convert_to_object,
Label::kNear);
__ bind(&convert_global_proxy);
{
// Patch receiver to global proxy.
__ Move(ToRegister(result()),
target_.native_context().global_proxy_object().object());
}
__ jmp(&done);
}
__ bind(&convert_to_object);
// ToObject needs to be ran with the target context installed.
__ Move(kContextRegister, target_.context().object());
__ CallBuiltin(Builtin::kToObject);
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
__ bind(&done);
}
void IncreaseInterruptBudget::AllocateVreg(
MaglevVregAllocationState* vreg_state) {
set_temporaries_needed(1);

View File

@ -127,10 +127,8 @@ class CompactInterpreterFrameState;
V(CallBuiltin) \
V(CallRuntime) \
V(CallWithSpread) \
V(CallKnownJSFunction) \
V(Construct) \
V(ConstructWithSpread) \
V(ConvertReceiver) \
V(CreateEmptyArrayLiteral) \
V(CreateArrayLiteral) \
V(CreateShallowArrayLiteral) \
@ -3940,48 +3938,6 @@ class CallWithSpread : public ValueNodeT<CallWithSpread> {
const compiler::FeedbackSource feedback_;
};
class CallKnownJSFunction : public ValueNodeT<CallKnownJSFunction> {
using Base = ValueNodeT<CallKnownJSFunction>;
public:
// We assume function and context as fixed inputs.
static constexpr int kReceiverIndex = 0;
static constexpr int kFixedInputCount = 1;
// We need enough inputs to have these fixed inputs plus the maximum arguments
// to a function call.
static_assert(kMaxInputs >= kFixedInputCount + Code::kMaxArguments);
// This ctor is used when for variable input counts.
// Inputs must be initialized manually.
CallKnownJSFunction(uint64_t bitfield, const compiler::JSFunctionRef function,
ValueNode* receiver)
: Base(bitfield), function_(function) {
set_input(kReceiverIndex, receiver);
}
static constexpr OpProperties kProperties = OpProperties::JSCall();
Input& receiver() { return input(kReceiverIndex); }
const Input& receiver() const { return input(kReceiverIndex); }
int num_args() const { return input_count() - kFixedInputCount; }
Input& arg(int i) { return input(i + kFixedInputCount); }
void set_arg(int i, ValueNode* node) {
set_input(i + kFixedInputCount, node);
}
compiler::SharedFunctionInfoRef shared_function_info() const {
return function_.shared();
}
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevAssembler*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
private:
const compiler::JSFunctionRef function_;
};
class ConstructWithSpread : public ValueNodeT<ConstructWithSpread> {
using Base = ValueNodeT<ConstructWithSpread>;
@ -4030,29 +3986,6 @@ class ConstructWithSpread : public ValueNodeT<ConstructWithSpread> {
const compiler::FeedbackSource feedback_;
};
class ConvertReceiver : public FixedInputValueNodeT<1, ConvertReceiver> {
using Base = FixedInputValueNodeT<1, ConvertReceiver>;
public:
explicit ConvertReceiver(uint64_t bitfield,
const compiler::JSFunctionRef target,
ConvertReceiverMode mode)
: Base(bitfield), target_(target), mode_(mode) {}
Input& receiver_input() { return input(0); }
// The implementation currently calls runtime.
static constexpr OpProperties kProperties = OpProperties::JSCall();
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevAssembler*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
private:
const compiler::JSFunctionRef target_;
ConvertReceiverMode mode_;
};
class IncreaseInterruptBudget
: public FixedInputNodeT<0, IncreaseInterruptBudget> {
using Base = FixedInputNodeT<0, IncreaseInterruptBudget>;