Skip to content

Commit

Permalink
[JSC] Adjust inlining options
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=266563
rdar://119795209

Reviewed by Justin Michaud.

This patch extends JSC to have different inlining options for DFG and FTL.
This is great since DFG and FTL have different purpose and we would like
to make DFG smaller-compilation and faster and keeping FTL heavy and highly optimized.
And then, we adjust these numbers based on benchmarks.

1. DFG inlining heuristics becomes 80.
2. FTL call inlining heuristics becomes 125.

* Source/JavaScriptCore/bytecode/CodeBlock.cpp:
(JSC::CodeBlock::setupWithUnlinkedBaselineCode):
(JSC::CodeBlock::computeCapabilityLevel):
(JSC::CodeBlock::noticeIncomingCall):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::inliningCost):
(JSC::DFG::ByteCodeParser::getInliningBalance):
* Source/JavaScriptCore/dfg/DFGCapabilities.cpp:
(JSC::DFG::mightInlineFunctionForCall):
(JSC::DFG::mightInlineFunctionForClosureCall):
(JSC::DFG::mightInlineFunctionForConstruct):
* Source/JavaScriptCore/dfg/DFGCapabilities.h:
(JSC::DFG::mightInlineFunctionForCall):
(JSC::DFG::mightInlineFunctionForClosureCall):
(JSC::DFG::mightInlineFunctionForConstruct):
(JSC::DFG::functionForCallCapabilityLevel):
(JSC::DFG::functionForConstructCapabilityLevel):
(JSC::DFG::inlineFunctionForCallCapabilityLevel):
(JSC::DFG::inlineFunctionForClosureCallCapabilityLevel):
(JSC::DFG::inlineFunctionForConstructCapabilityLevel):
(JSC::DFG::mightInlineFunctionFor):
(JSC::DFG::mightInlineFunction):
(JSC::DFG::inlineFunctionForCapabilityLevel):
* Source/JavaScriptCore/heap/LocalAllocatorInlines.h:
(JSC::LocalAllocator::allocate):
* Source/JavaScriptCore/jit/JITPlan.h:
(JSC::JITPlan::jitType const):
* Source/JavaScriptCore/runtime/Options.cpp:
(JSC::overrideDefaults):
* Source/JavaScriptCore/runtime/OptionsList.h:

Canonical link: https://commits.webkit.org/272208@main
  • Loading branch information
Constellation committed Dec 18, 2023
1 parent 471790c commit f24813d
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 53 deletions.
8 changes: 4 additions & 4 deletions Source/JavaScriptCore/bytecode/CodeBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ void CodeBlock::setupWithUnlinkedBaselineCode(Ref<BaselineJITCode> jitCode)
case FunctionCode:
// We could have already set it to false because we detected an uninlineable call.
// Don't override that observation.
m_shouldAlwaysBeInlined &= canInline(capabilityLevel()) && DFG::mightInlineFunction(this);
m_shouldAlwaysBeInlined &= canInline(capabilityLevel()) && DFG::mightInlineFunction(JITType::FTLJIT, this);
break;
}

Expand Down Expand Up @@ -2138,8 +2138,8 @@ DFG::CapabilityLevel CodeBlock::computeCapabilityLevel()

if (classInfo == FunctionCodeBlock::info()) {
if (isConstructor())
return DFG::functionForConstructCapabilityLevel(this);
return DFG::functionForCallCapabilityLevel(this);
return DFG::functionForConstructCapabilityLevel(JITType::FTLJIT, this);
return DFG::functionForCallCapabilityLevel(JITType::FTLJIT, this);
}

if (classInfo == EvalCodeBlock::info())
Expand Down Expand Up @@ -2349,7 +2349,7 @@ void CodeBlock::noticeIncomingCall(CallFrame* callerFrame)
if (!hasBaselineJITProfiling())
return;

if (!DFG::mightInlineFunction(this))
if (!DFG::mightInlineFunction(JITType::FTLJIT, this))
return;

if (!canInline(capabilityLevelState()))
Expand Down
11 changes: 5 additions & 6 deletions Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1694,12 +1694,11 @@ std::tuple<unsigned, InlineAttribute> ByteCodeParser::inliningCost(CallVariant c
}
}

CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(
codeBlock, specializationKind, callee.isClosureCall());
CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(m_graph.m_plan.jitType(), codeBlock, specializationKind, callee.isClosureCall());
VERBOSE_LOG(" Call mode: ", callMode, "\n");
VERBOSE_LOG(" Is closure call: ", callee.isClosureCall(), "\n");
VERBOSE_LOG(" Capability level: ", capabilityLevel, "\n");
VERBOSE_LOG(" Might inline function: ", mightInlineFunctionFor(codeBlock, specializationKind), "\n");
VERBOSE_LOG(" Might inline function: ", mightInlineFunctionFor(m_graph.m_plan.jitType(), codeBlock, specializationKind), "\n");
VERBOSE_LOG(" Might compile function: ", mightCompileFunctionFor(codeBlock, specializationKind), "\n");
VERBOSE_LOG(" Is supported for inlining: ", isSupportedForInlining(codeBlock), "\n");
VERBOSE_LOG(" Is inlining candidate: ", codeBlock->ownerExecutable()->isInliningCandidate(), "\n");
Expand Down Expand Up @@ -2215,11 +2214,11 @@ bool ByteCodeParser::handleVarargsInlining(Node* callTargetNode, Operand result,

unsigned ByteCodeParser::getInliningBalance(const CallLinkStatus& callLinkStatus, CodeSpecializationKind specializationKind)
{
unsigned inliningBalance = Options::maximumFunctionForCallInlineCandidateBytecodeCost();
unsigned inliningBalance = m_graph.m_plan.isFTL() ? Options::maximumFunctionForCallInlineCandidateBytecodeCostForFTL() : Options::maximumFunctionForCallInlineCandidateBytecodeCostForDFG();
if (specializationKind == CodeForConstruct)
inliningBalance = std::min(inliningBalance, Options::maximumFunctionForConstructInlineCandidateBytecoodeCost());
inliningBalance = std::min(inliningBalance, m_graph.m_plan.isFTL() ? Options::maximumFunctionForConstructInlineCandidateBytecodeCostForFTL() : Options::maximumFunctionForConstructInlineCandidateBytecodeCostForDFG());
if (callLinkStatus.isClosureCall())
inliningBalance = std::min(inliningBalance, Options::maximumFunctionForClosureCallInlineCandidateBytecodeCost());
inliningBalance = std::min(inliningBalance, m_graph.m_plan.isFTL() ? Options::maximumFunctionForClosureCallInlineCandidateBytecodeCostForFTL() : Options::maximumFunctionForClosureCallInlineCandidateBytecodeCostForDFG());
return inliningBalance;
}

Expand Down
39 changes: 30 additions & 9 deletions Source/JavaScriptCore/dfg/DFGCapabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,43 @@ bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
&& codeBlock->ownerExecutable()->isOkToOptimize();
}

