[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:
jameslahm 2022-08-02 19:26:02 +08:00 committed by V8 LUCI CQ
parent 1835dec7c0
commit 5903aa9354
5 changed files with 62 additions and 2 deletions

View File

@ -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)

View File

@ -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:

View File

@ -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());

View File

@ -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>;

View 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));