Diff
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/ChangeLog (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/ChangeLog 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/ChangeLog 2016-02-29 10:02:16 UTC (rev 197324)
@@ -1,3 +1,39 @@
+2016-02-25 Benjamin Poulain <bpoul...@apple.com>
+
+ [JSC] Be aggressive with OSR Entry to FTL if the DFG function was only used for OSR Entry itself
+ https://bugs.webkit.org/show_bug.cgi?id=154575
+
+ Reviewed by Filip Pizlo.
+
+ I noticed that imaging-gaussian-blur spends most of its
+ samples in DFG code despite executing most of the loop
+ iterations in FTL.
+
+ On this particular test, the main function is only entered
+ once and have a very heavy loop there. What happens is DFG
+ starts by compiling the full function in FTL. That takes about
+ 8 to 10 milliseconds during which the DFG code makes very little
+ progress. The calls to triggerOSREntryNow() try to OSR Enter
+ for a while then finally start compiling something. By the time
+ the function is ready, we have wasted a lot of time in DFG code.
+
+ What this patch does is set a flag when a DFG function is entered.
+ If we try to triggerOSREntryNow() and the flag was never set,
+ we start compiling both the full function and the one for OSR Entry.
+
+ * dfg/DFGJITCode.h:
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compileEntryExecutionFlag):
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGPlan.cpp:
+ (JSC::DFG::Plan::Plan): Deleted.
+ * dfg/DFGPlan.h:
+ * dfg/DFGTierUpCheckInjectionPhase.cpp:
+ (JSC::DFG::TierUpCheckInjectionPhase::run):
+
2016-02-26 Benjamin Poulain <benja...@webkit.org>
[JSC] Add the test for r197155
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCode.h (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCode.h 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCode.h 2016-02-29 10:02:16 UTC (rev 197324)
@@ -139,6 +139,7 @@
DFG::MinifiedGraph minifiedDFG;
#if ENABLE(FTL_JIT)
uint8_t nestedTriggerIsSet { 0 };
+ uint8_t neverExecutedEntry { 1 };
UpperTierExecutionCounter tierUpCounter;
WriteBarrier<CodeBlock> m_osrEntryBlock;
unsigned osrEntryRetry;
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2016-02-29 10:02:16 UTC (rev 197324)
@@ -111,6 +111,14 @@
emitMaterializeTagCheckRegisters();
}
+void JITCompiler::compileEntryExecutionFlag()
+{
+#if ENABLE(FTL_JIT)
+ if (m_graph.m_plan.canTierUpAndOSREnter)
+ store8(TrustedImm32(0), &m_jitCode->neverExecutedEntry);
+#endif // ENABLE(FTL_JIT)
+}
+
void JITCompiler::compileBody()
{
// We generate the speculative code path, followed by OSR exit code to return
@@ -326,6 +334,7 @@
addPtr(TrustedImm32(m_graph.stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, stackPointerRegister);
checkStackPointerAlignment();
compileSetupRegistersForEntry();
+ compileEntryExecutionFlag();
compileBody();
setEndOfMainPath();
@@ -392,6 +401,7 @@
checkStackPointerAlignment();
compileSetupRegistersForEntry();
+ compileEntryExecutionFlag();
// === Function body code generation ===
m_speculative = std::make_unique<SpeculativeJIT>(*this);
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCompiler.h (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCompiler.h 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGJITCompiler.h 2016-02-29 10:02:16 UTC (rev 197324)
@@ -264,6 +264,7 @@
// Internal implementation to compile.
void compileEntry();
void compileSetupRegistersForEntry();
+ void compileEntryExecutionFlag();
void compileBody();
void link(LinkBuffer&);
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGOperations.cpp (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-02-29 10:02:16 UTC (rev 197324)
@@ -1430,21 +1430,26 @@
}
#if ENABLE(FTL_JIT)
-static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
+static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
{
if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
if (Options::verboseOSR())
dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
jitCode->dontOptimizeAnytimeSoon(codeBlock);
- return;
+ return false;
}
-
- if (!jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
+
+ if (!codeBlock->hasOptimizedReplacement()
+ && !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
if (Options::verboseOSR())
dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
- return;
+ return false;
}
-
+ return true;
+}
+
+static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
+{
Worklist::State worklistState;
if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
worklistState = worklist->completeAllReadyPlansForVM(
@@ -1477,6 +1482,10 @@
compile(
*vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
Operands<JSValue>(), ToFTLDeferredCompilationCallback::create());
+
+ // If we reached here, the counter has not be reset. Do that now.
+ jitCode->setOptimizationThresholdBasedOnCompilationResult(
+ codeBlock, CompilationDeferred);
}
static void triggerTierUpNowCommon(ExecState* exec, bool inLoop)
@@ -1501,7 +1510,8 @@
if (inLoop)
jitCode->nestedTriggerIsSet = 1;
- triggerFTLReplacementCompile(vm, codeBlock, jitCode);
+ if (shouldTriggerFTLCompile(codeBlock, jitCode))
+ triggerFTLReplacementCompile(vm, codeBlock, jitCode);
}
void JIT_OPERATION triggerTierUpNow(ExecState* exec)
@@ -1539,15 +1549,15 @@
// - If we don't have an FTL code block, then try to compile one.
// - If we do have an FTL code block, then try to enter for a while.
// - If we couldn't enter for a while, then trigger OSR entry.
-
- triggerFTLReplacementCompile(vm, codeBlock, jitCode);
- if (!codeBlock->hasOptimizedReplacement())
- return 0;
-
- if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
- jitCode->osrEntryRetry++;
- return 0;
+ if (!shouldTriggerFTLCompile(codeBlock, jitCode))
+ return nullptr;
+
+ if (!jitCode->neverExecutedEntry) {
+ triggerFTLReplacementCompile(vm, codeBlock, jitCode);
+
+ if (!codeBlock->hasOptimizedReplacement())
+ return nullptr;
}
// It's time to try to compile code for OSR entry.
@@ -1558,33 +1568,43 @@
} else
worklistState = Worklist::NotKnown;
- if (worklistState == Worklist::Compiling)
- return 0;
+ if (worklistState == Worklist::Compiling) {
+ jitCode->setOptimizationThresholdBasedOnCompilationResult(
+ codeBlock, CompilationDeferred);
+ return nullptr;
+ }
if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
void* address = FTL::prepareOSREntry(
exec, codeBlock, entryBlock, bytecodeIndex, streamIndex);
if (address)
return static_cast<char*>(address);
-
+
+ if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
+ jitCode->osrEntryRetry++;
+ return nullptr;
+ }
+
FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
entryCode->countEntryFailure();
if (entryCode->entryFailureCount() <
- Options::ftlOSREntryFailureCountForReoptimization())
- return 0;
+ Options::ftlOSREntryFailureCountForReoptimization()) {
+ jitCode->optimizeSoon(codeBlock);
+ return nullptr;
+ }
// OSR entry failed. Oh no! This implies that we need to retry. We retry
// without exponential backoff and we only do this for the entry code block.
jitCode->clearOSREntryBlock();
jitCode->osrEntryRetry = 0;
- return 0;
+ return nullptr;
}
if (worklistState == Worklist::Compiled) {
// This means that compilation failed and we already set the thresholds.
if (Options::verboseOSR())
dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
- return 0;
+ return nullptr;
}
// We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
@@ -1596,10 +1616,16 @@
CompilationResult forEntryResult = compile(
*vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, bytecodeIndex,
mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create());
-
- if (forEntryResult != CompilationSuccessful)
- return 0;
+ if (jitCode->neverExecutedEntry)
+ triggerFTLReplacementCompile(vm, codeBlock, jitCode);
+
+ if (forEntryResult != CompilationSuccessful) {
+ jitCode->setOptimizationThresholdBasedOnCompilationResult(
+ codeBlock, CompilationDeferred);
+ return nullptr;
+ }
+
// It's possible that the for-entry compile already succeeded. In that case OSR
// entry will succeed unless we ran out of stack. It's not clear what we should do.
// We signal to try again after a while if that happens.
@@ -1607,6 +1633,7 @@
exec, codeBlock, jitCode->osrEntryBlock(), bytecodeIndex, streamIndex);
return static_cast<char*>(address);
}
+
#endif // ENABLE(FTL_JIT)
} // extern "C"
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGPlan.cpp (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGPlan.cpp 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGPlan.cpp 2016-02-29 10:02:16 UTC (rev 197324)
@@ -144,7 +144,6 @@
, inlineCallFrames(adoptRef(new InlineCallFrameSet()))
, identifiers(codeBlock)
, weakReferences(codeBlock)
- , willTryToTierUp(false)
, stage(Preparing)
{
}
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGPlan.h (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGPlan.h 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGPlan.h 2016-02-29 10:02:16 UTC (rev 197324)
@@ -98,7 +98,8 @@
DesiredWeakReferences weakReferences;
DesiredTransitions transitions;
- bool willTryToTierUp;
+ bool willTryToTierUp { false };
+ bool canTierUpAndOSREnter { false };
enum Stage { Preparing, Compiling, Compiled, Ready, Cancelled };
Stage stage;
Modified: releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGTierUpCheckInjectionPhase.cpp (197323 => 197324)
--- releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGTierUpCheckInjectionPhase.cpp 2016-02-29 09:53:38 UTC (rev 197323)
+++ releases/WebKitGTK/webkit-2.12/Source/_javascript_Core/dfg/DFGTierUpCheckInjectionPhase.cpp 2016-02-29 10:02:16 UTC (rev 197324)
@@ -71,6 +71,8 @@
NaturalLoops& naturalLoops = *m_graph.m_naturalLoops;
HashSet<const NaturalLoop*> loopsContainingLoopHintWithoutOSREnter = findLoopsContainingLoopHintWithoutOSREnter(naturalLoops, level);
+
+ bool canTierUpAndOSREnter = false;
InsertionSet insertionSet(m_graph);
for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
@@ -85,6 +87,7 @@
NodeOrigin origin = node->origin;
if (canOSREnterAtLoopHint(level, block, nodeIndex)) {
+ canTierUpAndOSREnter = true;
const NaturalLoop* loop = naturalLoops.innerMostLoopOf(block);
if (loop && loopsContainingLoopHintWithoutOSREnter.contains(loop))
insertionSet.insertNode(nodeIndex + 1, SpecNone, CheckTierUpWithNestedTriggerAndOSREnter, origin);
@@ -103,7 +106,8 @@
insertionSet.execute(block);
}
-
+
+ m_graph.m_plan.canTierUpAndOSREnter = canTierUpAndOSREnter;
m_graph.m_plan.willTryToTierUp = true;
return true;
#else // ENABLE(FTL_JIT)