Skip to content

Commit 2d92bb7

Browse files
committed
[JSC] Remove CodeBlock::m_shouldAlwaysBeInlined
https://bugs.webkit.org/show_bug.cgi?id=326308 rdar://189155170 Reviewed by Yusuke Suzuki. The shouldAlwaysBeInlined mechanism used to prevent operationOptimize from tiering up Baseline functions that would be inlined into any hot callsite anyway. In 216705@main, BytecodeIndex became a c++ class and the check in operationOptimize, `if (bytecodeIndex)`, was broken since `bytecodeIndex` was changed from `unsigned` to the new class, which has a bool operator that returns true for bytecode index 0. The result is that operationOptimize always ignores the shouldAlwaysBeInlined flag since it thinks the bytecode index is always non-zero and interprets that to mean we're attempting to OSR from a loop, where we should override the flag. Remove the flag and the code that maintained it, including DFG::mightInlineFunction() and RecursionCheckFunctor. No behavior change aside from removing debug output for shouldAlwaysBeInlined. * Source/JavaScriptCore/bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpAssumingJITType const): (JSC::CodeBlock::CodeBlock): (JSC::CodeBlock::setupWithUnlinkedBaselineCode): (JSC::CodeBlock::numberOfDFGCompiles): (JSC::RecursionCheckFunctor::RecursionCheckFunctor): Deleted. (JSC::RecursionCheckFunctor::operator() const): Deleted. (JSC::RecursionCheckFunctor::didRecurse const): Deleted. * Source/JavaScriptCore/bytecode/CodeBlock.h: (JSC::CodeBlock::offsetOfShouldAlwaysBeInlined): Deleted. * Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::inliningCost): * Source/JavaScriptCore/interpreter/CachedCall.h: (JSC::CachedCall::unlinkOrUpgradeImpl): * Source/JavaScriptCore/interpreter/Interpreter.cpp: (JSC::Interpreter::executeCallImpl): (JSC::Interpreter::executeConstruct): (JSC::Interpreter::prepareForCachedCall): (JSC::Interpreter::prepareForMicrotaskCall): * Source/JavaScriptCore/interpreter/MicrotaskCall.cpp: (JSC::MicrotaskCall::unlinkOrUpgradeImpl): * Source/JavaScriptCore/jit/JITOperations.cpp: (JSC::JSC_DEFINE_JIT_OPERATION): * Source/JavaScriptCore/runtime/JSMicrotask.cpp: (JSC::callMicrotask): Canonical link: https://commits.webkit.org/322790@main
1 parent 1538f2b commit 2d92bb7

9 files changed

Lines changed: 0 additions & 156 deletions

File tree

‎Source/JavaScriptCore/bytecode/CodeBlock.cpp‎

