From 06cecbd06d9581e2b589e49b67ea0502bace8c68 Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Fri, 13 Jun 2025 12:43:36 -0700 Subject: [PATCH] Eagerly unlinking CodeBlock when jettisoning https://bugs.webkit.org/show_bug.cgi?id=294420 rdar://153246940 Reviewed by Keith Miller. Let's make CodeBlock jettisoning a bit safer. Regardless of the type of CodeBlock, when it is getting jettisoning, ensuring unlinking it from CallLinkInfo is fine. * Source/JavaScriptCore/bytecode/CodeBlock.cpp: (JSC::CodeBlock::jettison): Canonical link: https://commits.webkit.org/296207@main --- Source/JavaScriptCore/bytecode/CodeBlock.cpp | 46 ++++++++++---------- Source/JavaScriptCore/bytecode/CodeBlock.h | 7 ++- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 87bc7a31d3959..7a83aaffef6a1 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -2126,7 +2126,6 @@ CodeBlock* CodeBlock::newReplacement() return ownerExecutable()->newReplacementCodeBlockFor(specializationKind()); } -#if ENABLE(JIT) CodeBlock* CodeBlock::replacement() { const ClassInfo* classInfo = this->classInfo(); @@ -2147,6 +2146,7 @@ CodeBlock* CodeBlock::replacement() return nullptr; } +#if ENABLE(JIT) DFG::CapabilityLevel CodeBlock::computeCapabilityLevel() { const ClassInfo* classInfo = this->classInfo(); @@ -2254,10 +2254,9 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod } } } - if (DFG::shouldDumpDisassembly()) dataLog(" Did invalidate ", *this, "\n"); - + // Count the reoptimization if that's what the user wanted. if (mode == CountReoptimization) { // FIXME: Maybe this should call alternative(). @@ -2266,32 +2265,33 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod if (DFG::shouldDumpDisassembly()) dataLog(" Did count reoptimization for ", *this, "\n"); } - - if (this != replacement()) { - // This means that we were never the entrypoint. This can happen for OSR entry code - // blocks. - return; - } - - if (alternative()) - alternative()->optimizeAfterWarmUp(); - - if (reason != Profiler::JettisonDueToOldAge && reason != Profiler::JettisonDueToVMTraps) - tallyFrequentExitSites(); #endif // ENABLE(DFG_JIT) - // Jettison can happen during GC. We don't want to install code to a dead executable - // because that would add a dead object to the remembered set. - if (vm.heap.currentThreadIsDoingGCWork() && !vm.heap.isMarked(ownerExecutable())) - return; + // If this is not true, then this means that we were never the entrypoint. This can happen for OSR entry code blocks. + if (this == replacement()) { +#if ENABLE(DFG_JIT) + if (alternative()) + alternative()->optimizeAfterWarmUp(); - // This accomplishes (2). - ownerExecutable()->installCode(vm, alternative(), codeType(), specializationKind(), reason); + if (reason != Profiler::JettisonDueToOldAge && reason != Profiler::JettisonDueToVMTraps) + tallyFrequentExitSites(); +#endif // ENABLE(DFG_JIT) + // Jettison can happen during GC. We don't want to install code to a dead executable + // because that would add a dead object to the remembered set. + if (!vm.heap.currentThreadIsDoingGCWork() || vm.heap.isMarked(ownerExecutable())) { + // This accomplishes (2). + ownerExecutable()->installCode(vm, alternative(), codeType(), specializationKind(), reason); #if ENABLE(DFG_JIT) - if (DFG::shouldDumpDisassembly()) - dataLog(" Did install baseline version of ", *this, "\n"); + if (DFG::shouldDumpDisassembly()) + dataLog(" Did install baseline version of ", *this, "\n"); #endif // ENABLE(DFG_JIT) + } + } + + // Regardless of whether it is used or replaced or upgraded already or not, since this is already jettisoned, + // there is no reason to keep it linked. Unlink incoming calls. + unlinkIncomingCalls(); } JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin) diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index b97a0b031e2cf..388e557a0cb58 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -319,8 +319,9 @@ class CodeBlock : public JSCell { // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind()) CodeBlock* newReplacement(); - - void setJITCode(Ref&& code) + CodeBlock* replacement(); + + void setJITCode(Ref&& code) { if (!code->isShared()) heap()->reportExtraMemoryAllocated(code->size()); @@ -347,8 +348,6 @@ class CodeBlock : public JSCell { bool useDataIC() const; #if ENABLE(JIT) - CodeBlock* replacement(); - DFG::CapabilityLevel computeCapabilityLevel(); DFG::CapabilityLevel capabilityLevel(); DFG::CapabilityLevel capabilityLevelState() { return static_cast(m_capabilityLevelState); }