[maglev] Support BranchIfJSReceiver

Bug: v8:7700
Change-Id: I4cb5636acd38319f13d91cbad7d04486346ba74d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3805882
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82195}
This commit is contained in:
Victor Gomes 2022-08-04 10:10:54 +02:00 committed by V8 LUCI CQ
parent b6f01045ad
commit 1fce10002c
4 changed files with 64 additions and 68 deletions

View File

@ -2384,8 +2384,14 @@ void MaglevGraphBuilder::VisitJumpIfUndefinedOrNull() {
&jump_targets_[next_offset()]);
MergeIntoFrameState(block, iterator_.GetJumpTargetOffset());
}
void MaglevGraphBuilder::VisitJumpIfJSReceiver() {
BasicBlock* block = FinishBlock<BranchIfJSReceiver>(
next_offset(), {GetAccumulatorTagged()},
&jump_targets_[iterator_.GetJumpTargetOffset()],
&jump_targets_[next_offset()]);
MergeIntoFrameState(block, iterator_.GetJumpTargetOffset());
}
MAGLEV_UNIMPLEMENTED_BYTECODE(JumpIfJSReceiver)
MAGLEV_UNIMPLEMENTED_BYTECODE(SwitchOnSmiNoFeedback)
MAGLEV_UNIMPLEMENTED_BYTECODE(ForInEnumerate)
MAGLEV_UNIMPLEMENTED_BYTECODE(ForInPrepare)

View File