bool mightInlineFunctionForCall(CodeBlock* codeBlock)
bool mightInlineFunctionForCall(JITType jitType, CodeBlock* codeBlock)
{
if (codeBlock->ownerExecutable()->inlineAttribute() != InlineAttribute::Always && codeBlock->bytecodeCost() > Options::maximumFunctionForCallInlineCandidateBytecodeCost())
return false;
if (codeBlock->ownerExecutable()->inlineAttribute() != InlineAttribute::Always) {
if (jitType == JITType::DFGJIT) {
if (codeBlock->bytecodeCost() > Options::maximumFunctionForCallInlineCandidateBytecodeCostForDFG())
return false;
} else {
if (codeBlock->bytecodeCost() > Options::maximumFunctionForCallInlineCandidateBytecodeCostForFTL())
return false;
}
}
return isSupportedForInlining(codeBlock);
}
bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock)
bool mightInlineFunctionForClosureCall(JITType jitType, CodeBlock* codeBlock)
{
if (codeBlock->ownerExecutable()->inlineAttribute() != InlineAttribute::Always && codeBlock->bytecodeCost() > Options::maximumFunctionForClosureCallInlineCandidateBytecodeCost())
return false;
if (codeBlock->ownerExecutable()->inlineAttribute() != InlineAttribute::Always) {
if (jitType == JITType::DFGJIT) {
if (codeBlock->bytecodeCost() > Options::maximumFunctionForClosureCallInlineCandidateBytecodeCostForDFG())
return false;
} else {
if (codeBlock->bytecodeCost() > Options::maximumFunctionForClosureCallInlineCandidateBytecodeCostForFTL())
return false;
}
}
return isSupportedForInlining(codeBlock);
}
bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
bool mightInlineFunctionForConstruct(JITType jitType, CodeBlock* codeBlock)
{
if (codeBlock->ownerExecutable()->inlineAttribute() != InlineAttribute::Always && codeBlock->bytecodeCost() > Options::maximumFunctionForConstructInlineCandidateBytecoodeCost())
return false;
if (codeBlock->ownerExecutable()->inlineAttribute() != InlineAttribute::Always) {
if (jitType == JITType::DFGJIT) {
if (codeBlock->bytecodeCost() > Options::maximumFunctionForConstructInlineCandidateBytecodeCostForDFG())
return false;
} else {
if (codeBlock->bytecodeCost() > Options::maximumFunctionForConstructInlineCandidateBytecodeCostForFTL())
return false;
}
}
return isSupportedForInlining(codeBlock);
}
bool canUseOSRExitFuzzing(CodeBlock* codeBlock)
Expand Down
50 changes: 25 additions & 25 deletions Source/JavaScriptCore/dfg/DFGCapabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ bool mightCompileEval(CodeBlock*);
bool mightCompileProgram(CodeBlock*);
bool mightCompileFunctionForCall(CodeBlock*);
bool mightCompileFunctionForConstruct(CodeBlock*);
bool mightInlineFunctionForCall(CodeBlock*);
bool mightInlineFunctionForClosureCall(CodeBlock*);
bool mightInlineFunctionForConstruct(CodeBlock*);
bool mightInlineFunctionForCall(JITType, CodeBlock*);
bool mightInlineFunctionForClosureCall(JITType, CodeBlock*);
bool mightInlineFunctionForConstruct(JITType, CodeBlock*);
bool canUseOSRExitFuzzing(CodeBlock*);
#else // ENABLE(DFG_JIT)
inline bool mightCompileEval(CodeBlock*) { return false; }
inline bool mightCompileProgram(CodeBlock*) { return false; }
inline bool mightCompileFunctionForCall(CodeBlock*) { return false; }
inline bool mightCompileFunctionForConstruct(CodeBlock*) { return false; }
inline bool mightInlineFunctionForCall(CodeBlock*) { return false; }
inline bool mightInlineFunctionForClosureCall(CodeBlock*) { return false; }
inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
inline bool mightInlineFunctionForCall(JITType, CodeBlock*) { return false; }
inline bool mightInlineFunctionForClosureCall(JITType, CodeBlock*) { return false; }
inline bool mightInlineFunctionForConstruct(JITType, CodeBlock*) { return false; }
inline bool canUseOSRExitFuzzing(CodeBlock*) { return false; }
#endif // ENABLE(DFG_JIT)

Expand Down Expand Up @@ -83,52 +83,52 @@ inline CapabilityLevel functionCapabilityLevel(bool mightCompile, bool mightInli
return CannotCompile;
}

inline CapabilityLevel functionForCallCapabilityLevel(CodeBlock* codeBlock)
inline CapabilityLevel functionForCallCapabilityLevel(JITType jitType, CodeBlock* codeBlock)
{
return functionCapabilityLevel(
mightCompileFunctionForCall(codeBlock),
mightInlineFunctionForCall(codeBlock),
mightInlineFunctionForCall(jitType, codeBlock),
CanCompileAndInline);
}

inline CapabilityLevel functionForConstructCapabilityLevel(CodeBlock* codeBlock)
inline CapabilityLevel functionForConstructCapabilityLevel(JITType jitType, CodeBlock* codeBlock)
{
return functionCapabilityLevel(
mightCompileFunctionForConstruct(codeBlock),
mightInlineFunctionForConstruct(codeBlock),
mightInlineFunctionForConstruct(jitType, codeBlock),
CanCompileAndInline);
}

