Title: [99910] trunk/Source/_javascript_Core
Revision
99910
Author
[email protected]
Date
2011-11-10 15:59:31 -0800 (Thu, 10 Nov 2011)

Log Message

ValueProfile/PredictedType contains dead code, and doesn't recognize functions
https://bugs.webkit.org/show_bug.cgi?id=72065

Reviewed by Gavin Barraclough and Geoff Garen.
        
Added PredictFunction support, and did some cleaning up along the way.
ValueProfile no longer has statistics machinery, because we never used
it. Rearranged some bits in PredictedType to more easily make room for
one more object type. Changed some debug code to use more consistent
conventions (ByteArray becomes Bytearray so that if we ever have a
"Byte" prediction we don't get confused between a prediction that is
the union of Byte and Array and a prediction that indicates precisely
a ByteArray).

* bytecode/PredictedType.cpp:
(JSC::predictionToString):
(JSC::predictionFromClassInfo):
* bytecode/PredictedType.h:
(JSC::isFunctionPrediction):
* bytecode/ValueProfile.cpp:
* bytecode/ValueProfile.h:
(JSC::ValueProfile::dump):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (99909 => 99910)


--- trunk/Source/_javascript_Core/ChangeLog	2011-11-10 23:47:29 UTC (rev 99909)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-11-10 23:59:31 UTC (rev 99910)
@@ -1,3 +1,32 @@
+2011-11-10  Filip Pizlo  <[email protected]>
+
+        ValueProfile/PredictedType contains dead code, and doesn't recognize functions
+        https://bugs.webkit.org/show_bug.cgi?id=72065
+
+        Reviewed by Gavin Barraclough and Geoff Garen.
+        
+        Added PredictFunction support, and did some cleaning up along the way.
+        ValueProfile no longer has statistics machinery, because we never used
+        it. Rearranged some bits in PredictedType to more easily make room for
+        one more object type. Changed some debug code to use more consistent
+        conventions (ByteArray becomes Bytearray so that if we ever have a
+        "Byte" prediction we don't get confused between a prediction that is
+        the union of Byte and Array and a prediction that indicates precisely
+        a ByteArray).
+
+        * bytecode/PredictedType.cpp:
+        (JSC::predictionToString):
+        (JSC::predictionFromClassInfo):
+        * bytecode/PredictedType.h:
+        (JSC::isFunctionPrediction):
+        * bytecode/ValueProfile.cpp:
+        * bytecode/ValueProfile.h:
+        (JSC::ValueProfile::dump):
+        * dfg/DFGAbstractState.cpp:
+        (JSC::DFG::AbstractState::execute):
+        * dfg/DFGPropagator.cpp:
+        (JSC::DFG::Propagator::propagateNodePredictions):
+
 2011-11-10  David Kilzer  <[email protected]>
 
         <http://webkit.org/b/72049> Specify testapi.js install path using _javascript_CORE_FRAMEWORKS_DIR

Modified: trunk/Source/_javascript_Core/bytecode/PredictedType.cpp (99909 => 99910)


--- trunk/Source/_javascript_Core/bytecode/PredictedType.cpp	2011-11-10 23:47:29 UTC (rev 99909)
+++ trunk/Source/_javascript_Core/bytecode/PredictedType.cpp	2011-11-10 23:59:31 UTC (rev 99910)
@@ -30,6 +30,7 @@
 #include "PredictedType.h"
 
 #include "JSByteArray.h"
+#include "JSFunction.h"
 #include "ValueProfile.h"
 #include <wtf/BoundsCheckedPointer.h>
 
@@ -68,10 +69,15 @@
         isTop = false;
     
     if (value & PredictByteArray)
-        ptr.strcat("ByteArray");
+        ptr.strcat("Bytearray");
     else
         isTop = false;
     
+    if (value & PredictFunction)
+        ptr.strcat("Function");
+    else
+        isTop = false;
+    
     if (value & PredictString)
         ptr.strcat("String");
     else
@@ -116,6 +122,9 @@
     
     if (classInfo == &JSString::s_info)
         return PredictString;
+    
+    if (classInfo->isSubClassOf(&JSFunction::s_info))
+        return PredictFunction;
 
     if (classInfo->isSubClassOf(&JSByteArray::s_info))
         return PredictByteArray;

Modified: trunk/Source/_javascript_Core/bytecode/PredictedType.h (99909 => 99910)


--- trunk/Source/_javascript_Core/bytecode/PredictedType.h	2011-11-10 23:47:29 UTC (rev 99909)
+++ trunk/Source/_javascript_Core/bytecode/PredictedType.h	2011-11-10 23:59:31 UTC (rev 99910)
@@ -39,8 +39,9 @@
 static const PredictedType PredictNone          = 0x0000; // We don't know anything yet.
 static const PredictedType PredictFinalObject   = 0x0001; // It's definitely a JSFinalObject.
 static const PredictedType PredictArray         = 0x0002; // It's definitely a JSArray.
