Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (122181 => 122182)
--- trunk/Source/_javascript_Core/ChangeLog 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-07-10 01:50:44 UTC (rev 122182)
@@ -1,5 +1,45 @@
2012-07-09 Filip Pizlo <[email protected]>
+ Unreviewed, roll out http://trac.webkit.org/changeset/121511
+ It made in-browser V8v7 10% slower.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::countSpeculationSuccess):
+ (JSC::CodeBlock::countSpeculationFailure):
+ (JSC::CodeBlock::speculativeSuccessCounter):
+ (JSC::CodeBlock::speculativeFailCounter):
+ (JSC::CodeBlock::forcedOSRExitCounter):
+ (JSC::CodeBlock::addressOfSpeculativeSuccessCounter):
+ (JSC::CodeBlock::addressOfSpeculativeFailCounter):
+ (JSC::CodeBlock::addressOfForcedOSRExitCounter):
+ (JSC::CodeBlock::offsetOfSpeculativeSuccessCounter):
+ (JSC::CodeBlock::offsetOfSpeculativeFailCounter):
+ (JSC::CodeBlock::offsetOfForcedOSRExitCounter):
+ (JSC::CodeBlock::largeFailCountThreshold):
+ (JSC::CodeBlock::largeFailCountThresholdForLoop):
+ (JSC::CodeBlock::shouldReoptimizeNow):
+ (JSC::CodeBlock::shouldReoptimizeFromLoopNow):
+ * bytecode/ExecutionCounter.cpp:
+ (JSC::ExecutionCounter::setThreshold):
+ * bytecode/ExecutionCounter.h:
+ (ExecutionCounter):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compileBody):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
+ * dfg/DFGOSRExitCompiler.cpp:
+ (JSC::DFG::OSRExitCompiler::handleExitCounts):
+ * dfg/DFGOperations.cpp:
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Options.h:
+ (JSC):
+
+2012-07-09 Filip Pizlo <[email protected]>
+
DFG may get stuck in an infinite fix point if it constant folds a mispredicted node
https://bugs.webkit.org/show_bug.cgi?id=90829
<rdar://problem/11823843>
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (122181 => 122182)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-07-10 01:50:44 UTC (rev 122182)
@@ -1707,7 +1707,9 @@
, m_functionDecls(other.m_functionDecls)
, m_functionExprs(other.m_functionExprs)
, m_symbolTable(symTab)
- , m_osrExitCounter(0)
+ , m_speculativeSuccessCounter(0)
+ , m_speculativeFailCounter(0)
+ , m_forcedOSRExitCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_lineInfo(other.m_lineInfo)
@@ -1762,7 +1764,8 @@
#endif
, m_symbolTable(symTab)
, m_alternative(alternative)
- , m_osrExitCounter(0)
+ , m_speculativeSuccessCounter(0)
+ , m_speculativeFailCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
#if ENABLE(BYTECODE_COMMENTS)
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (122181 => 122182)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-07-10 01:50:44 UTC (rev 122182)
@@ -1092,48 +1092,59 @@
m_jitExecuteCounter.setNewThreshold(Options::thresholdForOptimizeSoon() << reoptimizationRetryCounter(), this);
}
- uint32_t osrExitCounter() const { return m_osrExitCounter; }
+ // The speculative JIT tracks its success rate, so that we can
+ // decide when to reoptimize. It's interesting to note that these
+ // counters may overflow without any protection. The success
+ // counter will overflow before the fail one does, becuase the
+ // fail one is used as a trigger to reoptimize. So the worst case
+ // is that the success counter overflows and we reoptimize without
+ // needing to. But this is harmless. If a method really did
+ // execute 2^32 times then compiling it again probably won't hurt
+ // anyone.
- void countOSRExit() { m_osrExitCounter++; }
-
- uint32_t* addressOfOSRExitCounter() { return &m_osrExitCounter; }
-
- static ptrdiff_t offsetOfOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_osrExitCounter); }
-
-#if ENABLE(JIT)
- uint32_t adjustedExitCountThreshold(uint32_t desiredThreshold)
+ void countSpeculationSuccess()
{
- ASSERT(getJITType() == JITCode::DFGJIT);
- // Compute this the lame way so we don't saturate. This is called infrequently
- // enough that this loop won't hurt us.
- unsigned result = desiredThreshold;
- for (unsigned n = baselineVersion()->reoptimizationRetryCounter(); n--;) {
- unsigned newResult = result << 1;
- if (newResult < result)
- return std::numeric_limits<uint32_t>::max();
- result = newResult;
- }
- return result;
+ m_speculativeSuccessCounter++;
}
- uint32_t exitCountThresholdForReoptimization()
+ void countSpeculationFailure()
{
- return adjustedExitCountThreshold(Options::osrExitCountForReoptimization());
+ m_speculativeFailCounter++;
}
- uint32_t exitCountThresholdForReoptimizationFromLoop()
- {
- return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop());
- }
+ uint32_t speculativeSuccessCounter() const { return m_speculativeSuccessCounter; }
+ uint32_t speculativeFailCounter() const { return m_speculativeFailCounter; }
+ uint32_t forcedOSRExitCounter() const { return m_forcedOSRExitCounter; }
+
+ uint32_t* addressOfSpeculativeSuccessCounter() { return &m_speculativeSuccessCounter; }
+ uint32_t* addressOfSpeculativeFailCounter() { return &m_speculativeFailCounter; }
+ uint32_t* addressOfForcedOSRExitCounter() { return &m_forcedOSRExitCounter; }
+
+ static ptrdiff_t offsetOfSpeculativeSuccessCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeSuccessCounter); }
+ static ptrdiff_t offsetOfSpeculativeFailCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeFailCounter); }
+ static ptrdiff_t offsetOfForcedOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_forcedOSRExitCounter); }
+#if ENABLE(JIT)
+ // The number of failures that triggers the use of the ratio.
+ unsigned largeFailCountThreshold() { return Options::largeFailCountThresholdBase() << baselineVersion()->reoptimizationRetryCounter(); }
+ unsigned largeFailCountThresholdForLoop() { return Options::largeFailCountThresholdBaseForLoop() << baselineVersion()->reoptimizationRetryCounter(); }
+
bool shouldReoptimizeNow()
{
- return osrExitCounter() >= exitCountThresholdForReoptimization();
+ return (Options::desiredSpeculativeSuccessFailRatio() *
+ speculativeFailCounter() >= speculativeSuccessCounter()
+ && speculativeFailCounter() >= largeFailCountThreshold())
+ || forcedOSRExitCounter() >=
+ Options::forcedOSRExitCountForReoptimization();
}
-
+
bool shouldReoptimizeFromLoopNow()
{
- return osrExitCounter() >= exitCountThresholdForReoptimizationFromLoop();
+ return (Options::desiredSpeculativeSuccessFailRatio() *
+ speculativeFailCounter() >= speculativeSuccessCounter()
+ && speculativeFailCounter() >= largeFailCountThresholdForLoop())
+ || forcedOSRExitCounter() >=
+ Options::forcedOSRExitCountForReoptimization();
}
#endif
@@ -1336,7 +1347,9 @@
ExecutionCounter m_jitExecuteCounter;
int32_t m_totalJITExecutions;
- uint32_t m_osrExitCounter;
+ uint32_t m_speculativeSuccessCounter;
+ uint32_t m_speculativeFailCounter;
+ uint32_t m_forcedOSRExitCounter;
uint16_t m_optimizationDelayCounter;
uint16_t m_reoptimizationRetryCounter;
Modified: trunk/Source/_javascript_Core/bytecode/ExecutionCounter.cpp (122181 => 122182)
--- trunk/Source/_javascript_Core/bytecode/ExecutionCounter.cpp 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/bytecode/ExecutionCounter.cpp 2012-07-10 01:50:44 UTC (rev 122182)
@@ -144,7 +144,13 @@
return true;
}
- threshold = clippedThreshold(codeBlock->globalObject(), threshold);
+ int32_t maxThreshold;
+ if (Options::randomizeExecutionCountsBetweenCheckpoints())
+ maxThreshold = codeBlock->globalObject()->weakRandomInteger() % Options::maximumExecutionCountsBetweenCheckpoints();
+ else
+ maxThreshold = Options::maximumExecutionCountsBetweenCheckpoints();
+ if (threshold > maxThreshold)
+ threshold = maxThreshold;
m_counter = static_cast<int32_t>(-threshold);
Modified: trunk/Source/_javascript_Core/bytecode/ExecutionCounter.h (122181 => 122182)
--- trunk/Source/_javascript_Core/bytecode/ExecutionCounter.h 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/bytecode/ExecutionCounter.h 2012-07-10 01:50:44 UTC (rev 122182)
@@ -26,8 +26,6 @@
#ifndef ExecutionCounter_h
#define ExecutionCounter_h
-#include "JSGlobalObject.h"
-#include "Options.h"
#include <wtf/SimpleStats.h>
namespace JSC {
@@ -44,18 +42,6 @@
const char* status() const;
static double applyMemoryUsageHeuristics(int32_t value, CodeBlock*);
static int32_t applyMemoryUsageHeuristicsAndConvertToInt(int32_t value, CodeBlock*);
- template<typename T>
- static T clippedThreshold(JSGlobalObject* globalObject, T threshold)
- {
- int32_t maxThreshold;
- if (Options::randomizeExecutionCountsBetweenCheckpoints())
- maxThreshold = globalObject->weakRandomInteger() % Options::maximumExecutionCountsBetweenCheckpoints();
- else
- maxThreshold = Options::maximumExecutionCountsBetweenCheckpoints();
- if (threshold > maxThreshold)
- threshold = maxThreshold;
- return threshold;
- }
static int32_t formattedTotalCount(float value)
{
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (122181 => 122182)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2012-07-10 01:50:44 UTC (rev 122182)
@@ -88,6 +88,8 @@
breakpoint();
#endif
+ addPtr(TrustedImm32(1), AbsoluteAddress(codeBlock()->addressOfSpeculativeSuccessCounter()));
+
bool compiledSpeculative = speculative.compile();
ASSERT_UNUSED(compiledSpeculative, compiledSpeculative);
}
Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (122181 => 122182)
--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp 2012-07-10 01:50:44 UTC (rev 122182)
@@ -52,7 +52,7 @@
bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
{
- if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
+ if (static_cast<double>(m_count) / dfgCodeBlock->speculativeFailCounter() <= Options::osrExitProminenceForFrequentExitSite())
return false;
FrequentExitSite exitSite;
Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp (122181 => 122182)
--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp 2012-07-10 01:50:44 UTC (rev 122182)
@@ -116,14 +116,42 @@
m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.codeBlock()), GPRInfo::regT0);
- AssemblyHelpers::Jump tooFewFails;
+ AssemblyHelpers::JumpList tooFewFails;
- m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfOSRExitCounter()), GPRInfo::regT2);
- m_jit.add32(AssemblyHelpers::TrustedImm32(1), GPRInfo::regT2);
- m_jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfOSRExitCounter()));
- m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), GPRInfo::regT0);
- tooFewFails = m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(m_jit.codeBlock()->exitCountThresholdForReoptimization()));
+ if (exit.m_kind == InadequateCoverage) {
+ // Proceed based on the assumption that we can profitably optimize this code once
+ // it has executed enough times.
+
+ m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfForcedOSRExitCounter()), GPRInfo::regT2);
+ m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()), GPRInfo::regT1);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(1), GPRInfo::regT2);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(-1), GPRInfo::regT1);
+ m_jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfForcedOSRExitCounter()));
+ m_jit.store32(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()));
+
+ m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), GPRInfo::regT0);
+
+ tooFewFails.append(m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(Options::forcedOSRExitCountForReoptimization())));
+
+ } else {
+ // Proceed based on the assumption that we can handle these exits so long as they
+ // don't get too frequent.
+
+ m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeFailCounter()), GPRInfo::regT2);
+ m_jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()), GPRInfo::regT1);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(1), GPRInfo::regT2);
+ m_jit.add32(AssemblyHelpers::TrustedImm32(-1), GPRInfo::regT1);
+ m_jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeFailCounter()));
+ m_jit.store32(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()));
+ m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), GPRInfo::regT0);
+
+ tooFewFails.append(m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(m_jit.codeBlock()->largeFailCountThreshold())));
+ m_jit.mul32(AssemblyHelpers::TrustedImm32(Options::desiredSpeculativeSuccessFailRatio()), GPRInfo::regT2, GPRInfo::regT2);
+
+ tooFewFails.append(m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, GPRInfo::regT1));
+ }
+
// Reoptimize as soon as possible.
#if !NUMBER_OF_ARGUMENT_REGISTERS
m_jit.poke(GPRInfo::regT0);
@@ -143,7 +171,6 @@
m_jit.baselineCodeBlock()->counterValueForOptimizeAfterLongWarmUp(),
m_jit.baselineCodeBlock());
m_jit.store32(AssemblyHelpers::TrustedImm32(-targetValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
- targetValue = ExecutionCounter::clippedThreshold(m_jit.codeBlock()->globalObject(), targetValue);
m_jit.store32(AssemblyHelpers::TrustedImm32(targetValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
m_jit.store32(AssemblyHelpers::TrustedImm32(ExecutionCounter::formattedTotalCount(targetValue)), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionTotalCount()));
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (122181 => 122182)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-07-10 01:50:44 UTC (rev 122182)
@@ -1306,13 +1306,15 @@
CodeBlock* alternative = codeBlock->alternative();
dataLog("Speculation failure in %p at @%u with executeCounter = %s, "
"reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, "
- "osrExitCounter = %u\n",
+ "success/fail %u/(%u+%u)\n",
codeBlock,
debugInfo->nodeIndex,
alternative ? alternative->jitExecuteCounter().status() : 0,
alternative ? alternative->reoptimizationRetryCounter() : 0,
alternative ? alternative->optimizationDelayCounter() : 0,
- codeBlock->osrExitCounter());
+ codeBlock->speculativeSuccessCounter(),
+ codeBlock->speculativeFailCounter(),
+ codeBlock->forcedOSRExitCounter());
}
#endif
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (122181 => 122182)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-07-10 01:50:44 UTC (rev 122182)
@@ -1940,12 +1940,7 @@
unsigned bytecodeIndex = stackFrame.args[0].int32();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %s, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, exitCounter = ", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter().status(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
- if (codeBlock->hasOptimizedReplacement())
- dataLog("%u", codeBlock->replacement()->osrExitCounter());
- else
- dataLog("N/A");
- dataLog("\n");
+ dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %s, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter().status(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
#endif
if (!codeBlock->checkIfOptimizationThresholdReached()) {
@@ -1955,21 +1950,8 @@
if (codeBlock->hasOptimizedReplacement()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Considering OSR into %p(%p).\n", codeBlock, codeBlock->replacement());
+ dataLog("Considering OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
#endif
- // If we have an optimized replacement, then it must be the case that we entered
- // cti_optimize from a loop. That's because is there's an optimized replacement,
- // then all calls to this function will be relinked to the replacement and so
- // the prologue OSR will never fire.
-
- // This is an interesting threshold check. Consider that a function OSR exits
- // in the middle of a loop, while having a relatively low exit count. The exit
- // will reset the execution counter to some target threshold, meaning that this
- // code won't be reached until that loop heats up for >=1000 executions. But then
- // we do a second check here, to see if we should either reoptimize, or just
- // attempt OSR entry. Hence it might even be correct for
- // shouldReoptimizeFromLoopNow() to always return true. But we make it do some
- // additional checking anyway, to reduce the amount of recompilation thrashing.
if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
#if ENABLE(JIT_VERBOSE_OSR)
dataLog("Triggering reoptimization of %p(%p) (in loop).\n", codeBlock, codeBlock->replacement());
@@ -2015,6 +1997,7 @@
#endif
codeBlock->optimizeSoon();
+ optimizedCodeBlock->countSpeculationSuccess();
STUB_SET_RETURN_ADDRESS(address);
return;
}
@@ -2025,10 +2008,10 @@
// Count the OSR failure as a speculation failure. If this happens a lot, then
// reoptimize.
- optimizedCodeBlock->countOSRExit();
+ optimizedCodeBlock->countSpeculationFailure();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Encountered OSR failure into %p(%p).\n", codeBlock, codeBlock->replacement());
+ dataLog("Encountered OSR failure into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
#endif
// We are a lot more conservative about triggering reoptimization after OSR failure than
Modified: trunk/Source/_javascript_Core/runtime/Options.h (122181 => 122182)
--- trunk/Source/_javascript_Core/runtime/Options.h 2012-07-10 01:46:43 UTC (rev 122181)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2012-07-10 01:50:44 UTC (rev 122182)
@@ -91,15 +91,19 @@
v(bool, randomizeExecutionCountsBetweenCheckpoints, false) \
v(int32, maximumExecutionCountsBetweenCheckpoints, 1000) \
\
+ v(double, desiredSpeculativeSuccessFailRatio, 6) \
+ \
v(double, likelyToTakeSlowCaseThreshold, 0.15) \
v(double, couldTakeSlowCaseThreshold, 0.05) \
v(unsigned, likelyToTakeSlowCaseMinimumCount, 100) \
v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
\
v(double, osrExitProminenceForFrequentExitSite, 0.3) \
- v(unsigned, osrExitCountForReoptimization, 100) \
- v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
\
+ v(unsigned, largeFailCountThresholdBase, 20) \
+ v(unsigned, largeFailCountThresholdBaseForLoop, 1) \
+ v(unsigned, forcedOSRExitCountForReoptimization, 250) \
+ \
v(unsigned, reoptimizationRetryCounterMax, 0) \
v(unsigned, reoptimizationRetryCounterStep, 1) \
\