Revert "[osr] Extract extended OSR checks to BaselineOnStackReplacement builtin"

This reverts commit a4216b7b11.

Reason for revert: https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Linux%20-%20arm64%20-%20sim%20-%20MSAN/43174/overview

Original change's description:
> [osr] Extract extended OSR checks to BaselineOnStackReplacement builtin
>
> .. to reduce Sparkplug code size.
>
> Bug: v8:12161
> Change-Id: I4029a75dfa37f716c285ce27153c077a0a82a341
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3576119
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Commit-Queue: Jakob Linke <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#79962}

Bug: v8:12161
Change-Id: I382609d0b8cd951a3df5c9c834fe7071eb90faa5
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584121
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Owners-Override: Tobias Tebbi <tebbi@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#79966}
This commit is contained in:
Tobias Tebbi 2022-04-13 16:42:38 +00:00 committed by V8 LUCI CQ
parent f47899537c
commit af1fa2869b
12 changed files with 101 additions and 352 deletions

View File

@ -1925,30 +1925,50 @@ void BaselineCompiler::VisitCreateRestParameter() {
}
void BaselineCompiler::VisitJumpLoop() {
Label osr_not_armed;
Label osr_not_armed, osr;
{
BaselineAssembler::ScratchRegisterScope scope(&basm_);
Register osr_urgency_and_install_target = scope.AcquireScratch();
ASM_CODE_COMMENT_STRING(&masm_, "OSR Check Armed");
using D = BaselineOnStackReplacementDescriptor;
Register osr_urgency_and_install_target =
D::OsrUrgencyAndInstallTargetRegister();
__ LoadRegister(osr_urgency_and_install_target,
interpreter::Register::bytecode_array());
__ LoadWord16FieldZeroExtend(
osr_urgency_and_install_target, osr_urgency_and_install_target,
BytecodeArray::kOsrUrgencyAndInstallTargetOffset);
const int loop_depth = iterator().GetImmediateOperand(1);
int loop_depth = iterator().GetImmediateOperand(1);
__ JumpIfImmediate(Condition::kUnsignedLessThanEqual,
osr_urgency_and_install_target, loop_depth,
&osr_not_armed, Label::kNear);
// TODO(jgruber): Move the extended checks into the
// BaselineOnStackReplacement builtin.
// OSR based on urgency, i.e. is the OSR urgency greater than the current
// loop depth?
STATIC_ASSERT(BytecodeArray::OsrUrgencyBits::kShift == 0);
Register scratch2 = scope.AcquireScratch();
__ Word32And(scratch2, osr_urgency_and_install_target,
BytecodeArray::OsrUrgencyBits::kMask);
__ JumpIfImmediate(Condition::kUnsignedGreaterThan, scratch2, loop_depth,
&osr, Label::kNear);
// OSR based on the install target offset, i.e. does the current bytecode
// offset match the install target offset?
static constexpr int kShift = BytecodeArray::OsrInstallTargetBits::kShift;
static constexpr int kMask = BytecodeArray::OsrInstallTargetBits::kMask;
const int encoded_current_offset =
BytecodeArray::OsrInstallTargetFor(
BytecodeOffset{iterator().current_offset()})
<< BytecodeArray::OsrInstallTargetBits::kShift;
CallBuiltin<Builtin::kBaselineOnStackReplacement>(
loop_depth, encoded_current_offset, osr_urgency_and_install_target);
<< kShift;
__ Word32And(scratch2, osr_urgency_and_install_target, kMask);
__ JumpIfImmediate(Condition::kNotEqual, scratch2, encoded_current_offset,
&osr_not_armed, Label::kNear);
}
__ Bind(&osr);
CallBuiltin<Builtin::kBaselineOnStackReplacement>();
__ Bind(&osr_not_armed);
Label* label = &labels_[iterator().GetJumpTargetOffset()]->unlinked;
int weight = iterator().GetRelativeJumpTargetOffset() -

View File

@ -1816,44 +1816,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address,
__ Ret();
}
enum class OsrSourceTier {
kInterpreter,
kBaseline,
};
void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
Register current_loop_depth,
Register encoded_current_bytecode_offset,
Register osr_urgency_and_install_target) {
static constexpr Register scratch = r3;
DCHECK(!AreAliased(scratch, current_loop_depth,
encoded_current_bytecode_offset,
osr_urgency_and_install_target));
// OSR based on urgency, i.e. is the OSR urgency greater than the current
// loop depth?
Label try_osr;
STATIC_ASSERT(BytecodeArray::OsrUrgencyBits::kShift == 0);
Register urgency = scratch;
__ and_(urgency, osr_urgency_and_install_target,
Operand(BytecodeArray::OsrUrgencyBits::kMask));
__ cmp(urgency, current_loop_depth);
__ b(hi, &try_osr);
// OSR based on the install target offset, i.e. does the current bytecode
// offset match the install target offset?
static constexpr int kMask = BytecodeArray::OsrInstallTargetBits::kMask;
Register install_target = osr_urgency_and_install_target;
__ and_(install_target, osr_urgency_and_install_target, Operand(kMask));
__ cmp(install_target, encoded_current_bytecode_offset);
__ b(eq, &try_osr);
// Neither urgency nor the install target triggered, return to the caller.
// Note: the return value must be nullptr or a valid Code object.
__ Move(r0, Operand(0));
__ Ret(0);
__ bind(&try_osr);
void OnStackReplacement(MacroAssembler* masm, bool is_interpreter) {
ASM_CODE_COMMENT(masm);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
@ -1868,7 +1831,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
__ bind(&skip);
if (source == OsrSourceTier::kInterpreter) {
if (is_interpreter) {
// Drop the handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
__ LeaveFrame(StackFrame::STUB);
@ -1894,24 +1857,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
return OnStackReplacement(masm, true);
}
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ ldr(kContextRegister,
MemOperand(fp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
return OnStackReplacement(masm, false);
}
// static

View File

@ -2070,44 +2070,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address,
__ Br(x17);
}
enum class OsrSourceTier {
kInterpreter,
kBaseline,
};
void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
Register current_loop_depth,
Register encoded_current_bytecode_offset,
Register osr_urgency_and_install_target) {
static constexpr Register scratch = x3;
DCHECK(!AreAliased(scratch, current_loop_depth,
encoded_current_bytecode_offset,
osr_urgency_and_install_target));
// OSR based on urgency, i.e. is the OSR urgency greater than the current
// loop depth?
Label try_osr;
STATIC_ASSERT(BytecodeArray::OsrUrgencyBits::kShift == 0);
Register urgency = scratch;
__ And(urgency, osr_urgency_and_install_target,
BytecodeArray::OsrUrgencyBits::kMask);
__ Cmp(urgency, current_loop_depth);
__ B(hi, &try_osr);
// OSR based on the install target offset, i.e. does the current bytecode
// offset match the install target offset?
static constexpr int kMask = BytecodeArray::OsrInstallTargetBits::kMask;
Register install_target = osr_urgency_and_install_target;
__ And(install_target, osr_urgency_and_install_target, Operand(kMask));
__ Cmp(install_target, encoded_current_bytecode_offset);
__ B(eq, &try_osr);
// Neither urgency nor the install target triggered, return to the caller.
// Note: the return value must be nullptr or a valid Code object.
__ Move(x0, xzr);
__ Ret();
__ bind(&try_osr);
void OnStackReplacement(MacroAssembler* masm, bool is_interpreter) {
ASM_CODE_COMMENT(masm);
{
FrameScope scope(masm, StackFrame::INTERNAL);
@ -2121,7 +2084,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
__ Bind(&skip);
if (source == OsrSourceTier::kInterpreter) {
if (is_interpreter) {
// Drop the handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
__ LeaveFrame(StackFrame::STUB);
@ -2152,24 +2115,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
return OnStackReplacement(masm, true);
}
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ ldr(kContextRegister,
MemOperand(fp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
return OnStackReplacement(masm, false);
}
// static

View File

@ -189,11 +189,11 @@ namespace internal {
InterpreterPushArgsThenConstruct) \
ASM(InterpreterEnterAtBytecode, Dummy) \
ASM(InterpreterEnterAtNextBytecode, Dummy) \
ASM(InterpreterOnStackReplacement, InterpreterOnStackReplacement) \
ASM(InterpreterOnStackReplacement, ContextOnly) \
\
/* Baseline Compiler */ \
ASM(BaselineOutOfLinePrologue, BaselineOutOfLinePrologue) \
ASM(BaselineOnStackReplacement, BaselineOnStackReplacement) \
ASM(BaselineOnStackReplacement, Void) \
ASM(BaselineLeaveFrame, BaselineLeaveFrame) \
ASM(BaselineOrInterpreterEnterAtBytecode, Void) \
ASM(BaselineOrInterpreterEnterAtNextBytecode, Void) \

View File

@ -2801,44 +2801,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address) {
__ ret(0);
}
enum class OsrSourceTier {
kInterpreter,
kBaseline,
};
void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
Register current_loop_depth,
Register encoded_current_bytecode_offset,
Register osr_urgency_and_install_target) {
static constexpr Register scratch = edi;
DCHECK(!AreAliased(scratch, current_loop_depth,
encoded_current_bytecode_offset,
osr_urgency_and_install_target));
// OSR based on urgency, i.e. is the OSR urgency greater than the current
// loop depth?
Label try_osr;
STATIC_ASSERT(BytecodeArray::OsrUrgencyBits::kShift == 0);
Register urgency = scratch;
__ Move(urgency, osr_urgency_and_install_target);
__ and_(urgency, Immediate(BytecodeArray::OsrUrgencyBits::kMask));
__ cmp(urgency, current_loop_depth);
__ j(above, &try_osr, Label::kNear);
// OSR based on the install target offset, i.e. does the current bytecode
// offset match the install target offset?
static constexpr int kMask = BytecodeArray::OsrInstallTargetBits::kMask;
Register install_target = osr_urgency_and_install_target;
__ and_(install_target, Immediate(kMask));
__ cmp(install_target, encoded_current_bytecode_offset);
__ j(equal, &try_osr, Label::kNear);
// Neither urgency nor the install target triggered, return to the caller.
// Note: the return value must be nullptr or a valid Code object.
__ Move(eax, Immediate(0));
__ ret(0);
__ bind(&try_osr);
void OnStackReplacement(MacroAssembler* masm, bool is_interpreter) {
ASM_CODE_COMMENT(masm);
{
FrameScope scope(masm, StackFrame::INTERNAL);
@ -2853,7 +2816,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
__ bind(&skip);
if (source == OsrSourceTier::kInterpreter) {
if (is_interpreter) {
// Drop the handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
__ leave();
@ -2878,24 +2841,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
return OnStackReplacement(masm, true);
}
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ mov(kContextRegister,
MemOperand(ebp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
return OnStackReplacement(masm, false);
}
#if V8_ENABLE_WEBASSEMBLY

View File

@ -2729,38 +2729,7 @@ enum class OsrSourceTier {
kBaseline,
};
void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
Register current_loop_depth,
Register encoded_current_bytecode_offset,
Register osr_urgency_and_install_target) {
DCHECK(!AreAliased(kScratchRegister, current_loop_depth,
encoded_current_bytecode_offset,
osr_urgency_and_install_target));
// OSR based on urgency, i.e. is the OSR urgency greater than the current
// loop depth?
Label try_osr;
STATIC_ASSERT(BytecodeArray::OsrUrgencyBits::kShift == 0);
Register urgency = kScratchRegister;
__ Move(urgency, osr_urgency_and_install_target);
__ andq(urgency, Immediate(BytecodeArray::OsrUrgencyBits::kMask));
__ cmpq(urgency, current_loop_depth);
__ j(above, &try_osr, Label::kNear);
// OSR based on the install target offset, i.e. does the current bytecode
// offset match the install target offset?
static constexpr int kMask = BytecodeArray::OsrInstallTargetBits::kMask;
Register install_target = osr_urgency_and_install_target;
__ andq(install_target, Immediate(kMask));
__ cmpq(install_target, encoded_current_bytecode_offset);
__ j(equal, &try_osr, Label::kNear);
// Neither urgency nor the install target triggered, return to the caller.
// Note: the return value must be nullptr or a valid Code object.
__ Move(rax, Immediate(0));
__ ret(0);
__ bind(&try_osr);
void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kCompileOptimizedOSR);
@ -2802,24 +2771,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
OnStackReplacement(masm, OsrSourceTier::kInterpreter);
}
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ movq(kContextRegister,
MemOperand(rbp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
OnStackReplacement(masm, OsrSourceTier::kBaseline);
}
#if V8_ENABLE_WEBASSEMBLY

View File

@ -356,52 +356,6 @@ constexpr auto BaselineLeaveFrameDescriptor::registers() {
#endif
}
// static
constexpr auto BaselineOnStackReplacementDescriptor::registers() {
return DefaultRegisterArray();
}
// static
constexpr Register
BaselineOnStackReplacementDescriptor::CurrentLoopDepthRegister() {
return registers()[0];
}
// static
constexpr Register
BaselineOnStackReplacementDescriptor::EncodedCurrentBytecodeOffsetRegister() {
return registers()[1];
}
// static
constexpr Register
BaselineOnStackReplacementDescriptor::OsrUrgencyAndInstallTargetRegister() {
return registers()[2];
}
// static
constexpr auto InterpreterOnStackReplacementDescriptor::registers() {
using BaselineD = BaselineOnStackReplacementDescriptor;
return BaselineD::registers();
}
// static
constexpr Register
InterpreterOnStackReplacementDescriptor::CurrentLoopDepthRegister() {
using BaselineD = BaselineOnStackReplacementDescriptor;
return BaselineD::CurrentLoopDepthRegister();
}
// static
constexpr Register InterpreterOnStackReplacementDescriptor::
EncodedCurrentBytecodeOffsetRegister() {
using BaselineD = BaselineOnStackReplacementDescriptor;
return BaselineD::EncodedCurrentBytecodeOffsetRegister();
}
// static
constexpr Register
InterpreterOnStackReplacementDescriptor::OsrUrgencyAndInstallTargetRegister() {
using BaselineD = BaselineOnStackReplacementDescriptor;
return BaselineD::OsrUrgencyAndInstallTargetRegister();
}
// static
constexpr auto VoidDescriptor::registers() { return RegisterArray(); }

View File

@ -31,17 +31,16 @@ namespace internal {
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
V(AsyncFunctionStackParameter) \
V(BaselineLeaveFrame) \
V(BaselineOnStackReplacement) \
V(BaselineOutOfLinePrologue) \
V(BigIntToI32Pair) \
V(BigIntToI64) \
V(BinaryOp) \
V(BinaryOp_Baseline) \
V(BinaryOp_WithFeedback) \
V(BinarySmiOp_Baseline) \
V(BinaryOp_WithFeedback) \
V(CallForwardVarargs) \
V(CallFunctionTemplate) \
V(CopyDataPropertiesWithExcludedProperties) \
V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
V(CallTrampoline) \
V(CallTrampoline_Baseline) \
V(CallTrampoline_Baseline_Compact) \
@ -58,19 +57,17 @@ namespace internal {
V(Compare) \
V(Compare_Baseline) \
V(Compare_WithFeedback) \
V(Construct_Baseline) \
V(ConstructForwardVarargs) \
V(ConstructStub) \
V(ConstructVarargs) \
V(ConstructWithArrayLike) \
V(ConstructWithArrayLike_WithFeedback) \
V(Construct_WithFeedback) \
V(Construct_Baseline) \
V(ConstructWithSpread) \
V(ConstructWithSpread_Baseline) \
V(ConstructWithSpread_WithFeedback) \
V(ContextOnly) \
V(CopyDataPropertiesWithExcludedProperties) \
V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
V(CppBuiltinAdaptor) \
V(FastNewObject) \
V(ForInPrepare) \
@ -82,15 +79,11 @@ namespace internal {
V(InterpreterCEntry1) \
V(InterpreterCEntry2) \
V(InterpreterDispatch) \
V(InterpreterOnStackReplacement) \
V(InterpreterPushArgsThenCall) \
V(InterpreterPushArgsThenConstruct) \
V(JSTrampoline) \
V(KeyedHasICBaseline) \
V(KeyedHasICWithVector) \
V(KeyedLoad) \
V(KeyedLoadBaseline) \
V(KeyedLoadWithVector) \
V(BaselineOutOfLinePrologue) \
V(BaselineLeaveFrame) \
V(Load) \
V(LoadBaseline) \
V(LoadGlobal) \
@ -98,12 +91,18 @@ namespace internal {
V(LoadGlobalNoFeedback) \
V(LoadGlobalWithVector) \
V(LoadNoFeedback) \
V(LoadWithVector) \
V(KeyedLoad) \
V(KeyedLoadBaseline) \
V(KeyedLoadWithVector) \
V(KeyedHasICBaseline) \
V(KeyedHasICWithVector) \
V(LoadWithReceiverAndVector) \
V(LoadWithReceiverBaseline) \
V(LoadWithVector) \
V(LookupBaseline) \
V(NoContext) \
V(ResumeGenerator) \
V(SuspendGeneratorBaseline) \
V(ResumeGeneratorBaseline) \
V(RunMicrotasks) \
V(RunMicrotasksEntry) \
@ -117,10 +116,11 @@ namespace internal {
V(StoreWithVector) \
V(StringAtAsString) \
V(StringSubstring) \
V(SuspendGeneratorBaseline) \
IF_TSAN(V, TSANStore) \
IF_TSAN(V, TSANLoad) \
V(TypeConversion) \
V(TypeConversion_Baseline) \
V(TypeConversionNoContext) \
V(TypeConversion_Baseline) \
V(Typeof) \
V(UnaryOp_Baseline) \
V(UnaryOp_WithFeedback) \
@ -131,8 +131,6 @@ namespace internal {
V(WasmI64AtomicWait32) \
V(WasmSuspend) \
V(WriteBarrier) \
IF_TSAN(V, TSANLoad) \
IF_TSAN(V, TSANStore) \
BUILTIN_LIST_TFS(V) \
TORQUE_BUILTIN_LIST_TFC(V)
@ -1690,42 +1688,6 @@ class BaselineLeaveFrameDescriptor
static constexpr inline auto registers();
};
class InterpreterOnStackReplacementDescriptor
: public StaticCallInterfaceDescriptor<
InterpreterOnStackReplacementDescriptor> {
public:
DEFINE_PARAMETERS(kCurrentLoopDepth, kEncodedCurrentBytecodeOffset,
kOsrUrgencyAndInstallTarget)
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kCurrentLoopDepth
MachineType::Int32(), // kEncodedCurrentBytecodeOffset
MachineType::Int32()) // kOsrUrgencyAndInstallTarget
DECLARE_DESCRIPTOR(InterpreterOnStackReplacementDescriptor)
static constexpr inline Register CurrentLoopDepthRegister();
static constexpr inline Register EncodedCurrentBytecodeOffsetRegister();
static constexpr inline Register OsrUrgencyAndInstallTargetRegister();
static constexpr inline auto registers();
};
class BaselineOnStackReplacementDescriptor
: public StaticCallInterfaceDescriptor<
BaselineOnStackReplacementDescriptor> {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kCurrentLoopDepth, kEncodedCurrentBytecodeOffset,
kOsrUrgencyAndInstallTarget)
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kCurrentLoopDepth
MachineType::Int32(), // kEncodedCurrentBytecodeOffset
MachineType::Int32()) // kOsrUrgencyAndInstallTarget
DECLARE_DESCRIPTOR(BaselineOnStackReplacementDescriptor)
static constexpr inline Register CurrentLoopDepthRegister();
static constexpr inline Register EncodedCurrentBytecodeOffsetRegister();
static constexpr inline Register OsrUrgencyAndInstallTargetRegister();
static constexpr inline auto registers();
};
class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
: public StaticCallInterfaceDescriptor<InterpreterDispatchDescriptor> {
public:

View File

@ -19,17 +19,18 @@ constexpr bool ShouldPadArguments(int argument_count) {
return ArgumentPaddingSlots(argument_count) != 0;
}
#ifdef DEBUG
template <typename... RegTypes,
// All arguments must be either Register or DoubleRegister.
typename = typename std::enable_if_t<
std::conjunction_v<std::is_same<Register, RegTypes>...> ||
std::conjunction_v<std::is_same<DoubleRegister, RegTypes>...>>>
inline constexpr bool AreAliased(RegTypes... regs) {
using FirstRegType = std::tuple_element_t<0, std::tuple<RegTypes...>>;
int num_different_regs = RegListBase<FirstRegType>{regs...}.Count();
int num_different_regs = RegListBase{regs...}.Count();
int num_given_regs = (... + (regs.is_valid() ? 1 : 0));
return num_different_regs < num_given_regs;
}
#endif
} // namespace internal
} // namespace v8

View File

@ -1339,39 +1339,19 @@ void InterpreterAssembler::AbortIfWordNotEqual(TNode<WordT> lhs,
BIND(&ok);
}
void InterpreterAssembler::OnStackReplacement(
TNode<Context> context, TNode<IntPtrT> relative_jump,
TNode<Int32T> loop_depth, TNode<Int16T> osr_urgency_and_install_target) {
Label interpreter(this), baseline(this);
{
TNode<JSFunction> function =
CAST(LoadRegister(Register::function_closure()));
TNode<HeapObject> shared_info = LoadJSFunctionSharedFunctionInfo(function);
TNode<Object> sfi_data =
LoadObjectField(shared_info, SharedFunctionInfo::kFunctionDataOffset);
TNode<Uint16T> data_type = LoadInstanceType(CAST(sfi_data));
Branch(InstanceTypeEqual(data_type, CODET_TYPE), &baseline, &interpreter);
}
void InterpreterAssembler::OnStackReplacement(TNode<Context> context,
TNode<IntPtrT> relative_jump) {
TNode<JSFunction> function = CAST(LoadRegister(Register::function_closure()));
TNode<HeapObject> shared_info = LoadJSFunctionSharedFunctionInfo(function);
TNode<Object> sfi_data =
LoadObjectField(shared_info, SharedFunctionInfo::kFunctionDataOffset);
TNode<Uint16T> data_type = LoadInstanceType(CAST(sfi_data));
BIND(&interpreter);
Label baseline(this);
GotoIf(InstanceTypeEqual(data_type, CODET_TYPE), &baseline);
{
// Encode the current bytecode offset as
//
// BytecodeArray::OsrInstallTargetFor(
// BytecodeOffset{iterator().current_offset()})
// << BytecodeArray::OsrInstallTargetBits::kShift
static constexpr int kShift = BytecodeArray::OsrInstallTargetBits::kShift;
static constexpr int kMask = BytecodeArray::OsrInstallTargetBits::kMask;
TNode<Word32T> encoded_bytecode_offset = Word32Or(
Int32Sub(TruncateIntPtrToInt32(BytecodeOffset()), kFirstBytecodeOffset),
Int32Constant(1));
encoded_bytecode_offset = Word32And(
Word32Shl(UncheckedCast<Int32T>(encoded_bytecode_offset), kShift),
kMask);
Callable callable = CodeFactory::InterpreterOnStackReplacement(isolate());
CallStub(callable, context, loop_depth, encoded_bytecode_offset,
osr_urgency_and_install_target);
CallStub(callable, context);
JumpBackward(relative_jump);
}

View File

@ -263,12 +263,8 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
TNode<FixedArrayBase> parameters_and_registers,
TNode<IntPtrT> formal_parameter_count, TNode<UintPtrT> register_count);
// Attempts to OSR; note this may fail in some cases, e.g. on a mismatched
// install target, or if there's no compiled code object available yet
// (concurrent OSR).
void OnStackReplacement(TNode<Context> context, TNode<IntPtrT> relative_jump,
TNode<Int32T> loop_depth,
TNode<Int16T> osr_urgency_and_install_target);
// Perform OnStackReplacement.
void OnStackReplacement(TNode<Context> context, TNode<IntPtrT> relative_jump);
// The BytecodeOffset() is the offset from the ByteCodeArray pointer; to
// translate into runtime `BytecodeOffset` (defined in utils.h as the offset

View File

@ -2173,7 +2173,7 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
// OSR requests can be triggered either through urgency (when > the current
// loop depth), or an explicit install target (= the lower bits of the
// targeted bytecode offset).
Label ok(this), maybe_osr(this);
Label ok(this), maybe_osr(this, Label::kDeferred);
Branch(Int32GreaterThanOrEqual(loop_depth, osr_urgency_and_install_target),
&ok, &maybe_osr);
@ -2183,8 +2183,30 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
JumpBackward(relative_jump);
BIND(&maybe_osr);
OnStackReplacement(context, relative_jump, loop_depth,
osr_urgency_and_install_target);
Label osr(this);
// OSR based on urgency, i.e. is the OSR urgency greater than the current
// loop depth?
STATIC_ASSERT(BytecodeArray::OsrUrgencyBits::kShift == 0);
TNode<Word32T> osr_urgency = Word32And(osr_urgency_and_install_target,
BytecodeArray::OsrUrgencyBits::kMask);
GotoIf(Int32GreaterThan(osr_urgency, loop_depth), &osr);
// OSR based on the install target offset, i.e. does the current bytecode
// offset match the install target offset?
//
// if (((offset << kShift) & kMask) == (target & kMask)) { ... }
static constexpr int kShift = BytecodeArray::OsrInstallTargetBits::kShift;
static constexpr int kMask = BytecodeArray::OsrInstallTargetBits::kMask;
// Note: We OR in 1 to avoid 0 offsets, see Code::OsrInstallTargetFor.
TNode<Word32T> actual = Word32Or(
Int32Sub(TruncateIntPtrToInt32(BytecodeOffset()), kFirstBytecodeOffset),
Int32Constant(1));
actual = Word32And(Word32Shl(UncheckedCast<Int32T>(actual), kShift), kMask);
TNode<Word32T> expected = Word32And(osr_urgency_and_install_target, kMask);
Branch(Word32Equal(actual, expected), &osr, &ok);
BIND(&osr);
OnStackReplacement(context, relative_jump);
}
// SwitchOnSmiNoFeedback <table_start> <table_length> <case_value_base>