ValueProfile::computeUpdatedPrediction doesn't merge statistics correctly
https://bugs.webkit.org/show_bug.cgi?id=69906
Reviewed by Gavin Barraclough.
It turns out that the simplest fix is to switch computeUpdatedPredictions()
to using predictionFromValue() combined with mergePrediction(). Doing so
allowed me to kill off weakBuckets and visitWeakReferences(). Hence this
not only fixes a performance bug but kills off a lot of code that I never
liked to begin with.
This appears to be a 1% win on V8.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::visitAggregate):
* bytecode/CodeBlock.h:
* bytecode/PredictedType.cpp:
(JSC::predictionFromValue):
* bytecode/ValueProfile.cpp:
(JSC::ValueProfile::computeStatistics):
(JSC::ValueProfile::computeUpdatedPrediction):
* bytecode/ValueProfile.h:
(JSC::ValueProfile::classInfo):
(JSC::ValueProfile::numberOfSamples):
(JSC::ValueProfile::isLive):
(JSC::ValueProfile::dump):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@97294 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/ValueProfile.h b/Source/JavaScriptCore/bytecode/ValueProfile.h
index a1e85ee..58a7fd7 100644
--- a/Source/JavaScriptCore/bytecode/ValueProfile.h
+++ b/Source/JavaScriptCore/bytecode/ValueProfile.h
@@ -61,14 +61,14 @@
return 0;
return value.asCell()->structure()->classInfo();
}
- return m_weakBuckets[bucket].getClassInfo();
+ return 0;
}
unsigned numberOfSamples() const
{
unsigned result = 0;
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!JSValue::decode(m_buckets[i]) || !!m_weakBuckets[i])
+ if (!!JSValue::decode(m_buckets[i]))
result++;
}
return result;
@@ -82,7 +82,7 @@
bool isLive() const
{
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!JSValue::decode(m_buckets[i]) || !!m_weakBuckets[i])
+ if (!!JSValue::decode(m_buckets[i]))
return true;
}
return false;
@@ -239,19 +239,14 @@
bool first = true;
for (unsigned i = 0; i < numberOfBuckets; ++i) {
JSValue value = JSValue::decode(m_buckets[i]);
- if (!!value || !!m_weakBuckets[i]) {
+ if (!!value) {
if (first) {
fprintf(out, ": ");
first = false;
} else
fprintf(out, ", ");
- }
-
- if (!!value)
fprintf(out, "%s", value.description());
-
- if (!!m_weakBuckets[i])
- fprintf(out, "DeadCell");
+ }
}
}
#endif
@@ -290,70 +285,6 @@
unsigned m_numberOfSamplesInPrediction;
EncodedJSValue m_buckets[numberOfBuckets];
-
- class WeakBucket {
- public:
- WeakBucket()
- : m_value(0)
- {
- }
-
- WeakBucket(Structure* structure)
- : m_value(reinterpret_cast<uintptr_t>(structure))
- {
- }
-
- WeakBucket(const ClassInfo* classInfo)
- : m_value(reinterpret_cast<uintptr_t>(classInfo) | 1)
- {
- }
-
- bool operator!() const
- {
- return !m_value;
- }
-
- bool isEmpty() const
- {
- return !m_value;
- }
-
- bool isClassInfo() const
- {
- return !!(m_value & 1);
- }
-
- bool isStructure() const
- {
- return !isEmpty() && !isClassInfo();
- }
-
- Structure* asStructure() const
- {
- ASSERT(isStructure());
- return reinterpret_cast<Structure*>(m_value);
- }
-
- const ClassInfo* asClassInfo() const
- {
- ASSERT(isClassInfo());
- return reinterpret_cast<ClassInfo*>(m_value & ~static_cast<uintptr_t>(1));
- }
-
- const ClassInfo* getClassInfo() const
- {
- if (isEmpty())
- return 0;
- if (isClassInfo())
- return asClassInfo();
- return asStructure()->classInfo();
- }
-
- private:
- uintptr_t m_value;
- };
-
- WeakBucket m_weakBuckets[numberOfBuckets]; // this is not covered by a write barrier because it is only set from GC
};
inline int getValueProfileBytecodeOffset(ValueProfile* valueProfile)