inline CapabilityLevel inlineFunctionForCallCapabilityLevel(CodeBlock* codeBlock)
inline CapabilityLevel inlineFunctionForCallCapabilityLevel(JITType jitType, CodeBlock* codeBlock)
{
if (!mightInlineFunctionForCall(codeBlock))
if (!mightInlineFunctionForCall(jitType, codeBlock))
return CannotCompile;

return CanCompileAndInline;
}

inline CapabilityLevel inlineFunctionForClosureCallCapabilityLevel(CodeBlock* codeBlock)
inline CapabilityLevel inlineFunctionForClosureCallCapabilityLevel(JITType jitType, CodeBlock* codeBlock)
{
if (!mightInlineFunctionForClosureCall(codeBlock))
if (!mightInlineFunctionForClosureCall(jitType, codeBlock))
return CannotCompile;

return CanCompileAndInline;
}

inline CapabilityLevel inlineFunctionForConstructCapabilityLevel(CodeBlock* codeBlock)
inline CapabilityLevel inlineFunctionForConstructCapabilityLevel(JITType jitType, CodeBlock* codeBlock)
{
if (!mightInlineFunctionForConstruct(codeBlock))
if (!mightInlineFunctionForConstruct(jitType, codeBlock))
return CannotCompile;

return CanCompileAndInline;
}

inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
inline bool mightInlineFunctionFor(JITType jitType, CodeBlock* codeBlock, CodeSpecializationKind kind)
{
if (kind == CodeForCall)
return mightInlineFunctionForCall(codeBlock);
return mightInlineFunctionForCall(jitType, codeBlock);
ASSERT(kind == CodeForConstruct);
return mightInlineFunctionForConstruct(codeBlock);
return mightInlineFunctionForConstruct(jitType, codeBlock);
}

inline bool mightCompileFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
Expand All @@ -139,22 +139,22 @@ inline bool mightCompileFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind
return mightCompileFunctionForConstruct(codeBlock);
}

inline bool mightInlineFunction(CodeBlock* codeBlock)
inline bool mightInlineFunction(JITType jitType, CodeBlock* codeBlock)
{
return mightInlineFunctionFor(codeBlock, codeBlock->specializationKind());
return mightInlineFunctionFor(jitType, codeBlock, codeBlock->specializationKind());
}

inline CapabilityLevel inlineFunctionForCapabilityLevel(CodeBlock* codeBlock, CodeSpecializationKind kind, bool isClosureCall)
inline CapabilityLevel inlineFunctionForCapabilityLevel(JITType jitType, CodeBlock* codeBlock, CodeSpecializationKind kind, bool isClosureCall)
{
if (isClosureCall) {
if (kind != CodeForCall)
return CannotCompile;
return inlineFunctionForClosureCallCapabilityLevel(codeBlock);
return inlineFunctionForClosureCallCapabilityLevel(jitType, codeBlock);
}
if (kind == CodeForCall)
return inlineFunctionForCallCapabilityLevel(codeBlock);
return inlineFunctionForCallCapabilityLevel(jitType, codeBlock);
ASSERT(kind == CodeForConstruct);
return inlineFunctionForConstructCapabilityLevel(codeBlock);
return inlineFunctionForConstructCapabilityLevel(jitType, codeBlock);
}