Lines changed: 0 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
#include "DFGCommon.h"
4848
#include "DFGJITCode.h"
4949
#include "EvalCodeBlock.h"
50-
#include "FullCodeOrigin.h"
5150
#include "FunctionCodeBlock.h"
5251
#include "FunctionExecutableDump.h"
5352
#include "GetPutInfo.h"
@@ -80,7 +79,6 @@
8079
#include "ReduceWhitespace.h"
8180
#include "SlotVisitorInlines.h"
8281
#include "SourceProvider.h"
83-
#include "StackVisitor.h"
8482
#include "SymbolTableInlines.h"
8583
#include "TypeLocationCache.h"
8684
#include "TypeProfiler.h"
@@ -191,8 +189,6 @@ void CodeBlock::dumpAssumingJITType(PrintStream& out, JITType jitType) const
191189
if (codeType() == FunctionCode)
192190
out.print(specializationKind());
193191
out.print(", ", instructionsSize());
194-
if (this->jitType() == JITType::BaselineJIT && m_shouldAlwaysBeInlined)
195-
out.print(" (ShouldAlwaysBeInlined)");
196192
if (ownerExecutable()->neverInline())
197193
out.print(" (NeverInline)");
198194
if (ownerExecutable()->neverOptimize())
@@ -291,7 +287,6 @@ class PutToScopeFireDetail final : public FireDetail {
291287
CodeBlock::CodeBlock(VM& vm, Structure* structure, CopyParsedBlockTag, CodeBlock& other)
292288
: JSCell(vm, structure)
293289
, m_globalObject(other.m_globalObject)
294-
, m_shouldAlwaysBeInlined(true)
295290
#if ENABLE(JIT)
296291
, m_capabilityLevelState(DFG::CapabilityLevelNotSet)
297292
#endif
@@ -347,7 +342,6 @@ void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other)
347342
CodeBlock::CodeBlock(VM& vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope)
348343
: JSCell(vm, structure)
349344
, m_globalObject(scope->realm(), WriteBarrierEarlyInit)
350-
, m_shouldAlwaysBeInlined(true)
351345
#if ENABLE(JIT)
352346
, m_capabilityLevelState(DFG::CapabilityLevelNotSet)
353347
#endif
@@ -866,19 +860,6 @@ void CodeBlock::setupWithUnlinkedBaselineCode(Ref<BaselineJITCode> jitCode)
866860
optimizeAfterWarmUp();
867861
}
868862

869-
switch (codeType()) {
870-
case GlobalCode:
871-
case ModuleCode:
872-
case EvalCode:
873-
m_shouldAlwaysBeInlined = false;
874-
break;
875-
case FunctionCode:
876-
// We could have already set it to false because we detected an uninlineable call.
877-
// Don't override that observation.
878-
m_shouldAlwaysBeInlined &= canInline(capabilityLevel()) && DFG::mightInlineFunction(JITType::FTLJIT, this);
879-
break;
880-
}
881-
882863
if (jitCode->m_isShareable && !unlinkedCodeBlock()->m_unlinkedBaselineCode && Options::useBaselineJITCodeSharing())
883864
unlinkedCodeBlock()->m_unlinkedBaselineCode = WTF::move(jitCode);
884865
}
@@ -2460,117 +2441,13 @@ JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
24602441
return inlineCallFrame->baselineCodeBlock->globalObject();
24612442
}
24622443

