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:
parent
1e199f11a6
commit
9e2b7c683f
@ -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) \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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>;
|
||||
|
Loading…
Reference in New Issue
Block a user