Title: [197324] releases/WebKitGTK/webkit-2.12/Source/_javascript_Core
Revision
197324
Author
carlo...@webkit.org
Date
2016-02-29 02:02:16 -0800 (Mon, 29 Feb 2016)

Log Message

Merge r197159 - [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

Patch by Benjamin Poulain <bpoul...@apple.com> on 2016-02-25
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):

Modified Paths

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)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to