inline bool isSmallEnoughToInlineCodeInto(CodeBlock* codeBlock)
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/heap/LocalAllocatorInlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ALWAYS_INLINE void* LocalAllocator::allocate(JSC::Heap& heap, size_t cellSize, G
if constexpr (validateDFGDoesGC)
vm.verifyCanGC();
return m_freeList.allocateWithCellSize(
[&]() -> HeapCell* {
[&]() ALWAYS_INLINE_LAMBDA {
sanitizeStackForVM(vm);
return static_cast<HeapCell*>(allocateSlowCase(heap, cellSize, deferralContext, failureMode));
}, cellSize);
Expand Down
14 changes: 14 additions & 0 deletions Source/JavaScriptCore/jit/JITPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#if ENABLE(JIT)

#include "CompilationResult.h"
#include "JITCode.h"
#include "JITCompilationKey.h"
#include "JITCompilationMode.h"
#include "JITPlanStage.h"
Expand Down Expand Up @@ -62,6 +63,19 @@ class JITPlan : public ThreadSafeRefCounted<JITPlan> {

enum class Tier { Baseline = 0, DFG = 1, FTL = 2, Count = 3 };
Tier tier() const;
JITType jitType() const
{
switch (tier()) {
case Tier::Baseline:
return JITType::BaselineJIT;
case Tier::DFG:
return JITType::DFGJIT;
case Tier::FTL:
return JITType::FTLJIT;
default:
return JITType::None;
}
}

JITCompilationKey key();

Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/runtime/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,9 +556,9 @@ static void overrideDefaults()
#endif

#if OS(LINUX) && CPU(ARM)
Options::maximumFunctionForCallInlineCandidateBytecodeCost() = 77;
Options::maximumFunctionForCallInlineCandidateBytecodeCostForDFG() = 77;
Options::maximumOptimizationCandidateBytecodeCost() = 42403;
Options::maximumFunctionForClosureCallInlineCandidateBytecodeCost() = 68;
Options::maximumFunctionForClosureCallInlineCandidateBytecodeCostForDFG() = 68;
Options::maximumInliningCallerBytecodeCost() = 9912;
Options::maximumInliningDepth() = 8;
Options::maximumInliningRecursion() = 3;
Expand Down
12 changes: 6 additions & 6 deletions Source/JavaScriptCore/runtime/OptionsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,12 @@ bool canUseHandlerIC();
\
v(Unsigned, maximumOptimizationCandidateBytecodeCost, 100000, Normal, nullptr) \
\
v(Unsigned, maximumFunctionForCallInlineCandidateBytecodeCost, 120, Normal, nullptr) \
v(Unsigned, maximumFunctionForClosureCallInlineCandidateBytecodeCost, 100, Normal, nullptr) \
v(Unsigned, maximumFunctionForConstructInlineCandidateBytecoodeCost, 100, Normal, nullptr) \
v(Unsigned, maximumFunctionForCallInlineCandidateBytecodeCostForDFG, 80, Normal, nullptr) \
v(Unsigned, maximumFunctionForClosureCallInlineCandidateBytecodeCostForDFG, 80, Normal, nullptr) \
v(Unsigned, maximumFunctionForConstructInlineCandidateBytecodeCostForDFG, 80, Normal, nullptr) \
v(Unsigned, maximumFunctionForCallInlineCandidateBytecodeCostForFTL, 125, Normal, nullptr) \
v(Unsigned, maximumFunctionForClosureCallInlineCandidateBytecodeCostForFTL, 100, Normal, nullptr) \
v(Unsigned, maximumFunctionForConstructInlineCandidateBytecodeCostForFTL, 100, Normal, nullptr) \
\
v(Unsigned, maximumFTLCandidateBytecodeCost, 20000, Normal, nullptr) \
\
Expand Down Expand Up @@ -633,9 +636,6 @@ enum OptionEquivalence {
v(enableDollarVM, useDollarVM, SameOption) \
v(enableWebAssembly, useWebAssembly, SameOption) \
v(maximumOptimizationCandidateInstructionCount, maximumOptimizationCandidateBytecodeCost, SameOption) \
v(maximumFunctionForCallInlineCandidateInstructionCount, maximumFunctionForCallInlineCandidateBytecodeCost, SameOption) \
v(maximumFunctionForClosureCallInlineCandidateInstructionCount, maximumFunctionForClosureCallInlineCandidateBytecodeCost, SameOption) \
v(maximumFunctionForConstructInlineCandidateInstructionCount, maximumFunctionForConstructInlineCandidateBytecoodeCost, SameOption) \
v(maximumFTLCandidateInstructionCount, maximumFTLCandidateBytecodeCost, SameOption) \
v(maximumInliningCallerSize, maximumInliningCallerBytecodeCost, SameOption) \
v(validateBCE, validateBoundsCheckElimination, SameOption)
Expand Down

0 comments on commit f24813d

Please sign in to comment.