[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:
parent
b6f01045ad
commit
1fce10002c
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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>;
|
||||
|
Loading…
Reference in New Issue
Block a user