[maglev] Add support for Symbol feedback on equality

Introduces a CheckSymbol to guard a reference equality for values in an
equality comparison with Symbol feedback.

Bug: v8:7700
Change-Id: Ieb012b292f2d955faf76e485e6636a2d293fa007
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3811500
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82219}
This commit is contained in:
Leszek Swirski 2022-08-05 11:06:15 +02:00 committed by V8 LUCI CQ
parent 2b50e9cee9
commit dd255c0c49
4 changed files with 57 additions and 1 deletions

View File

@ -513,7 +513,7 @@ void MaglevGraphBuilder::VisitCompareOperation() {
// return;
}
break;
case CompareOperationHint::kInternalizedString:
case CompareOperationHint::kInternalizedString: {
DCHECK(kOperation == Operation::kEqual ||
kOperation == Operation::kStrictEqual);
ValueNode *left, *right;
@ -529,6 +529,30 @@ void MaglevGraphBuilder::VisitCompareOperation() {
}
SetAccumulator(AddNewNode<TaggedEqual>({left, right}));
return;
}
case CompareOperationHint::kSymbol: {
DCHECK(kOperation == Operation::kEqual ||
kOperation == Operation::kStrictEqual);
ValueNode *left, *right;
if (IsRegisterEqualToAccumulator(0)) {
left = right = LoadRegisterTagged(0);
AddNewNode<CheckHeapObject>({left});
AddNewNode<CheckSymbol>({left});
} else {
left = LoadRegisterTagged(0);
right = GetAccumulatorTagged();
AddNewNode<CheckHeapObject>({left});
AddNewNode<CheckSymbol>({left});
AddNewNode<CheckHeapObject>({right});
AddNewNode<CheckSymbol>({right});
}
if (TryBuildCompareOperation<BranchIfReferenceCompare>(kOperation, left,
right)) {
return;
}
SetAccumulator(AddNewNode<TaggedEqual>({left, right}));
return;
}
default:
// Fallback to generic node.
break;

View File

@ -118,6 +118,7 @@ class MaglevGraphVerifier {
case Opcode::kCheckSmi:
case Opcode::kCheckNumber:
case Opcode::kCheckString:
case Opcode::kCheckSymbol:
case Opcode::kCheckedInternalizedString:
// TODO(victorgomes): Can we check that the input is Boolean?
case Opcode::kBranchIfToBooleanTrue:

View File

@ -1206,6 +1206,20 @@ void CheckHeapObject::GenerateCode(MaglevCodeGenState* code_gen_state,
}
void CheckHeapObject::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {}
void CheckSymbol::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(receiver_input());
}
void CheckSymbol::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register object = ToRegister(receiver_input());
__ AssertNotSmi(object);
__ LoadMap(kScratchRegister, object);
__ CmpInstanceType(kScratchRegister, SYMBOL_TYPE);
EmitEagerDeoptIf(not_equal, code_gen_state, DeoptimizeReason::kNotASymbol,
this);
}
void CheckSymbol::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {}
void CheckString::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(receiver_input());

View File

@ -183,6 +183,7 @@ class CompactInterpreterFrameState;
V(CheckSmi) \
V(CheckNumber) \
V(CheckHeapObject) \
V(CheckSymbol) \
V(CheckString) \
V(CheckMapsWithMigration) \
V(StoreTaggedFieldNoWriteBarrier) \
@ -2320,6 +2321,22 @@ class CheckHeapObject : public FixedInputNodeT<1, CheckHeapObject> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
};
class CheckSymbol : public FixedInputNodeT<1, CheckSymbol> {
using Base = FixedInputNodeT<1, CheckSymbol>;
public:
explicit CheckSymbol(uint64_t bitfield) : Base(bitfield) {}
static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
static constexpr int kReceiverIndex = 0;
Input& receiver_input() { return input(kReceiverIndex); }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
};
class CheckString : public FixedInputNodeT<1, CheckString> {
using Base = FixedInputNodeT<1, CheckString>;