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;
}