2463-
class RecursionCheckFunctor {
2464-
public:
2465-
RecursionCheckFunctor(CallFrame* startCallFrame, CodeBlock* codeBlock, unsigned depthToCheck)
2466-
: m_startCallFrame(startCallFrame)
2467-
, m_codeBlock(codeBlock)
2468-
, m_depthToCheck(depthToCheck)
2469-
, m_foundStartCallFrame(false)
2470-
, m_didRecurse(false)
2471-
{ }
2472-
2473-
IterationStatus NODELETE operator()(StackVisitor& visitor) const
2474-
{
2475-
CallFrame* currentCallFrame = visitor->callFrame();
2476-
2477-
if (currentCallFrame == m_startCallFrame)
2478-
m_foundStartCallFrame = true;
2479-
2480-
if (m_foundStartCallFrame) {
2481-
if (visitor->codeBlock() == m_codeBlock) {
2482-
m_didRecurse = true;
2483-
return IterationStatus::Done;
2484-
}
2485-
2486-
if (!m_depthToCheck--)
2487-
return IterationStatus::Done;
2488-
}
2489-
2490-
return IterationStatus::Continue;
2491-
}
2492-
2493-
bool NODELETE didRecurse() const { return m_didRecurse; }
2494-
2495-
private:
2496-
CallFrame* const m_startCallFrame;
2497-
CodeBlock* const m_codeBlock;
2498-
mutable unsigned m_depthToCheck;
2499-
mutable bool m_foundStartCallFrame;
2500-
mutable bool m_didRecurse;
2501-
};
2502-
25032444
void CodeBlock::noticeIncomingCall(JSCell* caller)
25042445
{
25052446
RELEASE_ASSERT(!m_isJettisoned);
25062447

25072448
CodeBlock* callerCodeBlock = dynamicDowncast<CodeBlock>(caller);
25082449

25092450
dataLogLnIf(Options::verboseCallLink(), "Noticing call link from ", pointerDump(callerCodeBlock), " to ", *this);
2510-
2511-
#if ENABLE(DFG_JIT)
2512-
if (!m_shouldAlwaysBeInlined)
2513-
return;
2514-
2515-
if (!callerCodeBlock) {
2516-
m_shouldAlwaysBeInlined = false;
2517-
dataLogLnIf(Options::verboseCallLink(), " Clearing SABI because caller is native.");
2518-
return;
2519-
}
2520-
2521-
if (!hasBaselineJITProfiling())
2522-
return;
2523-
2524-
if (!DFG::mightInlineFunction(JITType::FTLJIT, this))
2525-
return;
2526-
2527-
if (!canInline(capabilityLevelState()))
2528-
return;
2529-
2530-
if (!DFG::isSmallEnoughToInlineCodeInto(callerCodeBlock)) {
2531-
m_shouldAlwaysBeInlined = false;
2532-
dataLogLnIf(Options::verboseCallLink(), " Clearing SABI because caller is too large.");
2533-
return;
2534-
}
2535-
2536-
if (callerCodeBlock->jitType() == JITType::InterpreterThunk) {
2537-
// If the caller is still in the interpreter, then we can't expect inlining to
2538-
// happen anytime soon. Assume it's profitable to optimize it separately. This
2539-
// ensures that a function is SABI only if it is called no more frequently than
2540-
// any of its callers.
2541-
m_shouldAlwaysBeInlined = false;
2542-
dataLogLnIf(Options::verboseCallLink(), " Clearing SABI because caller is in LLInt.");
2543-
return;
2544-
}
2545-
2546-
if (JSC::JITCode::isOptimizingJIT(callerCodeBlock->jitType())) {
2547-
m_shouldAlwaysBeInlined = false;
2548-
dataLogLnIf(Options::verboseCallLink(), " Clearing SABI bcause caller was already optimized.");
2549-
return;
2550-
}
2551-
2552-
if (callerCodeBlock->codeType() != FunctionCode) {
2553-
// If the caller is either eval or global code, assume that that won't be
2554-
// optimized anytime soon. For eval code this is particularly true since we
2555-
// delay eval optimization by a *lot*.
2556-
m_shouldAlwaysBeInlined = false;
2557-
dataLogLnIf(Options::verboseCallLink(), " Clearing SABI because caller is not a function.");
2558-
return;
2559-
}
2560-
2561-
// Recursive calls won't be inlined.
2562-
if (callerCodeBlock->capabilityLevelState() == DFG::CapabilityLevelNotSet) {
2563-
dataLog("In call from ", FullCodeOrigin(callerCodeBlock, CodeOrigin { }), " to ", *this, ": caller's DFG capability level is not set.\n");
2564-
CRASH();
2565-
}
2566-
2567-
if (canCompile(callerCodeBlock->capabilityLevelState()))
2568-
return;
2569-
2570-
dataLogLnIf(Options::verboseCallLink(), " Clearing SABI because the caller is not a DFG candidate.");
2571-
2572-
m_shouldAlwaysBeInlined = false;
2573-
#endif
25742451
}
25752452

25762453
unsigned CodeBlock::reoptimizationRetryCounter() const

