- Revision
- 164558
- Author
- [email protected]
- Date
- 2014-02-23 10:48:43 -0800 (Sun, 23 Feb 2014)
Log Message
Refine DFG+FTL inlining and compilation limits
https://bugs.webkit.org/show_bug.cgi?id=129212
Reviewed by Mark Hahnenberg.
Allow larger functions to be DFG-compiled. Institute a limit on FTL compilation,
and set that limit quite high. Institute a limit on inlining-into. The idea here is
that large functions tend to be autogenerated, and code generators like emscripten
appear to leave few inlining opportunities anyway. Also, we don't want the code
size explosion that we would risk if we allowed compilation of a large function and
then inlined a ton of stuff into it.
This is a 0.5% speed-up on Octane v2 and almost eliminates the typescript
regression. This is a 9% speed-up on AsmBench.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::noticeIncomingCall):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInlining):
* dfg/DFGCapabilities.h:
(JSC::DFG::isSmallEnoughToInlineCodeInto):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLState.h:
(JSC::FTL::shouldShowDisassembly):
* runtime/Options.h:
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (164557 => 164558)
--- trunk/Source/_javascript_Core/ChangeLog 2014-02-23 18:06:16 UTC (rev 164557)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-02-23 18:48:43 UTC (rev 164558)
@@ -1,3 +1,32 @@
+2014-02-22 Filip Pizlo <[email protected]>
+
+ Refine DFG+FTL inlining and compilation limits
+ https://bugs.webkit.org/show_bug.cgi?id=129212
+
+ Reviewed by Mark Hahnenberg.
+
+ Allow larger functions to be DFG-compiled. Institute a limit on FTL compilation,
+ and set that limit quite high. Institute a limit on inlining-into. The idea here is
+ that large functions tend to be autogenerated, and code generators like emscripten
+ appear to leave few inlining opportunities anyway. Also, we don't want the code
+ size explosion that we would risk if we allowed compilation of a large function and
+ then inlined a ton of stuff into it.
+
+ This is a 0.5% speed-up on Octane v2 and almost eliminates the typescript
+ regression. This is a 9% speed-up on AsmBench.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::noticeIncomingCall):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::isSmallEnoughToInlineCodeInto):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLState.h:
+ (JSC::FTL::shouldShowDisassembly):
+ * runtime/Options.h:
+
2014-02-22 Dan Bernstein <[email protected]>
REGRESSION (r164507): Crash beneath JSGlobalObjectInspectorController::reportAPIException at facebook.com, twitter.com, youtube.com
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (164557 => 164558)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-02-23 18:06:16 UTC (rev 164557)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-02-23 18:48:43 UTC (rev 164558)
@@ -2787,6 +2787,13 @@
if (!canInline(m_capabilityLevelState))
return;
+
+ if (!DFG::isSmallEnoughToInlineCodeInto(callerCodeBlock)) {
+ m_shouldAlwaysBeInlined = false;
+ if (Options::verboseCallLink())
+ dataLog(" Clearing SABI because caller is too large.\n");
+ return;
+ }
if (callerCodeBlock->jitType() == JITCode::InterpreterThunk) {
// If the caller is still in the interpreter, then we can't expect inlining to
@@ -2795,7 +2802,7 @@
// any of its callers.
m_shouldAlwaysBeInlined = false;
if (Options::verboseCallLink())
- dataLog(" Marking SABI because caller is in LLInt.\n");
+ dataLog(" Clearing SABI because caller is in LLInt.\n");
return;
}
@@ -2805,7 +2812,7 @@
// delay eval optimization by a *lot*.
m_shouldAlwaysBeInlined = false;
if (Options::verboseCallLink())
- dataLog(" Marking SABI because caller is not a function.\n");
+ dataLog(" Clearing SABI because caller is not a function.\n");
return;
}
@@ -2816,7 +2823,7 @@
if (frame->codeBlock() == this) {
// Recursive calls won't be inlined.
if (Options::verboseCallLink())
- dataLog(" Marking SABI because recursion was detected.\n");
+ dataLog(" Clearing SABI because recursion was detected.\n");
m_shouldAlwaysBeInlined = false;
return;
}
@@ -2828,7 +2835,7 @@
return;
if (Options::verboseCallLink())
- dataLog(" Marking SABI because the caller is not a DFG candidate.\n");
+ dataLog(" Clearing SABI because the caller is not a DFG candidate.\n");
m_shouldAlwaysBeInlined = false;
#endif
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (164557 => 164558)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2014-02-23 18:06:16 UTC (rev 164557)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2014-02-23 18:48:43 UTC (rev 164558)
@@ -1316,6 +1316,16 @@
return false;
}
+ // Check if the caller is already too large. We do this check here because that's just
+ // where we happen to also have the callee's code block, and we want that for the
+ // purpose of unsetting SABI.
+ if (!isSmallEnoughToInlineCodeInto(m_codeBlock)) {
+ codeBlock->m_shouldAlwaysBeInlined = false;
+ if (verbose)
+ dataLog(" Failing because the caller is too large.\n");
+ return false;
+ }
+
// FIXME: this should be better at predicting how much bloat we will introduce by inlining
// this function.
// https://bugs.webkit.org/show_bug.cgi?id=127627
Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.h (164557 => 164558)
--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.h 2014-02-23 18:06:16 UTC (rev 164557)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.h 2014-02-23 18:48:43 UTC (rev 164558)
@@ -144,6 +144,11 @@
return inlineFunctionForConstructCapabilityLevel(codeBlock);
}
+inline bool isSmallEnoughToInlineCodeInto(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumInliningCallerSize();
+}
+
} } // namespace JSC::DFG
#endif // DFGCapabilities_h
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (164557 => 164558)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2014-02-23 18:06:16 UTC (rev 164557)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2014-02-23 18:48:43 UTC (rev 164558)
@@ -278,6 +278,12 @@
CapabilityLevel canCompile(Graph& graph)
{
+ if (graph.m_codeBlock->instructionCount() > Options::maximumFTLCandidateInstructionCount()) {
+ if (verboseCapabilities())
+ dataLog("FTL rejecting ", *graph.m_codeBlock, " because it's too big.\n");
+ return CannotCompile;
+ }
+
if (graph.m_codeBlock->codeType() != FunctionCode) {
if (verboseCapabilities())
dataLog("FTL rejecting ", *graph.m_codeBlock, " because it doesn't belong to a function.\n");
Modified: trunk/Source/_javascript_Core/ftl/FTLState.h (164557 => 164558)
--- trunk/Source/_javascript_Core/ftl/FTLState.h 2014-02-23 18:06:16 UTC (rev 164557)
+++ trunk/Source/_javascript_Core/ftl/FTLState.h 2014-02-23 18:48:43 UTC (rev 164558)
@@ -46,7 +46,7 @@
return DFG::verboseCompilationEnabled(DFG::FTLMode);
}
-inline bool showDisassembly()
+inline bool shouldShowDisassembly()
{
return DFG::shouldShowDisassembly(DFG::FTLMode);
}
Modified: trunk/Source/_javascript_Core/runtime/Options.h (164557 => 164558)
--- trunk/Source/_javascript_Core/runtime/Options.h 2014-02-23 18:06:16 UTC (rev 164557)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2014-02-23 18:48:43 UTC (rev 164558)
@@ -170,18 +170,24 @@
\
v(bool, breakOnThrow, false) \
\
- v(unsigned, maximumOptimizationCandidateInstructionCount, 10000) \
+ v(unsigned, maximumOptimizationCandidateInstructionCount, 100000) \
\
v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180) \
v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100) \
v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100) \
\
+ v(unsigned, maximumFTLCandidateInstructionCount, 20000) \
+ \
/* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \
v(unsigned, maximumInliningDepth, 5) \
v(unsigned, maximumInliningRecursion, 2) \
v(unsigned, maximumInliningDepthForMustInline, 7) \
v(unsigned, maximumInliningRecursionForMustInline, 3) \
\
+ /* Maximum size of a caller for enabling inlining. This is purely to protect us */\
+ /* from super long compiles that take a lot of memory. */\
+ v(unsigned, maximumInliningCallerSize, 10000) \
+ \
v(bool, enablePolyvariantCallInlining, true) \
v(bool, enablePolyvariantByIdInlining, true) \
\