[maglev] Remove HasProperty and use CallBuiltin instead
We create a constructor for CallBuiltin that accepts a feedback vector. It assumes that the builtin expects a slot and the vector respectively at the end. Bug: v8:7700 Change-Id: I20f9b4ff172dca7779abd31a042b3bdc734df350 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3804250 Auto-Submit: Victor Gomes <victorgomes@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#82159}
This commit is contained in:
parent
71d3ae39e7
commit
d195ce148b
@ -1939,9 +1939,8 @@ void MaglevGraphBuilder::VisitTestIn() {
|
|||||||
// TODO(victorgomes): Create fast path using feedback.
|
// TODO(victorgomes): Create fast path using feedback.
|
||||||
USE(feedback_source);
|
USE(feedback_source);
|
||||||
|
|
||||||
ValueNode* context = GetContext();
|
|
||||||
SetAccumulator(
|
SetAccumulator(
|
||||||
AddNewNode<HasProperty>({context, object, name}, feedback_source));
|
BuildCallBuiltin<Builtin::kKeyedHasIC>({object, name}, feedback_source));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaglevGraphBuilder::VisitToName() {
|
void MaglevGraphBuilder::VisitToName() {
|
||||||
|
@ -305,6 +305,26 @@ class MaglevGraphBuilder {
|
|||||||
return AddNode(call_builtin);
|
return AddNode(call_builtin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <Builtin kBuiltin>
|
||||||
|
CallBuiltin* BuildCallBuiltin(
|
||||||
|
std::initializer_list<ValueNode*> inputs,
|
||||||
|
compiler::FeedbackSource& feedback,
|
||||||
|
CallBuiltin::FeedbackSlotType slot_type = CallBuiltin::kTaggedIndex) {
|
||||||
|
CallBuiltin* call_builtin = BuildCallBuiltin<kBuiltin>(inputs);
|
||||||
|
call_builtin->set_feedback(feedback, slot_type);
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Check that the last parameters are kSlot and kVector.
|
||||||
|
using Descriptor = typename CallInterfaceDescriptorFor<kBuiltin>::type;
|
||||||
|
int slot_index = call_builtin->num_args(Descriptor::HasContextParameter());
|
||||||
|
int vector_index = slot_index + 1;
|
||||||
|
DCHECK_EQ(slot_index, Descriptor::kSlot);
|
||||||
|
// TODO(victorgomes): Rename all kFeedbackVector parameters in the builtins
|
||||||
|
// to kVector.
|
||||||
|
DCHECK_EQ(vector_index, Descriptor::kVector);
|
||||||
|
#endif // DEBUG
|
||||||
|
return call_builtin;
|
||||||
|
}
|
||||||
|
|
||||||
CallRuntime* BuildCallRuntime(Runtime::FunctionId function_id,
|
CallRuntime* BuildCallRuntime(Runtime::FunctionId function_id,
|
||||||
std::initializer_list<ValueNode*> inputs) {
|
std::initializer_list<ValueNode*> inputs) {
|
||||||
CallRuntime* call_runtime = CreateNewNode<CallRuntime>(
|
CallRuntime* call_runtime = CreateNewNode<CallRuntime>(
|
||||||
|
@ -182,7 +182,6 @@ class MaglevGraphVerifier {
|
|||||||
CheckValueInputIs(node, 1, ValueRepresentation::kTagged);
|
CheckValueInputIs(node, 1, ValueRepresentation::kTagged);
|
||||||
break;
|
break;
|
||||||
case Opcode::kDeleteProperty:
|
case Opcode::kDeleteProperty:
|
||||||
case Opcode::kHasProperty:
|
|
||||||
case Opcode::kLoadNamedFromSuperGeneric:
|
case Opcode::kLoadNamedFromSuperGeneric:
|
||||||
case Opcode::kSetNamedGeneric:
|
case Opcode::kSetNamedGeneric:
|
||||||
case Opcode::kDefineNamedOwnGeneric:
|
case Opcode::kDefineNamedOwnGeneric:
|
||||||
|
@ -761,26 +761,6 @@ void DeleteProperty::PrintParams(std::ostream& os,
|
|||||||
os << "(" << LanguageMode2String(mode()) << ")";
|
os << "(" << LanguageMode2String(mode()) << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void HasProperty::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
|
||||||
using D = CallInterfaceDescriptorFor<Builtin::kKeyedHasIC>::type;
|
|
||||||
UseFixed(context(), kContextRegister);
|
|
||||||
UseFixed(object(), D::GetRegisterParameter(D::kReceiver));
|
|
||||||
UseFixed(name(), D::GetRegisterParameter(D::kName));
|
|
||||||
DefineAsFixed(vreg_state, this, kReturnRegister0);
|
|
||||||
}
|
|
||||||
void HasProperty::GenerateCode(MaglevCodeGenState* code_gen_state,
|
|
||||||
const ProcessingState& state) {
|
|
||||||
using D = CallInterfaceDescriptorFor<Builtin::kKeyedHasIC>::type;
|
|
||||||
DCHECK_EQ(ToRegister(context()), kContextRegister);
|
|
||||||
DCHECK_EQ(ToRegister(object()), D::GetRegisterParameter(D::kReceiver));
|
|
||||||
DCHECK_EQ(ToRegister(name()), D::GetRegisterParameter(D::kName));
|
|
||||||
__ Move(D::GetRegisterParameter(D::kSlot),
|
|
||||||
TaggedIndex::FromIntptr(feedback().index()));
|
|
||||||
__ Move(D::GetRegisterParameter(D::kVector), feedback().vector);
|
|
||||||
__ CallBuiltin(Builtin::kKeyedHasIC);
|
|
||||||
code_gen_state->DefineLazyDeoptPoint(lazy_deopt_info());
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitialValue::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
void InitialValue::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||||
// TODO(leszeks): Make this nicer.
|
// TODO(leszeks): Make this nicer.
|
||||||
result().SetUnallocated(compiler::UnallocatedOperand::FIXED_SLOT,
|
result().SetUnallocated(compiler::UnallocatedOperand::FIXED_SLOT,
|
||||||
@ -2536,13 +2516,14 @@ void Construct::GenerateCode(MaglevCodeGenState* code_gen_state,
|
|||||||
void CallBuiltin::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
void CallBuiltin::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||||
// TODO(v8:7700): Support stack arguments.
|
// TODO(v8:7700): Support stack arguments.
|
||||||
auto descriptor = Builtins::CallInterfaceDescriptorFor(builtin());
|
auto descriptor = Builtins::CallInterfaceDescriptorFor(builtin());
|
||||||
|
bool has_context = descriptor.HasContextParameter();
|
||||||
DCHECK_EQ(descriptor.GetRegisterParameterCount(),
|
DCHECK_EQ(descriptor.GetRegisterParameterCount(),
|
||||||
num_args(descriptor.HasContextParameter()));
|
num_args(has_context) + (has_feedback() ? 2 : 0));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < num_args(descriptor.HasContextParameter()); i++) {
|
for (; i < num_args(has_context); i++) {
|
||||||
UseFixed(input(i), descriptor.GetRegisterParameter(i));
|
UseFixed(input(i), descriptor.GetRegisterParameter(i));
|
||||||
}
|
}
|
||||||
if (descriptor.HasContextParameter()) {
|
if (has_context) {
|
||||||
UseFixed(input(i), kContextRegister);
|
UseFixed(input(i), kContextRegister);
|
||||||
}
|
}
|
||||||
DCHECK_EQ(descriptor.GetReturnCount(), 1);
|
DCHECK_EQ(descriptor.GetReturnCount(), 1);
|
||||||
@ -2550,6 +2531,22 @@ void CallBuiltin::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
|||||||
}
|
}
|
||||||
void CallBuiltin::GenerateCode(MaglevCodeGenState* code_gen_state,
|
void CallBuiltin::GenerateCode(MaglevCodeGenState* code_gen_state,
|
||||||
const ProcessingState& state) {
|
const ProcessingState& state) {
|
||||||
|
if (has_feedback()) {
|
||||||
|
auto descriptor = Builtins::CallInterfaceDescriptorFor(builtin());
|
||||||
|
int slot_index = num_args(descriptor.HasContextParameter());
|
||||||
|
int vector_index = slot_index + 1;
|
||||||
|
switch (slot_type()) {
|
||||||
|
case kTaggedIndex:
|
||||||
|
__ Move(descriptor.GetRegisterParameter(slot_index),
|
||||||
|
TaggedIndex::FromIntptr(feedback().index()));
|
||||||
|
break;
|
||||||
|
case kSmi:
|
||||||
|
__ Move(descriptor.GetRegisterParameter(slot_index),
|
||||||
|
Smi::FromInt(feedback().index()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
__ Move(descriptor.GetRegisterParameter(vector_index), feedback().vector);
|
||||||
|
}
|
||||||
__ CallBuiltin(builtin());
|
__ CallBuiltin(builtin());
|
||||||
code_gen_state->DefineLazyDeoptPoint(lazy_deopt_info());
|
code_gen_state->DefineLazyDeoptPoint(lazy_deopt_info());
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,6 @@ class CompactInterpreterFrameState;
|
|||||||
V(FastCreateClosure) \
|
V(FastCreateClosure) \
|
||||||
V(CreateRegExpLiteral) \
|
V(CreateRegExpLiteral) \
|
||||||
V(DeleteProperty) \
|
V(DeleteProperty) \
|
||||||
V(HasProperty) \
|
|
||||||
V(InitialValue) \
|
V(InitialValue) \
|
||||||
V(LoadTaggedField) \
|
V(LoadTaggedField) \
|
||||||
V(LoadDoubleField) \
|
V(LoadDoubleField) \
|
||||||
@ -1728,31 +1727,6 @@ class DeleteProperty : public FixedInputValueNodeT<3, DeleteProperty> {
|
|||||||
const LanguageMode mode_;
|
const LanguageMode mode_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HasProperty : public FixedInputValueNodeT<3, HasProperty> {
|
|
||||||
using Base = FixedInputValueNodeT<3, HasProperty>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit HasProperty(uint64_t bitfield,
|
|
||||||
const compiler::FeedbackSource& feedback)
|
|
||||||
: Base(bitfield), feedback_(feedback) {}
|
|
||||||
|
|
||||||
// The implementation currently calls runtime.
|
|
||||||
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
|
||||||
|
|
||||||
Input& context() { return input(0); }
|
|
||||||
Input& object() { return input(1); }
|
|
||||||
Input& name() { return input(2); }
|
|
||||||
|
|
||||||
compiler::FeedbackSource feedback() const { return feedback_; }
|
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*);
|
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
|
||||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const compiler::FeedbackSource feedback_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ToObject : public FixedInputValueNodeT<2, ToObject> {
|
class ToObject : public FixedInputValueNodeT<2, ToObject> {
|
||||||
using Base = FixedInputValueNodeT<2, ToObject>;
|
using Base = FixedInputValueNodeT<2, ToObject>;
|
||||||
|
|
||||||
@ -2858,6 +2832,8 @@ class CallBuiltin : public ValueNodeT<CallBuiltin> {
|
|||||||
using Base = ValueNodeT<CallBuiltin>;
|
using Base = ValueNodeT<CallBuiltin>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum FeedbackSlotType { kTaggedIndex, kSmi };
|
||||||
|
|
||||||
// This ctor is used when for variable input counts.
|
// This ctor is used when for variable input counts.
|
||||||
// Inputs must be initialized manually.
|
// Inputs must be initialized manually.
|
||||||
CallBuiltin(uint64_t bitfield, Builtin builtin)
|
CallBuiltin(uint64_t bitfield, Builtin builtin)
|
||||||
@ -2878,6 +2854,21 @@ class CallBuiltin : public ValueNodeT<CallBuiltin> {
|
|||||||
// This is an overestimation, since some builtins might not call JS code.
|
// This is an overestimation, since some builtins might not call JS code.
|
||||||
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
||||||
|
|
||||||
|
bool has_feedback() const { return feedback_.has_value(); }
|
||||||
|
compiler::FeedbackSource feedback() const {
|
||||||
|
DCHECK(has_feedback());
|
||||||
|
return feedback_.value();
|
||||||
|
}
|
||||||
|
FeedbackSlotType slot_type() const {
|
||||||
|
DCHECK(has_feedback());
|
||||||
|
return slot_type_;
|
||||||
|
}
|
||||||
|
void set_feedback(compiler::FeedbackSource& feedback,
|
||||||
|
FeedbackSlotType slot_type) {
|
||||||
|
feedback_ = feedback;
|
||||||
|
slot_type_ = slot_type;
|
||||||
|
}
|
||||||
|
|
||||||
Builtin builtin() const { return builtin_; }
|
Builtin builtin() const { return builtin_; }
|
||||||
|
|
||||||
int num_args(bool has_context) const {
|
int num_args(bool has_context) const {
|
||||||
@ -2895,6 +2886,8 @@ class CallBuiltin : public ValueNodeT<CallBuiltin> {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Builtin builtin_;
|
Builtin builtin_;
|
||||||
|
base::Optional<compiler::FeedbackSource> feedback_;
|
||||||
|
FeedbackSlotType slot_type_ = kTaggedIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CallRuntime : public ValueNodeT<CallRuntime> {
|
class CallRuntime : public ValueNodeT<CallRuntime> {
|
||||||
|
Loading…
Reference in New Issue
Block a user