‎Source/JavaScriptCore/bytecode/CodeBlock.h‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -805,10 +805,6 @@ class CodeBlock : public JSCell {
805805
// concurrent compilation threads finish what they're doing.
806806
mutable ConcurrentJSLock m_lock;
807807

808-
bool m_shouldAlwaysBeInlined { true }; // Not a bitfield because the JIT wants to store to it.
809-
810-
static constexpr ptrdiff_t offsetOfShouldAlwaysBeInlined() { return OBJECT_OFFSETOF(CodeBlock, m_shouldAlwaysBeInlined); }
811-
812808
#if ENABLE(JIT)
813809
unsigned m_capabilityLevelState : 2; // DFG::CapabilityLevel
814810
#endif

‎Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,11 +2065,7 @@ std::tuple<unsigned, InlineAttribute> ByteCodeParser::inliningCost(CallVariant c
20652065
return { UINT_MAX, InlineAttribute::None };
20662066
}
20672067

2068-
// Check if the caller is already too large. We do this check here because that's just
2069-
// where we happen to also have the callee's code block, and we want that for the
2070-
// purpose of unsetting SABI.
20712068
if (!isSmallEnoughToInlineCodeInto(m_codeBlock)) {
2072-
codeBlock->m_shouldAlwaysBeInlined = false;
20732069
VERBOSE_LOG(" Failing because the caller is too large.\n");
20742070
return { UINT_MAX, InlineAttribute::None };
20752071
}

‎Source/JavaScriptCore/dfg/DFGCapabilities.h‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,6 @@ inline bool mightCompileFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind
139139
return mightCompileFunctionForConstruct(codeBlock);
140140
}
141141