-static const PredictedType PredictByteArray     = 0x0004; // It's definitely a JSByteArray.
-static const PredictedType PredictObjectOther   = 0x0010; // It's definitely an object but not JSFinalObject or JSArray.
+static const PredictedType PredictByteArray     = 0x0004; // It's definitely a JSByteArray or one of its subclasses.
+static const PredictedType PredictFunction      = 0x0008; // It's definitely a JSFunction or one of its subclasses.
+static const PredictedType PredictObjectOther   = 0x0020; // It's definitely an object but not JSFinalObject, JSArray, JSByteArray, or JSFunction.
 static const PredictedType PredictObjectMask    = 0x003f; // Bitmask used for testing for any kind of object prediction.
 static const PredictedType PredictString        = 0x0040; // It's definitely a JSString.
 static const PredictedType PredictCellOther     = 0x0080; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
@@ -84,6 +85,11 @@
     return value == PredictArray;
 }
 
+inline bool isFunctionPrediction(PredictedType value)
+{
+    return value == PredictFunction;
+}
+
 inline bool isByteArrayPrediction(PredictedType value)
 {
     return value == PredictByteArray;

Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp (99909 => 99910)


--- trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp	2011-11-10 23:47:29 UTC (rev 99909)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp	2011-11-10 23:59:31 UTC (rev 99910)
@@ -32,51 +32,6 @@
 namespace JSC {
 
 #if ENABLE(VALUE_PROFILER)
-void ValueProfile::computeStatistics(const ClassInfo* classInfo, Statistics& statistics)
-{
-    statistics.cells++;
-    
-    if (classInfo == &JSFinalObject::s_info) {
-        statistics.finalObjects++;
-        statistics.objects++;
-        return;
-    }
-    
-    if (classInfo == &JSArray::s_info) {
-        statistics.arrays++;
-        statistics.objects++;
-        return;
-    }
-    
-    if (classInfo == &JSString::s_info) {
-        statistics.strings++;
-        return;
-    }
-    
-    if (classInfo->isSubClassOf(&JSObject::s_info))
-        statistics.objects++;
-}
-
-void ValueProfile::computeStatistics(Statistics& statistics) const
-{
-    for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-        JSValue value = JSValue::decode(m_buckets[i]);
-        if (!value)
-            continue;
-        
-        statistics.samples++;
-        
-        if (value.isInt32())
-            statistics.int32s++;
-        else if (value.isDouble())
-            statistics.doubles++;
-        else if (value.isCell())
-            computeStatistics(value.asCell()->structure()->classInfo(), statistics);
-        else if (value.isBoolean())
-            statistics.booleans++;
-    }
-}
-
 PredictedType ValueProfile::computeUpdatedPrediction()
 {
     for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {

Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (99909 => 99910)


--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-11-10 23:47:29 UTC (rev 99909)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-11-10 23:59:31 UTC (rev 99910)
@@ -43,8 +43,6 @@
     static const unsigned numberOfSpecFailBuckets = 1;
     static const unsigned bucketIndexMask = numberOfBuckets - 1;
     static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets;
-    static const unsigned certainty = totalNumberOfBuckets * totalNumberOfBuckets;
-    static const unsigned majority = certainty / 2;
     
     ValueProfile(int bytecodeOffset)
         : m_bytecodeOffset(bytecodeOffset)
@@ -96,154 +94,13 @@
         return false;
     }
     
-    static unsigned computeProbability(unsigned counts, unsigned numberOfSamples)
-    {
-        if (!numberOfSamples)
-            return 0;
-        return counts * certainty / numberOfSamples;
-    }
-    
-    unsigned numberOfInt32s() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            if (JSValue::decode(m_buckets[i]).isInt32())
-                result++;
-        }
-        return result;
-    }
-        
-    unsigned numberOfDoubles() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            if (JSValue::decode(m_buckets[i]).isDouble())
-                result++;
-        }
-        return result;
-    }
-        
-    unsigned numberOfCells() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            if (!!classInfo(i))
-                result++;
-        }
-        return result;
-    }
-    
-    unsigned numberOfObjects() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            const ClassInfo* ci = classInfo(i);
-            if (!!ci && ci->isSubClassOf(&JSObject::s_info))
-                result++;
-        }
-        return result;
-    }
-    
-    unsigned numberOfFinalObjects() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            if (classInfo(i) == &JSFinalObject::s_info)
-                result++;
-        }
-        return result;
-    }
-    
-    unsigned numberOfStrings() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            if (classInfo(i) == &JSString::s_info)
-                result++;
-        }
-        return result;
-    }
-    
-    unsigned numberOfArrays() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            if (classInfo(i) == &JSArray::s_info)
-                result++;
-        }
-        return result;
-    }
-    
-    unsigned numberOfBooleans() const
-    {
-        unsigned result = 0;
-        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
-            if (JSValue::decode(m_buckets[i]).isBoolean())
-                result++;
-        }
-        return result;
-    }
-        
-    // These methods are not particularly optimized, in that they will each
-    // perform two passes over the buckets array. However, they are
-    // probably the best bet unless you are sure that you will be making
-    // these calls with high frequency.
-        
-    unsigned probabilityOfInt32() const
-    {
-        return computeProbability(numberOfInt32s(), numberOfSamples());
-    }
-        
-    unsigned probabilityOfDouble() const
-    {
-        return computeProbability(numberOfDoubles(), numberOfSamples());
-    }
-    
-    unsigned probabilityOfCell() const
-    {
-        return computeProbability(numberOfCells(), numberOfSamples());
-    }
-    
-    unsigned probabilityOfObject() const
-    {
-        return computeProbability(numberOfObjects(), numberOfSamples());
-    }
-    
-    unsigned probabilityOfFinalObject() const
-    {
-        return computeProbability(numberOfFinalObjects(), numberOfSamples());
-    }
-    
-    unsigned probabilityOfArray() const
-    {
-        return computeProbability(numberOfArrays(), numberOfSamples());
-    }
-    
-    unsigned probabilityOfString() const
-    {
-        return computeProbability(numberOfStrings(), numberOfSamples());
-    }
-    
-    unsigned probabilityOfBoolean() const
-    {
-        return computeProbability(numberOfBooleans(), numberOfSamples());
-    }
-
 #ifndef NDEBUG
     void dump(FILE* out)
     {
         fprintf(out,
-                "samples = %u, int32 = %u (%u), double = %u (%u), cell = %u (%u), object = %u (%u), final object = %u (%u), array = %u (%u), string = %u (%u), boolean = %u (%u), prediction = %s, samples in prediction = %u",
-                numberOfSamples(),
-                probabilityOfInt32(), numberOfInt32s(),
-                probabilityOfDouble(), numberOfDoubles(),
-                probabilityOfCell(), numberOfCells(),
-                probabilityOfObject(), numberOfObjects(),
-                probabilityOfFinalObject(), numberOfFinalObjects(),
-                probabilityOfArray(), numberOfArrays(),
-                probabilityOfString(), numberOfStrings(),
-                probabilityOfBoolean(), numberOfBooleans(),
-                predictionToString(m_prediction), m_numberOfSamplesInPrediction);
+                "samples = %u, prediction = %s",
+                totalNumberOfSamples(),
+                predictionToString(m_prediction));
         bool first = true;
         for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
             JSValue value = JSValue::decode(m_buckets[i]);
