diff options
Diffstat (limited to 'Source/JavaScriptCore/bytecode')
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.cpp | 71 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.h | 11 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ExecutionCounter.cpp | 21 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ExecutionCounter.h | 2 |
4 files changed, 62 insertions, 43 deletions
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index bcbb51f63..e0a4da71d 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -2104,26 +2104,7 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor) } #endif -#if ENABLE(DFG_JIT) - if (hasCodeOrigins()) { - // Make sure that executables that we have inlined don't die. - // FIXME: If they would have otherwise died, we should probably trigger recompilation. - for (size_t i = 0; i < inlineCallFrames().size(); ++i) { - InlineCallFrame& inlineCallFrame = inlineCallFrames()[i]; - visitor.append(&inlineCallFrame.executable); - visitor.append(&inlineCallFrame.callee); - } - } - - m_lazyOperandValueProfiles.computeUpdatedPredictions(Collection); -#endif - -#if ENABLE(VALUE_PROFILER) - for (unsigned profileIndex = 0; profileIndex < numberOfArgumentValueProfiles(); ++profileIndex) - valueProfileForArgument(profileIndex)->computeUpdatedPrediction(Collection); - for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex) - valueProfile(profileIndex)->computeUpdatedPrediction(Collection); -#endif + updateAllPredictions(Collection); } void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor) @@ -2574,21 +2555,11 @@ bool FunctionCodeBlock::jitCompileImpl(ExecState* exec) #endif #if ENABLE(VALUE_PROFILER) -bool CodeBlock::shouldOptimizeNow() +void CodeBlock::updateAllPredictionsAndCountLiveness( + OperationInProgress operation, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles) { -#if ENABLE(JIT_VERBOSE_OSR) - dataLog("Considering optimizing %p...\n", this); -#endif - -#if ENABLE(VERBOSE_VALUE_PROFILE) - dumpValueProfiles(); -#endif - - if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay) - return true; - - unsigned numberOfLiveNonArgumentValueProfiles = 0; - unsigned numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full. + numberOfLiveNonArgumentValueProfiles = 0; + numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full. for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) { ValueProfile* profile = getFromAllValueProfiles(i); unsigned numSamples = profile->totalNumberOfSamples(); @@ -2596,13 +2567,41 @@ bool CodeBlock::shouldOptimizeNow() numSamples = ValueProfile::numberOfBuckets; // We don't want profiles that are extremely hot to be given more weight. numberOfSamplesInProfiles += numSamples; if (profile->m_bytecodeOffset < 0) { - profile->computeUpdatedPrediction(); + profile->computeUpdatedPrediction(operation); continue; } if (profile->numberOfSamples() || profile->m_prediction != SpecNone) numberOfLiveNonArgumentValueProfiles++; - profile->computeUpdatedPrediction(); + profile->computeUpdatedPrediction(operation); } + +#if ENABLE(DFG_JIT) + m_lazyOperandValueProfiles.computeUpdatedPredictions(operation); +#endif +} + +void CodeBlock::updateAllPredictions(OperationInProgress operation) +{ + unsigned ignoredValue1, ignoredValue2; + updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2); +} + +bool CodeBlock::shouldOptimizeNow() +{ +#if ENABLE(JIT_VERBOSE_OSR) + dataLog("Considering optimizing %p...\n", this); +#endif + +#if ENABLE(VERBOSE_VALUE_PROFILE) + dumpValueProfiles(); +#endif + + if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay) + return true; + + unsigned numberOfLiveNonArgumentValueProfiles; + unsigned numberOfSamplesInProfiles; + updateAllPredictionsAndCountLiveness(NoOperation, numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles); #if ENABLE(JIT_VERBOSE_OSR) dataLog("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles()); diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index b73dcb2b6..4e4fee2b7 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -913,9 +913,9 @@ namespace JSC { m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon, this); } - int32_t llintExecuteCounter() const + const ExecutionCounter& llintExecuteCounter() const { - return m_llintExecuteCounter.m_counter; + return m_llintExecuteCounter; } // Functions for controlling when tiered compilation kicks in. This @@ -971,7 +971,7 @@ namespace JSC { static ptrdiff_t offsetOfJITExecutionActiveThreshold() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_activeThreshold); } static ptrdiff_t offsetOfJITExecutionTotalCount() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_totalCount); } - int32_t jitExecuteCounter() const { return m_jitExecuteCounter.m_counter; } + const ExecutionCounter& jitExecuteCounter() const { return m_jitExecuteCounter; } unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; } @@ -1100,8 +1100,10 @@ namespace JSC { #if ENABLE(VALUE_PROFILER) bool shouldOptimizeNow(); + void updateAllPredictions(OperationInProgress = NoOperation); #else bool shouldOptimizeNow() { return false; } + void updateAllPredictions(OperationInProgress = NoOperation) { } #endif #if ENABLE(JIT) @@ -1134,6 +1136,9 @@ namespace JSC { #else void tallyFrequentExitSites() { } #endif +#if ENABLE(VALUE_PROFILER) + void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles); +#endif void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&); diff --git a/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp index ea335005e..1f2e8260a 100644 --- a/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp +++ b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp @@ -28,6 +28,7 @@ #include "CodeBlock.h" #include "ExecutableAllocator.h" +#include <wtf/StringExtras.h> namespace JSC { @@ -125,7 +126,7 @@ bool ExecutionCounter::setThreshold(CodeBlock* codeBlock) ASSERT(!hasCrossedThreshold(codeBlock)); // Compute the true total count. - double trueTotalCount = static_cast<double>(m_totalCount) + m_counter; + double trueTotalCount = count(); // Correct the threshold for current memory usage. double threshold = applyMemoryUsageHeuristics(m_activeThreshold, codeBlock); @@ -143,9 +144,14 @@ bool ExecutionCounter::setThreshold(CodeBlock* codeBlock) return true; } - if (threshold > std::numeric_limits<int32_t>::max()) - threshold = std::numeric_limits<int32_t>::max(); - + 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); m_totalCount = trueTotalCount + threshold; @@ -160,5 +166,12 @@ void ExecutionCounter::reset() m_activeThreshold = 0; } +const char* ExecutionCounter::status() const +{ + static char result[80]; + snprintf(result, sizeof(result), "%lf/%lf, %d", count(), static_cast<double>(m_activeThreshold), m_counter); + return result; +} + } // namespace JSC diff --git a/Source/JavaScriptCore/bytecode/ExecutionCounter.h b/Source/JavaScriptCore/bytecode/ExecutionCounter.h index d2ffbb649..1c0d23f0f 100644 --- a/Source/JavaScriptCore/bytecode/ExecutionCounter.h +++ b/Source/JavaScriptCore/bytecode/ExecutionCounter.h @@ -38,6 +38,8 @@ public: bool checkIfThresholdCrossedAndSet(CodeBlock*); void setNewThreshold(int32_t threshold, CodeBlock*); void deferIndefinitely(); + double count() const { return static_cast<double>(m_totalCount) + m_counter; } + const char* status() const; static double applyMemoryUsageHeuristics(int32_t value, CodeBlock*); static int32_t applyMemoryUsageHeuristicsAndConvertToInt(int32_t value, CodeBlock*); |