142-
inline bool mightInlineFunction(JITType jitType, CodeBlock* codeBlock)
143-
{
144-
return mightInlineFunctionFor(jitType, codeBlock, codeBlock->specializationKind());
145-
}
146-
147142
inline CapabilityLevel inlineFunctionForCapabilityLevel(JITType jitType, CodeBlock* codeBlock, CodeSpecializationKind kind, bool isClosureCall)
148143
{
149144
if (isClosureCall) {

‎Source/JavaScriptCore/interpreter/CachedCall.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ class CachedCall : public CallLinkInfoBase {
7878
remove();
7979

8080
if (newCodeBlock && m_protoCallFrame.codeBlock() == oldCodeBlock) {
81-
newCodeBlock->m_shouldAlwaysBeInlined = false;
8281
m_addressForCall = newCodeBlock->jitCode()->addressForCall();
8382
m_protoCallFrame.setCodeBlock(newCodeBlock);
8483
newCodeBlock->linkIncomingCall(nullptr, this);

‎Source/JavaScriptCore/interpreter/Interpreter.cpp‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,6 @@ ALWAYS_INLINE JSValue Interpreter::executeCallImpl(VM& vm, JSObject* function, c
13081308
functionExecutable->prepareForExecution<FunctionExecutable>(vm, uncheckedDowncast<JSFunction>(function), functionScope, CodeSpecializationKind::CodeForCall, newCodeBlock);
13091309
RETURN_IF_EXCEPTION_WITH_TRAPS_DEFERRED(scope, scope.exception());
13101310
ASSERT(newCodeBlock);
1311-
newCodeBlock->m_shouldAlwaysBeInlined = false;
13121311
}
13131312

13141313
{
@@ -1404,7 +1403,6 @@ JSObject* Interpreter::executeConstruct(JSObject* constructor, const CallData& c
14041403
constructData.js.functionExecutable->prepareForExecution<FunctionExecutable>(vm, uncheckedDowncast<JSFunction>(constructor), scope, CodeSpecializationKind::CodeForConstruct, newCodeBlock);
14051404
RETURN_IF_EXCEPTION_WITH_TRAPS_DEFERRED(throwScope, nullptr);
14061405
ASSERT(newCodeBlock);
1407-
newCodeBlock->m_shouldAlwaysBeInlined = false;
14081406
}
14091407

14101408
{
@@ -1441,7 +1439,6 @@ CodeBlock* Interpreter::prepareForCachedCall(CachedCall& cachedCall, JSFunction*
14411439
RETURN_IF_EXCEPTION(throwScope, { });
14421440

14431441
ASSERT(newCodeBlock);
1444-
newCodeBlock->m_shouldAlwaysBeInlined = false;
14451442

14461443
cachedCall.m_addressForCall = newCodeBlock->jitCode()->addressForCall();
14471444
newCodeBlock->linkIncomingCall(nullptr, &cachedCall);
@@ -1459,7 +1456,6 @@ CodeBlock* Interpreter::prepareForMicrotaskCall(MicrotaskCall& microtaskCall, JS
14591456
RETURN_IF_EXCEPTION_WITH_TRAPS_DEFERRED(throwScope, { });
14601457

14611458
ASSERT(newCodeBlock);
1462-
newCodeBlock->m_shouldAlwaysBeInlined = false;
14631459

14641460
microtaskCall.m_addressForCall = newCodeBlock->jitCode()->addressForCall();
14651461
newCodeBlock->linkIncomingCall(nullptr, &microtaskCall);

‎Source/JavaScriptCore/interpreter/MicrotaskCall.cpp‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ void MicrotaskCall::unlinkOrUpgradeImpl(VM&, CodeBlock* oldCodeBlock, CodeBlock*
6363
remove();
6464

6565
if (newCodeBlock && m_codeBlock == oldCodeBlock) {
66-
newCodeBlock->m_shouldAlwaysBeInlined = false;
6766
m_addressForCall = newCodeBlock->jitCode()->addressForCall();
6867
m_codeBlock = newCodeBlock;
6968
m_numParameters = newCodeBlock->numParameters();

‎Source/JavaScriptCore/jit/JITOperations.cpp‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2967,12 +2967,6 @@ JSC_DEFINE_JIT_OPERATION(operationOptimize, UGPRPair, (VM* vmPointer, uint32_t b
29672967
if (level == DFG::CannotCompile)
29682968
OPERATION_RETURN(scope, encodeResult(nullptr, nullptr));
29692969

2970-
if (bytecodeIndex) {
2971-
// If we're attempting to OSR from a loop, assume that this should be
2972-
// separately optimized.
2973-
codeBlock->m_shouldAlwaysBeInlined = false;
2974-
}
2975-
29762970
if (Options::verboseOSR()) [[unlikely]] {
29772971
dataLog(
29782972
*codeBlock, ": Entered optimize with bytecodeIndex = ", bytecodeIndex,
@@ -3009,13 +3003,6 @@ JSC_DEFINE_JIT_OPERATION(operationOptimize, UGPRPair, (VM* vmPointer, uint32_t b
30093003
OPERATION_RETURN(scope, encodeResult(nullptr, nullptr));
30103004
}
30113005

3012-
if (codeBlock->m_shouldAlwaysBeInlined) {
3013-
CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("should always be inlined"));
3014-
updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
3015-
dataLogLnIf(Options::verboseOSR(), "Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.");
3016-
OPERATION_RETURN(scope, encodeResult(nullptr, nullptr));
3017-
}
3018-
30193006
// The call to JITWorklist::completeAllReadyPlansForVM() will complete all ready
30203007
// (i.e. compiled) code blocks. But if it completes ours, we also need to know
30213008
// what the result was so that we don't plow ahead and attempt OSR or immediate

‎Source/JavaScriptCore/runtime/JSMicrotask.cpp‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ static JSValue callMicrotask(JSGlobalObject* globalObject, JSValue functionObjec
137137
functionExecutable->prepareForExecution<FunctionExecutable>(vm, uncheckedDowncast<JSFunction>(functionObject.asCell()), functionScope, CodeSpecializationKind::CodeForCall, newCodeBlock);
138138
RETURN_IF_EXCEPTION_WITH_TRAPS_DEFERRED(scope, scope.exception());
139139
ASSERT(newCodeBlock);
140-
newCodeBlock->m_shouldAlwaysBeInlined = false;
141140
}
142141

143142
if (microtaskCallCache) {

0 commit comments

Comments
 (0)