Title: [97294] trunk/Source/_javascript_Core
Revision
97294
Author
[email protected]
Date
2011-10-12 13:28:49 -0700 (Wed, 12 Oct 2011)

Log Message

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):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (97293 => 97294)


--- trunk/Source/_javascript_Core/ChangeLog	2011-10-12 20:24:55 UTC (rev 97293)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-10-12 20:28:49 UTC (rev 97294)
@@ -1,3 +1,32 @@
+2011-10-12  Filip Pizlo  <[email protected]>
+
+        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):
+
 2011-10-12  Mark Hahnenberg  <[email protected]>
 
         De-virtualize JSCell::toString

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (97293 => 97294)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-10-12 20:24:55 UTC (rev 97293)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-10-12 20:28:49 UTC (rev 97294)
@@ -1527,8 +1527,6 @@
 
 void CodeBlock::visitAggregate(SlotVisitor& visitor)
 {
-    bool handleWeakReferences = false;
-    
     if (!!m_alternative)
         m_alternative->visitAggregate(visitor);
     visitor.append(&m_globalObject);
@@ -1580,64 +1578,11 @@
 #endif
 
 #if ENABLE(VALUE_PROFILER)
-    for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex) {
-        ValueProfile* profile = ""
-        
-        for (unsigned index = 0; index < ValueProfile::numberOfBuckets; ++index) {
-            if (!profile->m_buckets[index]) {
-                if (!!profile->m_weakBuckets[index])
-                    handleWeakReferences = true;
-                continue;
-            }
-            
-            if (!JSValue::decode(profile->m_buckets[index]).isCell()) {
-                profile->m_weakBuckets[index] = ValueProfile::WeakBucket();
-                continue;
-            }
-            
-            handleWeakReferences = true;
-        }
-    }
+    for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex)
+        valueProfile(profileIndex)->computeUpdatedPrediction();
 #endif
-    
-    if (handleWeakReferences)
-        visitor.addWeakReferenceHarvester(this);
 }
 
-void CodeBlock::visitWeakReferences(SlotVisitor&)
-{
-#if ENABLE(VALUE_PROFILER)
-    for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex) {
-        ValueProfile* profile = ""
-        
-        for (unsigned index = 0; index < ValueProfile::numberOfBuckets; ++index) {
-            if (!!profile->m_buckets[index]) {
-                JSValue value = JSValue::decode(profile->m_buckets[index]);
-                if (!value.isCell())
-                    continue;
-                
-                JSCell* cell = value.asCell();
-                if (Heap::isMarked(cell))
-                    continue;
-                
-                profile->m_buckets[index] = JSValue::encode(JSValue());
-                profile->m_weakBuckets[index] = cell->structure();
-            }
-            
-            ValueProfile::WeakBucket weak = profile->m_weakBuckets[index];
-            if (!weak || weak.isClassInfo())
-                continue;
-            
-            ASSERT(weak.isStructure());
-            if (Heap::isMarked(weak.asStructure()))
-                continue;
-            
-            profile->m_weakBuckets[index] = weak.asStructure()->classInfo();
-        }
-    }
-#endif
-}
-
 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
 {
     ASSERT(bytecodeOffset < m_instructionCount);

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (97293 => 97294)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-10-12 20:24:55 UTC (rev 97293)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-10-12 20:28:49 UTC (rev 97294)
@@ -43,7 +43,6 @@
 #include "PredictionTracker.h"
 #include "RegExpObject.h"
 #include "UString.h"
-#include "WeakReferenceHarvester.h"
 #include "ValueProfile.h"
 #include <wtf/FastAllocBase.h>
 #include <wtf/PassOwnPtr.h>
@@ -232,7 +231,7 @@
     }
 #endif
 
-    class CodeBlock: public WeakReferenceHarvester {
+    class CodeBlock {
         WTF_MAKE_FAST_ALLOCATED;
         friend class JIT;
     protected:
@@ -248,7 +247,6 @@
         PassOwnPtr<CodeBlock> releaseAlternative() { return m_alternative.release(); }
         
         void visitAggregate(SlotVisitor&);
-        void visitWeakReferences(SlotVisitor&);
 
         static void dumpStatistics();
 

Modified: trunk/Source/_javascript_Core/bytecode/PredictedType.cpp (97293 => 97294)


--- trunk/Source/_javascript_Core/bytecode/PredictedType.cpp	2011-10-12 20:24:55 UTC (rev 97293)
+++ trunk/Source/_javascript_Core/bytecode/PredictedType.cpp	2011-10-12 20:28:49 UTC (rev 97294)
@@ -137,6 +137,7 @@
         return predictionFromCell(value.asCell());
     if (value.isBoolean())
         return PredictBoolean;
+    ASSERT(value.isUndefinedOrNull());
     return PredictOther;
 }
 

Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp (97293 => 97294)


--- trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp	2011-10-12 20:24:55 UTC (rev 97293)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp	2011-10-12 20:28:49 UTC (rev 97294)
@@ -61,15 +61,8 @@
 {
     for (unsigned i = 0; i < numberOfBuckets; ++i) {
         JSValue value = JSValue::decode(m_buckets[i]);
-        if (!value) {
-            WeakBucket weakBucket = m_weakBuckets[i];
-            if (!!weakBucket) {
-                statistics.samples++;
-                computeStatistics(weakBucket.getClassInfo(), statistics);
-            }
-            
+        if (!value)
             continue;
-        }
         
         statistics.samples++;
         
@@ -86,40 +79,17 @@
 
 PredictedType ValueProfile::computeUpdatedPrediction()
 {
-    ValueProfile::Statistics statistics;
-    computeStatistics(statistics);
-    
-    PredictedType prediction;
-    
-    if (!statistics.samples)
-        prediction = PredictNone;
-    else if (statistics.int32s == statistics.samples)
-        prediction = PredictInt32;
-    else if (statistics.doubles == statistics.samples)
-        prediction = PredictDouble;
-    else if (statistics.int32s + statistics.doubles == statistics.samples)
-        prediction = PredictNumber;
-    else if (statistics.arrays == statistics.samples)
-        prediction = PredictArray;
-    else if (statistics.finalObjects == statistics.samples)
-        prediction = PredictFinalObject;
-    else if (statistics.strings == statistics.samples)
-        prediction = PredictString;
-    else if (statistics.objects == statistics.samples)
-        prediction = PredictObjectOther;
-    else if (statistics.cells == statistics.samples)
-        prediction = PredictCellOther;
-    else if (statistics.booleans == statistics.samples)
-        prediction = PredictBoolean;
-    else
-        prediction = PredictOther;
-
-    m_numberOfSamplesInPrediction += statistics.samples;
-    mergePrediction(m_prediction, prediction);
     for (unsigned i = 0; i < numberOfBuckets; ++i) {
+        JSValue value = JSValue::decode(m_buckets[i]);
+        if (!value)
+            continue;
+        
+        m_numberOfSamplesInPrediction++;
+        mergePrediction(m_prediction, predictionFromValue(value));
+        
         m_buckets[i] = JSValue::encode(JSValue());
-        m_weakBuckets[i] = WeakBucket();
     }
+    
     return m_prediction;
 }
 #endif // ENABLE(VALUE_PROFILER)

Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (97293 => 97294)


--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-10-12 20:24:55 UTC (rev 97293)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-10-12 20:28:49 UTC (rev 97294)
@@ -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)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to