- Revision
- 99375
- Author
- [email protected]
- Date
- 2011-11-06 03:54:59 -0800 (Sun, 06 Nov 2011)
Log Message
Value profiling should just use two buckets
https://bugs.webkit.org/show_bug.cgi?id=71619
Reviewed by Gavin Barraclough.
Added one more configuration options (like Heuristics::minimumOptimizationDelay),
improved debugging in JIT optimization support, changed the number of buckets
in the value profile from 9 to 2, and wrote a more optimal value profiling path
in the old JIT to take advantage of this. It's still possible to play around with
larger numbers of buckets, and we should probably keep this for a little while
until we convince ourselves that using just two buckets is the right call.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::shouldOptimizeNow):
* bytecode/ValueProfile.h:
* jit/JITInlineMethods.h:
(JSC::JIT::emitValueProfilingSite):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/Heuristics.cpp:
(JSC::Heuristics::initializeHeuristics):
* runtime/Heuristics.h:
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (99374 => 99375)
--- trunk/Source/_javascript_Core/ChangeLog 2011-11-06 11:39:12 UTC (rev 99374)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-11-06 11:54:59 UTC (rev 99375)
@@ -1,3 +1,28 @@
+2011-11-05 Filip Pizlo <[email protected]>
+
+ Value profiling should just use two buckets
+ https://bugs.webkit.org/show_bug.cgi?id=71619
+
+ Reviewed by Gavin Barraclough.
+
+ Added one more configuration options (like Heuristics::minimumOptimizationDelay),
+ improved debugging in JIT optimization support, changed the number of buckets
+ in the value profile from 9 to 2, and wrote a more optimal value profiling path
+ in the old JIT to take advantage of this. It's still possible to play around with
+ larger numbers of buckets, and we should probably keep this for a little while
+ until we convince ourselves that using just two buckets is the right call.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::shouldOptimizeNow):
+ * bytecode/ValueProfile.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitValueProfilingSite):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Heuristics.cpp:
+ (JSC::Heuristics::initializeHeuristics):
+ * runtime/Heuristics.h:
+
2011-11-03 Filip Pizlo <[email protected]>
JSC should be able to sample itself in a more flexible way than just sampling flags
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (99374 => 99375)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-11-06 11:39:12 UTC (rev 99374)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-11-06 11:54:59 UTC (rev 99375)
@@ -1956,9 +1956,11 @@
#endif
if ((!numberOfNonArgumentValueProfiles || (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles >= Heuristics::desiredProfileLivenessRate)
- && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= Heuristics::desiredProfileFullnessRate))
+ && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= Heuristics::desiredProfileFullnessRate)
+ && static_cast<unsigned>(m_optimizationDelayCounter) + 1 >= Heuristics::minimumOptimizationDelay)
return true;
+ ASSERT(m_optimizationDelayCounter < std::numeric_limits<uint8_t>::max());
m_optimizationDelayCounter++;
optimizeAfterWarmUp();
return false;
Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (99374 => 99375)
--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2011-11-06 11:39:12 UTC (rev 99374)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2011-11-06 11:54:59 UTC (rev 99375)
@@ -38,7 +38,7 @@
#if ENABLE(VALUE_PROFILER)
struct ValueProfile {
- static const unsigned logNumberOfBuckets = 3; // 8 buckets
+ static const unsigned logNumberOfBuckets = 0; // 1 bucket
static const unsigned numberOfBuckets = 1 << logNumberOfBuckets;
static const unsigned numberOfSpecFailBuckets = 1;
static const unsigned bucketIndexMask = numberOfBuckets - 1;
Modified: trunk/Source/_javascript_Core/jit/JITInlineMethods.h (99374 => 99375)
--- trunk/Source/_javascript_Core/jit/JITInlineMethods.h 2011-11-06 11:39:12 UTC (rev 99374)
+++ trunk/Source/_javascript_Core/jit/JITInlineMethods.h 2011-11-06 11:54:59 UTC (rev 99375)
@@ -462,6 +462,9 @@
return;
const RegisterID value = regT0;
+#if USE(JSVALUE32_64)
+ const RegisterID valueTag = regT1;
+#endif
const RegisterID scratch = regT3;
ValueProfile* valueProfile;
@@ -474,6 +477,19 @@
ASSERT(valueProfile);
+ if (ValueProfile::numberOfBuckets == 1) {
+ // We're in a simple configuration: only one bucket, so we can just do a direct
+ // store.
+#if USE(JSVALUE64)
+ storePtr(value, valueProfile->m_buckets);
+#else
+ EncodedValueDescriptor* descriptor = bitwise_cast<EncodedValueDescriptor*>(valueProfile->m_buckets);
+ store32(value, &descriptor->asBits.payload);
+ store32(valueTag, &descriptor->asBits.tag);
+#endif
+ return;
+ }
+
if (m_randomGenerator.getUint32() & 1)
add32(Imm32(1), bucketCounterRegister);
else
@@ -483,7 +499,6 @@
#if USE(JSVALUE64)
storePtr(value, BaseIndex(scratch, bucketCounterRegister, TimesEight));
#elif USE(JSVALUE32_64)
- const RegisterID valueTag = regT1;
store32(value, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
store32(valueTag, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
#endif
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (99374 => 99375)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-11-06 11:39:12 UTC (rev 99374)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-11-06 11:54:59 UTC (rev 99375)
@@ -1958,7 +1958,7 @@
if (void* address = DFG::prepareOSREntry(callFrame, optimizedCodeBlock, bytecodeIndex)) {
#if ENABLE(JIT_VERBOSE_OSR)
- printf("Optimizing %p from loop succeeded, performing OSR.\n", codeBlock);
+ printf("Optimizing %p from loop succeeded, performing OSR after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
#endif
codeBlock->optimizeSoon();
@@ -1968,7 +1968,7 @@
}
#if ENABLE(JIT_VERBOSE_OSR)
- printf("Optimizing %p from loop succeeded, OSR failed.\n", codeBlock);
+ printf("Optimizing %p from loop succeeded, OSR failed, after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
#endif
// Count the OSR failure as a speculation failure. If this happens a lot, then
@@ -2058,7 +2058,7 @@
ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
#if ENABLE(JIT_VERBOSE_OSR)
- printf("Optimizing %p from return succeeded.\n", codeBlock);
+ printf("Optimizing %p from return succeeded after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
#endif
codeBlock->optimizeSoon();
Modified: trunk/Source/_javascript_Core/runtime/Heuristics.cpp (99374 => 99375)
--- trunk/Source/_javascript_Core/runtime/Heuristics.cpp 2011-11-06 11:39:12 UTC (rev 99374)
+++ trunk/Source/_javascript_Core/runtime/Heuristics.cpp 2011-11-06 11:54:59 UTC (rev 99375)
@@ -74,6 +74,7 @@
unsigned reoptimizationRetryCounterMax;
unsigned reoptimizationRetryCounterStep;
+unsigned minimumOptimizationDelay;
unsigned maximumOptimizationDelay;
double desiredProfileLivenessRate;
double desiredProfileFullnessRate;
@@ -157,6 +158,7 @@
SET(reoptimizationRetryCounterStep, 1);
+ SET(minimumOptimizationDelay, 1);
SET(maximumOptimizationDelay, 5);
SET(desiredProfileLivenessRate, 0.75);
SET(desiredProfileFullnessRate, 0.35);
Modified: trunk/Source/_javascript_Core/runtime/Heuristics.h (99374 => 99375)
--- trunk/Source/_javascript_Core/runtime/Heuristics.h 2011-11-06 11:39:12 UTC (rev 99374)
+++ trunk/Source/_javascript_Core/runtime/Heuristics.h 2011-11-06 11:54:59 UTC (rev 99375)
@@ -60,6 +60,7 @@
extern unsigned reoptimizationRetryCounterMax;
extern unsigned reoptimizationRetryCounterStep;
+extern unsigned minimumOptimizationDelay;
extern unsigned maximumOptimizationDelay;
extern double desiredProfileLivenessRate;
extern double desiredProfileFullnessRate;