@@ -259,31 +116,6 @@
     }
 #endif
     
-    struct Statistics {
-        unsigned samples;
-        unsigned int32s;
-        unsigned doubles;
-        unsigned cells;
-        unsigned objects;
-        unsigned finalObjects;
-        unsigned arrays;
-        unsigned strings;
-        unsigned booleans;
-        
-        Statistics()
-        {
-            bzero(this, sizeof(Statistics));
-        }
-    };
-    
-    // Method for incrementing all relevant statistics for a ClassInfo, except for
-    // incrementing the number of samples, which the caller is responsible for
-    // doing.
-    static void computeStatistics(const ClassInfo*, Statistics&);
-
-    // Optimized method for getting all counts at once.
-    void computeStatistics(Statistics&) const;
-    
     // Updates the prediction and returns the new one.
     PredictedType computeUpdatedPrediction();
     

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (99909 => 99910)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2011-11-10 23:47:29 UTC (rev 99909)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2011-11-10 23:59:31 UTC (rev 99910)
@@ -498,7 +498,7 @@
             destination = source;
             break;
         }
-            
+        
         if (isOtherPrediction(child.prediction())) {
             source.filter(PredictOther);
             destination.set(PredictObjectOther);
@@ -534,7 +534,7 @@
         break;
             
     case GetCallee:
-        forNode(nodeIndex).set(PredictObjectOther);
+        forNode(nodeIndex).set(PredictFunction);
         break;
             
     case GetScopeChain:
@@ -604,12 +604,12 @@
     case CheckMethod:
         // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
         forNode(node.child1()).filter(m_graph.m_methodCheckData[node.methodCheckDataIndex()].structure);
-        forNode(nodeIndex).set(PredictObjectOther);
+        forNode(nodeIndex).set(PredictFunction);
         m_haveStructures = true;
         break;
         
     case CheckFunction:
-        forNode(node.child1()).filter(PredictObjectOther);
+        forNode(node.child1()).filter(PredictFunction);
         // FIXME: Should be able to propagate the fact that we know what the function is.
         break;
             

Modified: trunk/Source/_javascript_Core/dfg/DFGPropagator.cpp (99909 => 99910)


--- trunk/Source/_javascript_Core/dfg/DFGPropagator.cpp	2011-11-10 23:47:29 UTC (rev 99909)
+++ trunk/Source/_javascript_Core/dfg/DFGPropagator.cpp	2011-11-10 23:59:31 UTC (rev 99910)
@@ -526,7 +526,7 @@
         }
             
         case GetCallee: {
-            changed |= setPrediction(PredictObjectOther);
+            changed |= setPrediction(PredictFunction);
             break;
         }
             
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to