Modified: trunk/Source/_javascript_Core/ChangeLog (292766 => 292767)
--- trunk/Source/_javascript_Core/ChangeLog 2022-04-12 06:49:21 UTC (rev 292766)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-04-12 07:51:30 UTC (rev 292767)
@@ -1,3 +1,31 @@
+2022-04-12 Geza Lore <[email protected]>
+
+ [JSC] Reduce Baseline JIT code size in debug builds
+ https://bugs.webkit.org/show_bug.cgi?id=238928
+
+ Reviewed by Saam Barati.
+
+ The Baseline JIT used to emit a substantial but identical sequence to
+ check pinned registers and the SP at the beginning of every bytecode.
+ This caused large code bloat and made it somewhat difficult to use
+ debug builds on resource constrained platforms. Trying to alleviate
+ this by emitting a small dispatcher after the slow path section (but
+ before the stack overflow check), which then tail-calls a shared
+ thunk. The opcodes then call this very small dispatcher. The source op
+ of a faulting bytecode is easily visible in the link register (or on
+ the stack on x86).
+
+ This saves 34% Baseline JIT code size (and 14% overall) on a debug
+ build with JetStream2. Also fixes all code-size related test failures
+ on the ARMv7 debug build.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::emitConsistencyCheck):
+ (JSC::JIT::compileAndLinkWithoutFinalizing):
+ (JSC::JIT::link):
+ * jit/JIT.h:
+
2022-04-11 Yusuke Suzuki <[email protected]>
[JSC] Reduce use of unnecessary cryptographicallyRandom numbers
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (292766 => 292767)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2022-04-12 06:49:21 UTC (rev 292766)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2022-04-12 07:51:30 UTC (rev 292767)
@@ -143,17 +143,6 @@
}
}
-void JIT::assertStackPointerOffset()
-{
- if (!ASSERT_ENABLED)
- return;
-
- addPtr(TrustedImm32(stackPointerOffsetFor(m_unlinkedCodeBlock) * sizeof(Register)), callFrameRegister, regT0);
- Jump ok = branchPtr(Equal, regT0, stackPointerRegister);
- breakpoint();
- ok.link(this);
-}
-
void JIT::resetSP()
{
addPtr(TrustedImm32(stackPointerOffsetFor(m_unlinkedCodeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
@@ -248,19 +237,8 @@
}
#if ASSERT_ENABLED
- if (opcodeID != op_catch) {
- loadPtr(addressFor(CallFrameSlot::codeBlock), regT0);
- loadPtr(Address(regT0, CodeBlock::offsetOfMetadataTable()), regT1);
- loadPtr(Address(regT0, CodeBlock::offsetOfBaselineJITData()), regT2);
-
- auto metadataOK = branchPtr(Equal, regT1, s_metadataGPR);
- breakpoint();
- metadataOK.link(this);
-
- auto constantsOK = branchPtr(Equal, regT2, s_constantsGPR);
- breakpoint();
- constantsOK.link(this);
- }
+ if (opcodeID != op_catch)
+ m_consistencyCheckCalls.append(nearCall());
#endif
if (UNLIKELY(m_compilation)) {
@@ -281,9 +259,6 @@
});
}
- if (opcodeID != op_catch)
- assertStackPointerOffset();
-
switch (opcodeID) {
DEFINE_SLOW_OP(less)
DEFINE_SLOW_OP(lesseq)
@@ -688,6 +663,57 @@
Base::emitRestoreCalleeSavesFor(&RegisterAtOffsetList::llintBaselineCalleeSaveRegisters());
}
+#if ASSERT_ENABLED
+MacroAssemblerCodeRef<JITThunkPtrTag> JIT::consistencyCheckGenerator(VM&)
+{
+ CCallHelpers jit;
+
+ constexpr GPRReg stackOffsetGPR = regT0; // Incoming
+ constexpr GPRReg expectedStackPointerGPR = regT1;
+ constexpr GPRReg expectedMetadataGPR = regT2;
+ constexpr GPRReg expectedConstantsGPR = regT3;
+
+ jit.tagReturnAddress();
+
+ jit.mul32(TrustedImm32(sizeof(Register)), stackOffsetGPR, stackOffsetGPR);
+ jit.subPtr(callFrameRegister, stackOffsetGPR, expectedStackPointerGPR);
+ // Fix up in case the call sequence (from the op) changed the stack pointer, e.g.: like on x86
+ if (constexpr size_t delta = sizeof(CallerFrameAndPC) - prologueStackPointerDelta())
+ jit.subPtr(TrustedImm32(delta), expectedStackPointerGPR);
+
+ jit.loadPtr(addressFor(CallFrameSlot::codeBlock), expectedConstantsGPR);
+ jit.loadPtr(Address(expectedConstantsGPR, CodeBlock::offsetOfMetadataTable()), expectedMetadataGPR);
+ jit.loadPtr(Address(expectedConstantsGPR, CodeBlock::offsetOfBaselineJITData()), expectedConstantsGPR);
+
+ auto stackPointerOK = jit.branchPtr(Equal, expectedStackPointerGPR, stackPointerRegister);
+ jit.breakpoint();
+ stackPointerOK.link(&jit);
+
+ auto metadataOK = jit.branchPtr(Equal, expectedMetadataGPR, s_metadataGPR);
+ jit.breakpoint();
+ metadataOK.link(&jit);
+
+ auto constantsOK = jit.branchPtr(Equal, expectedConstantsGPR, s_constantsGPR);
+ jit.breakpoint();
+ constantsOK.link(&jit);
+
+ jit.ret();
+
+ LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk);
+ return FINALIZE_CODE(patchBuffer, JITThunkPtrTag, "Baseline: generateConsistencyCheck");
+}
+
+void JIT::emitConsistencyCheck()
+{
+ ASSERT(!m_consistencyCheckLabel.isSet());
+ m_consistencyCheckLabel = label();
+ move(TrustedImm32(-stackPointerOffsetFor(m_unlinkedCodeBlock)), regT0);
+ m_bytecodeIndex = BytecodeIndex(0);
+ emitNakedNearTailCall(vm().getCTIStub(consistencyCheckGenerator).retaggedCode<NoPtrTag>());
+ m_bytecodeIndex = BytecodeIndex(); // Reset this, in order to guard its use with ASSERTs.
+}
+#endif
+
void JIT::compileAndLinkWithoutFinalizing(JITCompilationEffort effort)
{
DFG::CapabilityLevel level = m_profiledCodeBlock->capabilityLevel();
@@ -791,6 +817,10 @@
m_disassembler->setEndOfSlowPath(label());
m_pcToCodeOriginMapBuilder.appendItem(label(), PCToCodeOriginMapBuilder::defaultCodeOrigin());
+#if ASSERT_ENABLED
+ emitConsistencyCheck();
+#endif
+
stackOverflow.link(this);
m_bytecodeIndex = BytecodeIndex(0);
if (maxFrameExtentForSlowPathCall)
@@ -903,6 +933,12 @@
patchBuffer.link(record.from, record.callee);
}
+#if ASSERT_ENABLED
+ const auto consistencyCheck = patchBuffer.locationOf<JSInternalPtrTag>(m_consistencyCheckLabel);
+ for (auto& call : m_consistencyCheckCalls)
+ patchBuffer.link<JSInternalPtrTag>(call, consistencyCheck);
+#endif
+
auto finalizeICs = [&] (auto& generators) {
for (auto& gen : generators) {
gen.m_unlinkedStubInfo->start = patchBuffer.locationOf<JITStubRoutinePtrTag>(gen.m_start);
Modified: trunk/Source/_javascript_Core/jit/JIT.h (292766 => 292767)
--- trunk/Source/_javascript_Core/jit/JIT.h 2022-04-12 06:49:21 UTC (rev 292766)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2022-04-12 07:51:30 UTC (rev 292767)
@@ -388,8 +388,6 @@
template<typename SlowOperation>
void emit_compareAndJumpSlowImpl(VirtualRegister op1, VirtualRegister op2, unsigned target, size_t instructionSize, DoubleCondition, SlowOperation, bool invert, Vector<SlowCaseEntry>::iterator&);
- void assertStackPointerOffset();
-
void emit_op_add(const JSInstruction*);
void emit_op_bitand(const JSInstruction*);
void emit_op_bitor(const JSInstruction*);
@@ -884,6 +882,11 @@
void emitSaveCalleeSaves();
void emitRestoreCalleeSaves();
+#if ASSERT_ENABLED
+ static MacroAssemblerCodeRef<JITThunkPtrTag> consistencyCheckGenerator(VM&);
+ void emitConsistencyCheck();
+#endif
+
static bool reportCompileTimes();
static bool computeCompileTimes();
@@ -921,6 +924,10 @@
JumpList m_exceptionChecks;
JumpList m_exceptionChecksWithCallFrameRollback;
+#if ASSERT_ENABLED
+ Label m_consistencyCheckLabel;
+ Vector<Call> m_consistencyCheckCalls;
+#endif
unsigned m_getByIdIndex { UINT_MAX };
unsigned m_getByValIndex { UINT_MAX };