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;