Commit af1fa286 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by V8 LUCI CQ

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

This reverts commit a4216b7b.

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}
parent f4789953
...@@ -1925,30 +1925,50 @@ void BaselineCompiler::VisitCreateRestParameter() { ...@@ -1925,30 +1925,50 @@ void BaselineCompiler::VisitCreateRestParameter() {
} }
void BaselineCompiler::VisitJumpLoop() { 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"); 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, __ LoadRegister(osr_urgency_and_install_target,
interpreter::Register::bytecode_array()); interpreter::Register::bytecode_array());
__ LoadWord16FieldZeroExtend( __ LoadWord16FieldZeroExtend(
osr_urgency_and_install_target, osr_urgency_and_install_target, osr_urgency_and_install_target, osr_urgency_and_install_target,
BytecodeArray::kOsrUrgencyAndInstallTargetOffset); BytecodeArray::kOsrUrgencyAndInstallTargetOffset);
const int loop_depth = iterator().GetImmediateOperand(1); int loop_depth = iterator().GetImmediateOperand(1);
__ JumpIfImmediate(Condition::kUnsignedLessThanEqual, __ JumpIfImmediate(Condition::kUnsignedLessThanEqual,
osr_urgency_and_install_target, loop_depth, osr_urgency_and_install_target, loop_depth,
&osr_not_armed, Label::kNear); &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 = const int encoded_current_offset =
BytecodeArray::OsrInstallTargetFor( BytecodeArray::OsrInstallTargetFor(
BytecodeOffset{iterator().current_offset()}) BytecodeOffset{iterator().current_offset()})
<< BytecodeArray::OsrInstallTargetBits::kShift; << kShift;
CallBuiltin<Builtin::kBaselineOnStackReplacement>( __ Word32And(scratch2, osr_urgency_and_install_target, kMask);
loop_depth, encoded_current_offset, osr_urgency_and_install_target); __ JumpIfImmediate(Condition::kNotEqual, scratch2, encoded_current_offset,
&osr_not_armed, Label::kNear);
} }
__ Bind(&osr);
CallBuiltin<Builtin::kBaselineOnStackReplacement>();
__ Bind(&osr_not_armed); __ Bind(&osr_not_armed);
Label* label = &labels_[iterator().GetJumpTargetOffset()]->unlinked; Label* label = &labels_[iterator().GetJumpTargetOffset()]->unlinked;
int weight = iterator().GetRelativeJumpTargetOffset() - int weight = iterator().GetRelativeJumpTargetOffset() -
......
...@@ -1816,44 +1816,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address, ...@@ -1816,44 +1816,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address,
__ Ret(); __ Ret();
} }
enum class OsrSourceTier { void OnStackReplacement(MacroAssembler* masm, bool is_interpreter) {
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);
ASM_CODE_COMMENT(masm); ASM_CODE_COMMENT(masm);
{ {
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
...@@ -1868,7 +1831,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, ...@@ -1868,7 +1831,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
__ bind(&skip); __ bind(&skip);
if (source == OsrSourceTier::kInterpreter) { if (is_interpreter) {
// Drop the handler frame that is be sitting on top of the actual // 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. // JavaScript frame. This is the case then OSR is triggered from bytecode.
__ LeaveFrame(StackFrame::STUB); __ LeaveFrame(StackFrame::STUB);
...@@ -1894,24 +1857,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, ...@@ -1894,24 +1857,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace } // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor; return OnStackReplacement(masm, true);
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ ldr(kContextRegister, __ ldr(kContextRegister,
MemOperand(fp, BaselineFrameConstants::kContextOffset)); MemOperand(fp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline, return OnStackReplacement(masm, false);
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
// static // static
......
...@@ -2070,44 +2070,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address, ...@@ -2070,44 +2070,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address,
__ Br(x17); __ Br(x17);
} }
enum class OsrSourceTier { void OnStackReplacement(MacroAssembler* masm, bool is_interpreter) {
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);
ASM_CODE_COMMENT(masm); ASM_CODE_COMMENT(masm);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
...@@ -2121,7 +2084,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, ...@@ -2121,7 +2084,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
__ Bind(&skip); __ Bind(&skip);
if (source == OsrSourceTier::kInterpreter) { if (is_interpreter) {
// Drop the handler frame that is be sitting on top of the actual // 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. // JavaScript frame. This is the case then OSR is triggered from bytecode.
__ LeaveFrame(StackFrame::STUB); __ LeaveFrame(StackFrame::STUB);
...@@ -2152,24 +2115,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, ...@@ -2152,24 +2115,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace } // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor; return OnStackReplacement(masm, true);
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ ldr(kContextRegister, __ ldr(kContextRegister,
MemOperand(fp, BaselineFrameConstants::kContextOffset)); MemOperand(fp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline, return OnStackReplacement(masm, false);
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
// static // static
......
...@@ -189,11 +189,11 @@ namespace internal { ...@@ -189,11 +189,11 @@ namespace internal {
InterpreterPushArgsThenConstruct) \ InterpreterPushArgsThenConstruct) \
ASM(InterpreterEnterAtBytecode, Dummy) \ ASM(InterpreterEnterAtBytecode, Dummy) \
ASM(InterpreterEnterAtNextBytecode, Dummy) \ ASM(InterpreterEnterAtNextBytecode, Dummy) \
ASM(InterpreterOnStackReplacement, InterpreterOnStackReplacement) \ ASM(InterpreterOnStackReplacement, ContextOnly) \
\ \
/* Baseline Compiler */ \ /* Baseline Compiler */ \
ASM(BaselineOutOfLinePrologue, BaselineOutOfLinePrologue) \ ASM(BaselineOutOfLinePrologue, BaselineOutOfLinePrologue) \
ASM(BaselineOnStackReplacement, BaselineOnStackReplacement) \ ASM(BaselineOnStackReplacement, Void) \
ASM(BaselineLeaveFrame, BaselineLeaveFrame) \ ASM(BaselineLeaveFrame, BaselineLeaveFrame) \
ASM(BaselineOrInterpreterEnterAtBytecode, Void) \ ASM(BaselineOrInterpreterEnterAtBytecode, Void) \
ASM(BaselineOrInterpreterEnterAtNextBytecode, Void) \ ASM(BaselineOrInterpreterEnterAtNextBytecode, Void) \
......
...@@ -2801,44 +2801,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address) { ...@@ -2801,44 +2801,7 @@ void Generate_OSREntry(MacroAssembler* masm, Register entry_address) {
__ ret(0); __ ret(0);
} }
enum class OsrSourceTier { void OnStackReplacement(MacroAssembler* masm, bool is_interpreter) {
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);
ASM_CODE_COMMENT(masm); ASM_CODE_COMMENT(masm);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
...@@ -2853,7 +2816,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, ...@@ -2853,7 +2816,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
__ bind(&skip); __ bind(&skip);
if (source == OsrSourceTier::kInterpreter) { if (is_interpreter) {
// Drop the handler frame that is be sitting on top of the actual // 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. // JavaScript frame. This is the case then OSR is triggered from bytecode.
__ leave(); __ leave();
...@@ -2878,24 +2841,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, ...@@ -2878,24 +2841,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace } // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor; return OnStackReplacement(masm, true);
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ mov(kContextRegister, __ mov(kContextRegister,
MemOperand(ebp, BaselineFrameConstants::kContextOffset)); MemOperand(ebp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline, return OnStackReplacement(masm, false);
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
......
...@@ -2729,38 +2729,7 @@ enum class OsrSourceTier { ...@@ -2729,38 +2729,7 @@ enum class OsrSourceTier {
kBaseline, kBaseline,
}; };
void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, 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);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kCompileOptimizedOSR); __ CallRuntime(Runtime::kCompileOptimizedOSR);
...@@ -2802,24 +2771,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source, ...@@ -2802,24 +2771,13 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
} // namespace } // namespace
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
using D = InterpreterOnStackReplacementDescriptor; OnStackReplacement(masm, OsrSourceTier::kInterpreter);
STATIC_ASSERT(D::kParameterCount == 3);
OnStackReplacement(masm, OsrSourceTier::kInterpreter,
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) { void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
using D = BaselineOnStackReplacementDescriptor;
STATIC_ASSERT(D::kParameterCount == 3);
__ movq(kContextRegister, __ movq(kContextRegister,
MemOperand(rbp, BaselineFrameConstants::kContextOffset)); MemOperand(rbp, BaselineFrameConstants::kContextOffset));
OnStackReplacement(masm, OsrSourceTier::kBaseline, OnStackReplacement(masm, OsrSourceTier::kBaseline);
D::CurrentLoopDepthRegister(),
D::EncodedCurrentBytecodeOffsetRegister(),
D::OsrUrgencyAndInstallTargetRegister());
} }
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
......
...@@ -356,52 +356,6 @@ constexpr auto BaselineLeaveFrameDescriptor::registers() { ...@@ -356,52 +356,6 @@ constexpr auto BaselineLeaveFrameDescriptor::registers() {
#endif #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 // static
constexpr auto VoidDescriptor::registers() { return RegisterArray(); } constexpr auto VoidDescriptor::registers() { return RegisterArray(); }
......
...@@ -31,17 +31,16 @@ namespace internal { ...@@ -31,17 +31,16 @@ namespace internal {
V(ArrayNoArgumentConstructor) \ V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \ V(ArraySingleArgumentConstructor) \
V(AsyncFunctionStackParameter) \ V(AsyncFunctionStackParameter) \
V(BaselineLeaveFrame) \
V(BaselineOnStackReplacement) \
V(BaselineOutOfLinePrologue) \
V(BigIntToI32Pair) \ V(BigIntToI32Pair) \
V(BigIntToI64) \ V(BigIntToI64) \
V(BinaryOp) \ V(BinaryOp) \
V(BinaryOp_Baseline) \ V(BinaryOp_Baseline) \
V(BinaryOp_WithFeedback) \
V(BinarySmiOp_Baseline) \ V(BinarySmiOp_Baseline) \
V(BinaryOp_WithFeedback) \
V(CallForwardVarargs) \ V(CallForwardVarargs) \
V(CallFunctionTemplate) \ V(CallFunctionTemplate) \
V(CopyDataPropertiesWithExcludedProperties) \
V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
V(CallTrampoline) \ V(CallTrampoline) \
V(CallTrampoline_Baseline) \ V(CallTrampoline_Baseline) \
V(CallTrampoline_Baseline_Compact) \ V(CallTrampoline_Baseline_Compact) \
...@@ -58,19 +57,17 @@ namespace internal { ...@@ -58,19 +57,17 @@ namespace internal {
V(Compare) \ V(Compare) \
V(Compare_Baseline) \ V(Compare_Baseline) \
V(Compare_WithFeedback) \ V(Compare_WithFeedback) \
V(Construct_Baseline) \
V(ConstructForwardVarargs) \ V(ConstructForwardVarargs) \
V(ConstructStub) \ V(ConstructStub) \
V(ConstructVarargs) \ V(ConstructVarargs) \
V(ConstructWithArrayLike) \ V(ConstructWithArrayLike) \
V(ConstructWithArrayLike_WithFeedback) \ V(ConstructWithArrayLike_WithFeedback) \
V(Construct_WithFeedback) \ V(Construct_WithFeedback) \
V(Construct_Baseline) \
V(ConstructWithSpread) \ V(ConstructWithSpread) \
V(ConstructWithSpread_Baseline) \ V(ConstructWithSpread_Baseline) \
V(ConstructWithSpread_WithFeedback) \ V(ConstructWithSpread_WithFeedback) \
V(ContextOnly) \ V(ContextOnly) \
V(CopyDataPropertiesWithExcludedProperties) \
V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
V(CppBuiltinAdaptor) \ V(CppBuiltinAdaptor) \
V(FastNewObject) \ V(FastNewObject) \
V(ForInPrepare) \ V(ForInPrepare) \
...@@ -82,15 +79,11 @@ namespace internal { ...@@ -82,15 +79,11 @@ namespace internal {
V(InterpreterCEntry1) \ V(InterpreterCEntry1) \
V(InterpreterCEntry2) \ V(InterpreterCEntry2) \
V(InterpreterDispatch) \ V(InterpreterDispatch) \
V(InterpreterOnStackReplacement) \
V(InterpreterPushArgsThenCall) \ V(InterpreterPushArgsThenCall) \
V(InterpreterPushArgsThenConstruct) \ V(InterpreterPushArgsThenConstruct) \
V(JSTrampoline) \ V(JSTrampoline) \
V(KeyedHasICBaseline) \ V(BaselineOutOfLinePrologue) \
V(KeyedHasICWithVector) \ V(BaselineLeaveFrame) \
V(KeyedLoad) \
V(KeyedLoadBaseline) \
V(KeyedLoadWithVector) \
V(Load) \ V(Load) \
V(LoadBaseline) \ V(LoadBaseline) \
V(LoadGlobal) \ V(LoadGlobal) \
...@@ -98,12 +91,18 @@ namespace internal { ...@@ -98,12 +91,18 @@ namespace internal {
V(LoadGlobalNoFeedback) \ V(LoadGlobalNoFeedback) \
V(LoadGlobalWithVector) \ V(LoadGlobalWithVector) \
V(LoadNoFeedback) \ V(LoadNoFeedback) \
V(LoadWithVector) \
V(KeyedLoad) \
V(KeyedLoadBaseline) \
V(KeyedLoadWithVector) \
V(KeyedHasICBaseline) \
V(KeyedHasICWithVector) \
V(LoadWithReceiverAndVector) \ V(LoadWithReceiverAndVector) \
V(LoadWithReceiverBaseline) \ V(LoadWithReceiverBaseline) \
V(LoadWithVector) \
V(LookupBaseline) \ V(LookupBaseline) \
V(NoContext) \ V(NoContext) \
V(ResumeGenerator) \ V(ResumeGenerator) \
V(SuspendGeneratorBaseline) \
V(ResumeGeneratorBaseline) \ V(ResumeGeneratorBaseline) \
V(RunMicrotasks) \ V(RunMicrotasks) \
V(RunMicrotasksEntry) \ V(RunMicrotasksEntry) \
...@@ -117,10 +116,11 @@ namespace internal { ...@@ -117,10 +116,11 @@ namespace internal {
V(StoreWithVector) \ V(StoreWithVector) \
V(StringAtAsString) \ V(StringAtAsString) \
V(StringSubstring) \ V(StringSubstring) \
V(SuspendGeneratorBaseline) \ IF_TSAN(V, TSANStore) \
IF_TSAN(V, TSANLoad) \
V(TypeConversion) \ V(TypeConversion) \
V(TypeConversion_Baseline) \
V(TypeConversionNoContext) \ V(TypeConversionNoContext) \
V(TypeConversion_Baseline) \
V(Typeof) \ V(Typeof) \
V(UnaryOp_Baseline) \ V(UnaryOp_Baseline) \
V(UnaryOp_WithFeedback) \ V(UnaryOp_WithFeedback) \
...@@ -131,8 +131,6 @@ namespace internal { ...@@ -131,8 +131,6 @@ namespace internal {
V(WasmI64AtomicWait32) \ V(WasmI64AtomicWait32) \
V(WasmSuspend) \ V(WasmSuspend) \
V(WriteBarrier) \ V(WriteBarrier) \
IF_TSAN(V, TSANLoad) \
IF_TSAN(V, TSANStore) \
BUILTIN_LIST_TFS(V) \ BUILTIN_LIST_TFS(V) \
TORQUE_BUILTIN_LIST_TFC(V) TORQUE_BUILTIN_LIST_TFC(V)
...@@ -1690,42 +1688,6 @@ class BaselineLeaveFrameDescriptor ...@@ -1690,42 +1688,6 @@ class BaselineLeaveFrameDescriptor
static constexpr inline auto registers(); 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 class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
: public StaticCallInterfaceDescriptor<InterpreterDispatchDescriptor> { : public StaticCallInterfaceDescriptor<InterpreterDispatchDescriptor> {
public: public:
......
...@@ -19,17 +19,18 @@ constexpr bool ShouldPadArguments(int argument_count) { ...@@ -19,17 +19,18 @@ constexpr bool ShouldPadArguments(int argument_count) {
return ArgumentPaddingSlots(argument_count) != 0; return ArgumentPaddingSlots(argument_count) != 0;
} }
#ifdef DEBUG
template <typename... RegTypes, template <typename... RegTypes,
// All arguments must be either Register or DoubleRegister. // All arguments must be either Register or DoubleRegister.
typename = typename std::enable_if_t< typename = typename std::enable_if_t<
std::conjunction_v<std::is_same<Register, RegTypes>...> || std::conjunction_v<std::is_same<Register, RegTypes>...> ||
std::conjunction_v<std::is_same<DoubleRegister, RegTypes>...>>> std::conjunction_v<std::is_same<DoubleRegister, RegTypes>...>>>
inline constexpr bool AreAliased(RegTypes... regs) { inline constexpr bool AreAliased(RegTypes... regs) {
using FirstRegType = std::tuple_element_t<0, std::tuple<RegTypes...>>; int num_different_regs = RegListBase{regs...}.Count();
int num_different_regs = RegListBase<FirstRegType>{regs...}.Count();
int num_given_regs = (... + (regs.is_valid() ? 1 : 0)); int num_given_regs = (... + (regs.is_valid() ? 1 : 0));
return num_different_regs < num_given_regs; return num_different_regs < num_given_regs;
} }
#endif
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -1339,39 +1339,19 @@ void InterpreterAssembler::AbortIfWordNotEqual(TNode<WordT> lhs, ...@@ -1339,39 +1339,19 @@ void InterpreterAssembler::AbortIfWordNotEqual(TNode<WordT> lhs,
BIND(&ok); BIND(&ok);
} }
void InterpreterAssembler::OnStackReplacement( void InterpreterAssembler::OnStackReplacement(TNode<Context> context,
TNode<Context> context, TNode<IntPtrT> relative_jump, TNode<IntPtrT> relative_jump) {
TNode<Int32T> loop_depth, TNode<Int16T> osr_urgency_and_install_target) { TNode<JSFunction> function = CAST(LoadRegister(Register::function_closure()));
Label interpreter(this), baseline(this);
{
TNode<JSFunction> function =
CAST(LoadRegister(Register::function_closure()));
TNode<HeapObject> shared_info = LoadJSFunctionSharedFunctionInfo(function); TNode<HeapObject> shared_info = LoadJSFunctionSharedFunctionInfo(function);
TNode<Object> sfi_data = TNode<Object> sfi_data =
LoadObjectField(shared_info, SharedFunctionInfo::kFunctionDataOffset); LoadObjectField(shared_info, SharedFunctionInfo::kFunctionDataOffset);
TNode<Uint16T> data_type = LoadInstanceType(CAST(sfi_data)); TNode<Uint16T> data_type = LoadInstanceType(CAST(sfi_data));
Branch(InstanceTypeEqual(data_type, CODET_TYPE), &baseline, &interpreter);
}
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()); Callable callable = CodeFactory::InterpreterOnStackReplacement(isolate());
CallStub(callable, context, loop_depth, encoded_bytecode_offset, CallStub(callable, context);
osr_urgency_and_install_target);
JumpBackward(relative_jump); JumpBackward(relative_jump);
} }
......
...@@ -263,12 +263,8 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { ...@@ -263,12 +263,8 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
TNode<FixedArrayBase> parameters_and_registers, TNode<FixedArrayBase> parameters_and_registers,
TNode<IntPtrT> formal_parameter_count, TNode<UintPtrT> register_count); TNode<IntPtrT> formal_parameter_count, TNode<UintPtrT> register_count);
// Attempts to OSR; note this may fail in some cases, e.g. on a mismatched // Perform OnStackReplacement.
// install target, or if there's no compiled code object available yet void OnStackReplacement(TNode<Context> context, TNode<IntPtrT> relative_jump);
// (concurrent OSR).
void OnStackReplacement(TNode<Context> context, TNode<IntPtrT> relative_jump,
TNode<Int32T> loop_depth,
TNode<Int16T> osr_urgency_and_install_target);
// The BytecodeOffset() is the offset from the ByteCodeArray pointer; to // The BytecodeOffset() is the offset from the ByteCodeArray pointer; to
// translate into runtime `BytecodeOffset` (defined in utils.h as the offset // translate into runtime `BytecodeOffset` (defined in utils.h as the offset
......
...@@ -2173,7 +2173,7 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) { ...@@ -2173,7 +2173,7 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
// OSR requests can be triggered either through urgency (when > the current // OSR requests can be triggered either through urgency (when > the current
// loop depth), or an explicit install target (= the lower bits of the // loop depth), or an explicit install target (= the lower bits of the
// targeted bytecode offset). // 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), Branch(Int32GreaterThanOrEqual(loop_depth, osr_urgency_and_install_target),
&ok, &maybe_osr); &ok, &maybe_osr);
...@@ -2183,8 +2183,30 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) { ...@@ -2183,8 +2183,30 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
JumpBackward(relative_jump); JumpBackward(relative_jump);
BIND(&maybe_osr); BIND(&maybe_osr);
OnStackReplacement(context, relative_jump, loop_depth, Label osr(this);
osr_urgency_and_install_target); // 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> // SwitchOnSmiNoFeedback <table_start> <table_length> <case_value_base>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment