Title: [102489] trunk/Source/_javascript_Core
Revision
102489
Author
[email protected]
Date
2011-12-09 16:09:55 -0800 (Fri, 09 Dec 2011)

Log Message

DFG's interpretation of rare case profiles should be frequency-based not count-based
https://bugs.webkit.org/show_bug.cgi?id=74170

Reviewed by Geoff Garen.
        
DFG optimizes for rare cases only when the rare case counter is above some threshold
and it also constitutes a large enough fraction of total function executions. Also
added some minor debug logic.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::likelyToTakeSlowCase):
(JSC::CodeBlock::couldTakeSlowCase):
(JSC::CodeBlock::likelyToTakeSpecialFastCase):
(JSC::CodeBlock::likelyToTakeDeepestSlowCase):
(JSC::CodeBlock::likelyToTakeAnySlowCase):
(JSC::CodeBlock::executionEntryCount):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::makeSafe):
(JSC::DFG::ByteCodeParser::makeDivSafe):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* runtime/Heuristics.cpp:
(JSC::Heuristics::initializeHeuristics):
* runtime/Heuristics.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (102488 => 102489)


--- trunk/Source/_javascript_Core/ChangeLog	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-12-10 00:09:55 UTC (rev 102489)
@@ -1,3 +1,36 @@
+2011-12-09  Filip Pizlo  <[email protected]>
+
+        DFG's interpretation of rare case profiles should be frequency-based not count-based
+        https://bugs.webkit.org/show_bug.cgi?id=74170
+
+        Reviewed by Geoff Garen.
+        
+        DFG optimizes for rare cases only when the rare case counter is above some threshold
+        and it also constitutes a large enough fraction of total function executions. Also
+        added some minor debug logic.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::likelyToTakeSlowCase):
+        (JSC::CodeBlock::couldTakeSlowCase):
+        (JSC::CodeBlock::likelyToTakeSpecialFastCase):
+        (JSC::CodeBlock::likelyToTakeDeepestSlowCase):
+        (JSC::CodeBlock::likelyToTakeAnySlowCase):
+        (JSC::CodeBlock::executionEntryCount):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::makeSafe):
+        (JSC::DFG::ByteCodeParser::makeDivSafe):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compile):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * runtime/Heuristics.cpp:
+        (JSC::Heuristics::initializeHeuristics):
+        * runtime/Heuristics.h:
+
 2011-12-09  Oliver Hunt  <[email protected]>
 
         PutByValAlias unnecessarily clobbers GetIndexedPropertyStorage

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (102488 => 102489)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-12-10 00:09:55 UTC (rev 102489)
@@ -1433,6 +1433,9 @@
 #if ENABLE(JIT)
     , m_globalResolveInfos(other.m_globalResolveInfos)
 #endif
+#if ENABLE(VALUE_PROFILER)
+    , m_executionEntryCount(0)
+#endif
     , m_jumpTargets(other.m_jumpTargets)
     , m_loopTargets(other.m_loopTargets)
     , m_identifiers(other.m_identifiers)
@@ -1481,6 +1484,9 @@
     , m_codeType(codeType)
     , m_source(sourceProvider)
     , m_sourceOffset(sourceOffset)
+#if ENABLE(VALUE_PROFILER)
+    , m_executionEntryCount(0)
+#endif
     , m_symbolTable(symTab)
     , m_alternative(alternative)
     , m_speculativeSuccessCounter(0)
@@ -2235,16 +2241,6 @@
 }
 #endif
 
-#if ENABLE(VALUE_PROFILER)
-void CodeBlock::resetRareCaseProfiles()
-{
-    for (unsigned i = 0; i < numberOfRareCaseProfiles(); ++i)
-        rareCaseProfile(i)->m_counter = 0;
-    for (unsigned i = 0; i < numberOfSpecialFastCaseProfiles(); ++i)
-        specialFastCaseProfile(i)->m_counter = 0;
-}
-#endif
-
 #if ENABLE(VERBOSE_VALUE_PROFILE)
 void CodeBlock::dumpValueProfiles()
 {

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (102488 => 102489)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-12-10 00:09:55 UTC (rev 102489)
@@ -676,12 +676,14 @@
         
         bool likelyToTakeSlowCase(int bytecodeOffset)
         {
-            return rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter >= Heuristics::likelyToTakeSlowCaseThreshold;
+            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+            return value >= Heuristics::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Heuristics::likelyToTakeSlowCaseThreshold;
         }
         
         bool couldTakeSlowCase(int bytecodeOffset)
         {
-            return rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter >= Heuristics::couldTakeSlowCaseThreshold;
+            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+            return value >= Heuristics::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Heuristics::couldTakeSlowCaseThreshold;
         }
         
         RareCaseProfile* addSpecialFastCaseProfile(int bytecodeOffset)
@@ -699,24 +701,26 @@
         bool likelyToTakeSpecialFastCase(int bytecodeOffset)
         {
             unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
-            return specialFastCaseCount >= Heuristics::likelyToTakeSlowCaseThreshold;
+            return specialFastCaseCount >= Heuristics::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Heuristics::likelyToTakeSlowCaseThreshold;
         }
         
         bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
         {
             unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
             unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
-            return (slowCaseCount - specialFastCaseCount) >= Heuristics::likelyToTakeSlowCaseThreshold;
+            unsigned value = slowCaseCount - specialFastCaseCount;
+            return value >= Heuristics::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Heuristics::likelyToTakeSlowCaseThreshold;
         }
         
         bool likelyToTakeAnySlowCase(int bytecodeOffset)
         {
             unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
             unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
-            return (slowCaseCount + specialFastCaseCount) >= Heuristics::likelyToTakeSlowCaseThreshold;
+            unsigned value = slowCaseCount + specialFastCaseCount;
+            return value >= Heuristics::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Heuristics::likelyToTakeSlowCaseThreshold;
         }
         
-        void resetRareCaseProfiles();
+        unsigned executionEntryCount() const { return m_executionEntryCount; }
 #endif
 
         unsigned globalResolveInfoCount() const
@@ -1213,6 +1217,7 @@
         SegmentedVector<ValueProfile, 8> m_valueProfiles;
         SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
         SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;
+        unsigned m_executionEntryCount;
 #endif
 
         Vector<unsigned> m_jumpTargets;

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (102488 => 102489)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-12-10 00:09:55 UTC (rev 102489)
@@ -67,7 +67,7 @@
         for (int i = 0; i < codeBlock->m_numVars; ++i)
             m_preservedVars.set(i);
     }
-
+    
     // Parse a full CodeBlock of bytecode.
     bool parse();
     
@@ -646,10 +646,17 @@
             break;
             
         case ArithMul:
-            if (m_inlineStackTop->m_profiledBlock->likelyToTakeDeepestSlowCase(m_currentIndex))
+            if (m_inlineStackTop->m_profiledBlock->likelyToTakeDeepestSlowCase(m_currentIndex)) {
+#if DFG_ENABLE(DEBUG_VERBOSE)
+                printf("Making ArithMul @%u take deepest slow case.\n", nodeIndex);
+#endif
                 m_graph[nodeIndex].mergeArithNodeFlags(NodeMayOverflow | NodeMayNegZero);
-            else
+            } else {
+#if DFG_ENABLE(DEBUG_VERBOSE)
+                printf("Making ArithMul @%u take faster slow case.\n", nodeIndex);
+#endif
                 m_graph[nodeIndex].mergeArithNodeFlags(NodeMayNegZero);
+            }
             break;
             
         default:
@@ -673,6 +680,10 @@
         if (!m_inlineStackTop->m_profiledBlock->likelyToTakeSpecialFastCase(m_currentIndex))
             return nodeIndex;
         
+#if DFG_ENABLE(DEBUG_VERBOSE)
+        printf("Making %s @%u safe at bc#%u because special fast-case counter is at %u\n", Graph::opName(m_graph[nodeIndex].op), nodeIndex, m_currentIndex, m_inlineStackTop->m_profiledBlock->specialFastCaseProfileForBytecodeOffset(m_currentIndex)->m_counter);
+#endif
+        
         m_graph[nodeIndex].mergeArithNodeFlags(NodeMayOverflow | NodeMayNegZero);
         
         return nodeIndex;
@@ -874,7 +885,7 @@
     enum { ConstantFunction, LinkedFunction, UnknownFunction } callType;
             
 #if DFG_ENABLE(DEBUG_VERBOSE)
-    printf("Slow case count for call at @%lu bc#%u: %u.\n", m_graph.size(), m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter);
+    printf("Slow case count for call at @%lu bc#%u: %u/%u.\n", m_graph.size(), m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter, m_inlineStackTop->m_profiledBlock->executionEntryCount());
 #endif
             
     if (m_graph.isFunctionConstant(m_codeBlock, callTarget))
@@ -1246,6 +1257,10 @@
 {
     bool shouldContinueParsing = true;
     
+    Interpreter* interpreter = m_globalData->interpreter;
+    Instruction* instructionsBegin = m_inlineStackTop->m_codeBlock->instructions().begin();
+    unsigned blockBegin = m_currentIndex;
+    
     // If we are the first basic block, introduce markers for arguments. This allows
     // us to track if a use of an argument may use the actual argument passed, as
     // opposed to using a value we set explicitly.
@@ -1259,9 +1274,6 @@
         }
     }
 