@ -122,6 +122,7 @@ class MaglevGraphVerifier {
case Opcode::kBranchIfToBooleanTrue:
case Opcode::kBranchIfRootConstant:
case Opcode::kBranchIfUndefinedOrNull:
case Opcode::kBranchIfJSReceiver:
case Opcode::kCheckedFloat64Unbox:
case Opcode::kCreateFunctionContext:
case Opcode::kCreateClosure:

View File

@ -96,6 +96,23 @@ void UseFixed(Input& input, Register reg) {
// Code gen helpers.
// ---
void Branch(MaglevCodeGenState* code_gen_state, Condition condition,
BasicBlock* if_true, BasicBlock* if_false, BasicBlock* next_block) {
// We don't have any branch probability information, so try to jump
// over whatever the next block emitted is.
if (if_false == next_block) {
// Jump over the false block if true, otherwise fall through into it.
__ j(condition, if_true->label());
} else {
// Jump to the false block if true.
__ j(NegateCondition(condition), if_false->label());
// Jump to the true block if it's not the next block.
if (if_true != next_block) {
__ jmp(if_true->label());
}
}
}
void PushInput(MaglevCodeGenState* code_gen_state, const Input& input) {
if (input.operand().IsConstant()) {
input.node()->LoadToRegister(code_gen_state, kScratchRegister);
@ -2916,23 +2933,8 @@ void BranchIfRootConstant::AllocateVreg(MaglevVregAllocationState* vreg_state) {
}
void BranchIfRootConstant::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register value = ToRegister(condition_input());
auto* next_block = state.next_block();
// We don't have any branch probability information, so try to jump
// over whatever the next block emitted is.
if (if_false() == next_block) {
// Jump over the false block if true, otherwise fall through into it.
__ JumpIfRoot(value, root_index(), if_true()->label());
} else {
// Jump to the false block if true.
__ JumpIfNotRoot(value, root_index(), if_false()->label());
// Jump to the true block if it's not the next block.
if (if_true() != next_block) {
__ jmp(if_true()->label());
}
}
__ CompareRoot(ToRegister(condition_input()), root_index());
Branch(code_gen_state, equal, if_true(), if_false(), state.next_block());
}
void BranchIfUndefinedOrNull::AllocateVreg(
@ -2950,6 +2952,19 @@ void BranchIfUndefinedOrNull::GenerateCode(MaglevCodeGenState* code_gen_state,
}
}
void BranchIfJSReceiver::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(condition_input());
}
void BranchIfJSReceiver::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register value = ToRegister(condition_input());
__ JumpIfSmi(value, if_false()->label());
__ LoadMap(kScratchRegister, value);
__ CmpInstanceType(kScratchRegister, FIRST_JS_RECEIVER_TYPE);
Branch(code_gen_state, above_equal, if_true(), if_false(),
state.next_block());
}
void BranchIfInt32Compare::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(left_input());
UseRegister(right_input());
@ -2958,24 +2973,9 @@ void BranchIfInt32Compare::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register left = ToRegister(left_input());
Register right = ToRegister(right_input());
auto* next_block = state.next_block();
__ cmpl(left, right);
// We don't have any branch probability information, so try to jump
// over whatever the next block emitted is.
if (if_false() == next_block) {
// Jump over the false block if true, otherwise fall through into it.
__ j(ConditionFor(operation_), if_true()->label());
} else {
// Jump to the false block if true.
__ j(NegateCondition(ConditionFor(operation_)), if_false()->label());
// Jump to the true block if it's not the next block.
if (if_true() != next_block) {
__ jmp(if_true()->label());
}
}
Branch(code_gen_state, ConditionFor(operation_), if_true(), if_false(),
state.next_block());
}
void BranchIfFloat64Compare::PrintParams(
std::ostream& os, MaglevGraphLabeller* graph_labeller) const {
@ -2991,24 +2991,9 @@ void BranchIfFloat64Compare::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
DoubleRegister left = ToDoubleRegister(left_input());
DoubleRegister right = ToDoubleRegister(right_input());
auto* next_block = state.next_block();
__ Ucomisd(left, right);
// We don't have any branch probability information, so try to jump
// over whatever the next block emitted is.
if (if_false() == next_block) {
// Jump over the false block if true, otherwise fall through into it.
__ j(ConditionFor(operation_), if_true()->label());
} else {
// Jump to the false block if true.
__ j(NegateCondition(ConditionFor(operation_)), if_false()->label());
// Jump to the true block if it's not the next block.
if (if_true() != next_block) {
__ jmp(if_true()->label());
}
}
Branch(code_gen_state, ConditionFor(operation_), if_true(), if_false(),
state.next_block());
}
void BranchIfInt32Compare::PrintParams(
std::ostream& os, MaglevGraphLabeller* graph_labeller) const {
@ -3024,22 +3009,9 @@ void BranchIfReferenceCompare::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register left = ToRegister(left_input());
Register right = ToRegister(right_input());
auto* next_block = state.next_block();
__ cmp_tagged(left, right);
// We don't have any branch probability information, so try to jump
// over whatever the next block emitted is.
if (if_false() == next_block) {
// Jump over the false block if true, otherwise fall through into it.
__ j(ConditionFor(operation_), if_true()->label());
} else {
// Jump to the false block if true.
__ j(NegateCondition(ConditionFor(operation_)), if_false()->label());
// Jump to the true block if it's not the next block.
if (if_true() != next_block) {
__ jmp(if_true()->label());
}
}
Branch(code_gen_state, ConditionFor(operation_), if_true(), if_false(),
state.next_block());
}
void BranchIfReferenceCompare::PrintParams(
std::ostream& os, MaglevGraphLabeller* graph_labeller) const {

View File

@ -198,7 +198,8 @@ class CompactInterpreterFrameState;
V(BranchIfReferenceCompare) \
V(BranchIfInt32Compare) \
V(BranchIfFloat64Compare) \
V(BranchIfUndefinedOrNull)
V(BranchIfUndefinedOrNull) \
V(BranchIfJSReceiver)
#define UNCONDITIONAL_CONTROL_NODE_LIST(V) \
V(Jump) \
@ -3517,6 +3518,22 @@ class BranchIfUndefinedOrNull
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
class BranchIfJSReceiver
: public ConditionalControlNodeT<1, BranchIfJSReceiver> {
using Base = ConditionalControlNodeT<1, BranchIfJSReceiver>;
public:
explicit BranchIfJSReceiver(uint64_t bitfield, BasicBlockRef* if_true_refs,
BasicBlockRef* if_false_refs)
: Base(bitfield, if_true_refs, if_false_refs) {}
Input& condition_input() { return input(0); }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
class BranchIfToBooleanTrue
: public ConditionalControlNodeT<1, BranchIfToBooleanTrue> {
using Base = ConditionalControlNodeT<1, BranchIfToBooleanTrue>;