[maglev] Support JumpIfUndefinedOrNull
Bug: v8:7700 Change-Id: I36018a3323d778b8657087736e1bff70b0fdbf2d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3779920 Commit-Queue: 王澳 <wangao.james@bytedance.com> Reviewed-by: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/main@{#82145}
This commit is contained in:
parent
1835dec7c0
commit
5903aa9354
@ -2161,7 +2161,14 @@ void MaglevGraphBuilder::VisitJumpIfNotUndefined() {
|
||||
BuildBranchIfUndefined(GetAccumulatorTagged(), next_offset(),
|
||||
iterator_.GetJumpTargetOffset());
|
||||
}
|
||||
MAGLEV_UNIMPLEMENTED_BYTECODE(JumpIfUndefinedOrNull)
|
||||
void MaglevGraphBuilder::VisitJumpIfUndefinedOrNull() {
|
||||
BasicBlock* block = FinishBlock<BranchIfUndefinedOrNull>(
|
||||
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)
|
||||
|
@ -120,6 +120,7 @@ class MaglevGraphVerifier {
|
||||
// TODO(victorgomes): Can we check that the input is Boolean?
|
||||
case Opcode::kBranchIfToBooleanTrue:
|
||||
case Opcode::kBranchIfRootConstant:
|
||||
case Opcode::kBranchIfUndefinedOrNull:
|
||||
case Opcode::kCheckedFloat64Unbox:
|
||||
case Opcode::kCreateFunctionContext:
|
||||
case Opcode::kCreateClosure:
|
||||
|
@ -2836,6 +2836,21 @@ void BranchIfRootConstant::GenerateCode(MaglevCodeGenState* code_gen_state,
|
||||
}
|
||||
}
|
||||
|
||||
void BranchIfUndefinedOrNull::AllocateVreg(
|
||||
MaglevVregAllocationState* vreg_state) {
|
||||
UseRegister(condition_input());
|
||||
}
|
||||
void BranchIfUndefinedOrNull::GenerateCode(MaglevCodeGenState* code_gen_state,
|
||||
const ProcessingState& state) {
|
||||
Register value = ToRegister(condition_input());
|
||||
__ JumpIfRoot(value, RootIndex::kUndefinedValue, if_true()->label());
|
||||
__ JumpIfRoot(value, RootIndex::kNullValue, if_true()->label());
|
||||
auto* next_block = state.next_block();
|
||||
if (if_false() != next_block) {
|
||||
__ jmp(if_false()->label());
|
||||
}
|
||||
}
|
||||
|
||||
void BranchIfInt32Compare::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
|
@ -194,7 +194,8 @@ class CompactInterpreterFrameState;
|
||||
V(BranchIfToBooleanTrue) \
|
||||
V(BranchIfReferenceCompare) \
|
||||
V(BranchIfInt32Compare) \
|
||||
V(BranchIfFloat64Compare)
|
||||
V(BranchIfFloat64Compare) \
|
||||
V(BranchIfUndefinedOrNull)
|
||||
|
||||
#define UNCONDITIONAL_CONTROL_NODE_LIST(V) \
|
||||
V(Jump) \
|
||||
@ -3371,6 +3372,23 @@ class BranchIfRootConstant
|
||||
RootIndex root_index_;
|
||||
};
|
||||
|
||||
class BranchIfUndefinedOrNull
|
||||
: public ConditionalControlNodeT<1, BranchIfUndefinedOrNull> {
|
||||
using Base = ConditionalControlNodeT<1, BranchIfUndefinedOrNull>;
|
||||
|
||||
public:
|
||||
explicit BranchIfUndefinedOrNull(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>;
|
||||
|
19
test/mjsunit/maglev/undefined-or-null-branch.js
Normal file
19
test/mjsunit/maglev/undefined-or-null-branch.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax --maglev --no-stress-opt --no-always-turbofan
|
||||
|
||||
function foo(x) {
|
||||
return x ?? 10
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(foo);
|
||||
assertEquals(10, foo(undefined));
|
||||
assertEquals(10, foo(null));
|
||||
assertEquals(1, foo(1));
|
||||
%OptimizeMaglevOnNextCall(foo);
|
||||
assertEquals(10, foo(undefined));
|
||||
assertEquals(10, foo(null));
|
||||
assertEquals(1, foo(1));
|
||||
assertTrue(isMaglevved(foo));
|
Loading…
Reference in New Issue
Block a user