-    Interpreter* interpreter = m_globalData->interpreter;
-    Instruction* instructionsBegin = m_inlineStackTop->m_codeBlock->instructions().begin();
-    unsigned blockBegin = m_currentIndex;
     while (true) {
         // Don't extend over jump destinations.
         if (m_currentIndex == limit) {
@@ -1691,6 +1703,10 @@
             Identifier identifier = m_codeBlock->identifier(identifierNumber);
             StructureStubInfo& stubInfo = m_inlineStackTop->m_profiledBlock->getStubInfo(m_currentIndex);
             
+#if DFG_ENABLE(DEBUG_VERBOSE)
+            printf("Slow case count for GetById @%lu bc#%u: %u\n", m_graph.size(), m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter);
+#endif
+            
             size_t offset = notFound;
             StructureSet structureSet;
             if (stubInfo.seen && !m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)) {
@@ -1781,6 +1797,10 @@
             
             bool alreadyGenerated = false;
             
+#if DFG_ENABLE(DEBUG_VERBOSE)
+            printf("Slow case count for PutById @%lu bc#%u: %u\n", m_graph.size(), m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter);
+#endif            
+
             if (stubInfo.seen && !m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)) {
                 switch (stubInfo.accessType) {
                 case access_put_by_id_replace: {

Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (102488 => 102489)


--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2011-12-10 00:09:55 UTC (rev 102489)
@@ -44,7 +44,7 @@
     ASSERT(codeBlock->alternative()->getJITType() == JITCode::BaselineJIT);
 
 #if DFG_ENABLE(DEBUG_VERBOSE)
-    fprintf(stderr, "DFG compiling code block %p, number of instructions = %u.\n", codeBlock, codeBlock->instructionCount());
+    fprintf(stderr, "DFG compiling code block %p(%p), number of instructions = %u.\n", codeBlock, codeBlock->alternative(), codeBlock->instructionCount());
 #endif
     
     JSGlobalData* globalData = &exec->globalData();

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (102488 => 102489)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2011-12-10 00:09:55 UTC (rev 102489)
@@ -581,6 +581,11 @@
     }
 
     Label functionBody = label();
+    
+#if ENABLE(VALUE_PROFILER)
+    if (m_canBeOptimized)
+        add32(Imm32(1), AbsoluteAddress(&m_codeBlock->m_executionEntryCount));
+#endif
 
     privateCompileMainPass();
     privateCompileLinkPass();

Modified: trunk/Source/_javascript_Core/runtime/Heuristics.cpp (102488 => 102489)


--- trunk/Source/_javascript_Core/runtime/Heuristics.cpp	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/runtime/Heuristics.cpp	2011-12-10 00:09:55 UTC (rev 102489)
@@ -62,8 +62,10 @@
 
 unsigned desiredSpeculativeSuccessFailRatio;
 
-unsigned likelyToTakeSlowCaseThreshold;
-unsigned couldTakeSlowCaseThreshold;
+double likelyToTakeSlowCaseThreshold;
+double couldTakeSlowCaseThreshold;
+unsigned likelyToTakeSlowCaseMinimumCount;
+unsigned couldTakeSlowCaseMinimumCount;
 
 unsigned largeFailCountThresholdBase;
 unsigned largeFailCountThresholdBaseForLoop;
@@ -141,8 +143,10 @@
 
     SET(desiredSpeculativeSuccessFailRatio, 6);
     
-    SET(likelyToTakeSlowCaseThreshold, 100);
-    SET(couldTakeSlowCaseThreshold,    10); // Shouldn't be zero because some ops will spuriously take slow case, for example for linking or caching.
+    SET(likelyToTakeSlowCaseThreshold,    0.15);
+    SET(couldTakeSlowCaseThreshold,       0.05); // Shouldn't be zero because some ops will spuriously take slow case, for example for linking or caching.
+    SET(likelyToTakeSlowCaseMinimumCount, 100);
+    SET(couldTakeSlowCaseMinimumCount,    10);
 
     SET(largeFailCountThresholdBase,        20);
     SET(largeFailCountThresholdBaseForLoop, 1);

Modified: trunk/Source/_javascript_Core/runtime/Heuristics.h (102488 => 102489)


--- trunk/Source/_javascript_Core/runtime/Heuristics.h	2011-12-09 23:53:35 UTC (rev 102488)
+++ trunk/Source/_javascript_Core/runtime/Heuristics.h	2011-12-10 00:09:55 UTC (rev 102489)
@@ -48,8 +48,10 @@
 
 extern unsigned desiredSpeculativeSuccessFailRatio;
 
-extern unsigned likelyToTakeSlowCaseThreshold;
-extern unsigned couldTakeSlowCaseThreshold;
+extern double likelyToTakeSlowCaseThreshold;
+extern double couldTakeSlowCaseThreshold;
+extern unsigned likelyToTakeSlowCaseMinimumCount;
+extern unsigned couldTakeSlowCaseMinimumCount;
 
 extern unsigned largeFailCountThresholdBase;
 extern unsigned largeFailCountThresholdBaseForLoop;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to