summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecode')
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp71
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h11
-rw-r--r--Source/JavaScriptCore/bytecode/ExecutionCounter.cpp21
-rw-r--r--Source/JavaScriptCore/bytecode/ExecutionCounter.h2
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*);