summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGAbstractValue.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-25 15:09:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-25 15:09:11 +0200
commita89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd (patch)
treeb7abd9f49ae1d4d2e426a5883bfccd42b8e2ee12 /Source/JavaScriptCore/dfg/DFGAbstractValue.h
parent8d473cf9743f1d30a16a27114e93bd5af5648d23 (diff)
downloadqtwebkit-a89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd.tar.gz
Imported WebKit commit eb5c1b8fe4d4b1b90b5137433fc58a91da0e6878 (http://svn.webkit.org/repository/webkit/trunk@118516)
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGAbstractValue.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractValue.h112
1 files changed, 104 insertions, 8 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.h b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
index 682c7a90f..c61a383eb 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -317,18 +317,23 @@ struct AbstractValue {
{
m_type = PredictNone;
m_structure.clear();
+ m_value = JSValue();
checkConsistency();
}
- bool isClear()
+ bool isClear() const
{
- return m_type == PredictNone && m_structure.isClear();
+ bool result = m_type == PredictNone && m_structure.isClear();
+ if (result)
+ ASSERT(!m_value);
+ return result;
}
void makeTop()
{
m_type = PredictTop;
m_structure.makeTop();
+ m_value = JSValue();
checkConsistency();
}
@@ -341,11 +346,26 @@ struct AbstractValue {
checkConsistency();
}
+ void clobberValue()
+ {
+ m_value = JSValue();
+ }
+
bool isTop() const
{
return m_type == PredictTop && m_structure.isTop();
}
+ bool valueIsTop() const
+ {
+ return !m_value && m_type;
+ }
+
+ JSValue value() const
+ {
+ return m_value;
+ }
+
static AbstractValue top()
{
AbstractValue result;
@@ -355,11 +375,19 @@ struct AbstractValue {
void set(JSValue value)
{
- m_structure.clear();
- if (value.isCell())
- m_structure.add(value.asCell()->structure());
+ if (!!value && value.isCell()) {
+ // Have to be careful here! It's tempting to set the structure to the
+ // value's structure, but that would be wrong, since that would
+ // constitute a proof that this value will always have the same
+ // structure. The whole point of a value having a structure is that
+ // it may change in the future - for example between when we compile
+ // the code and when we run it.
+ m_structure.makeTop();
+ } else
+ m_structure.clear();
m_type = predictionFromValue(value);
+ m_value = value;
checkConsistency();
}
@@ -370,6 +398,7 @@ struct AbstractValue {
m_structure.add(structure);
m_type = predictionFromStructure(structure);
+ m_value = JSValue();
checkConsistency();
}
@@ -381,18 +410,40 @@ struct AbstractValue {
else
m_structure.clear();
m_type = type;
+ m_value = JSValue();
checkConsistency();
}
bool operator==(const AbstractValue& other) const
{
- return m_type == other.m_type && m_structure == other.m_structure;
+ return m_type == other.m_type
+ && m_structure == other.m_structure
+ && m_value == other.m_value;
+ }
+ bool operator!=(const AbstractValue& other) const
+ {
+ return !(*this == other);
}
bool merge(const AbstractValue& other)
{
- bool result = mergePrediction(m_type, other.m_type) | m_structure.addAll(other.m_structure);
+#if !ASSERT_DISABLED
+ AbstractValue oldMe = *this;
+#endif
+ bool result = false;
+ if (isClear()) {
+ *this = other;
+ result = !other.isClear();
+ } else {
+ result |= mergePrediction(m_type, other.m_type);
+ result |= m_structure.addAll(other.m_structure);
+ if (m_value != other.m_value) {
+ result |= !!m_value;
+ m_value = JSValue();
+ }
+ }
checkConsistency();
+ ASSERT(result == (*this != oldMe));
return result;
}
@@ -402,6 +453,7 @@ struct AbstractValue {
if (type & PredictCell)
m_structure.makeTop();
+ m_value = JSValue();
checkConsistency();
}
@@ -417,6 +469,10 @@ struct AbstractValue {
// sure that new information gleaned from the PredictedType needs to be fed back
// into the information gleaned from the StructureSet.
m_structure.filter(m_type);
+
+ if (!!m_value && !validateIgnoringValue(m_value))
+ clear();
+
checkConsistency();
}
@@ -431,14 +487,45 @@ struct AbstractValue {
// to ensure that the structure filtering does the right thing is to filter on
// the new type (None) rather than the one passed (Array).
m_structure.filter(m_type);
+
+ if (!!m_value && !validateIgnoringValue(m_value))
+ clear();
+
checkConsistency();
}
+ bool validateIgnoringValue(JSValue value) const
+ {
+ if (isTop())
+ return true;
+
+ if (mergePredictions(m_type, predictionFromValue(value)) != m_type)
+ return false;
+
+ if (value.isEmpty()) {
+ ASSERT(m_type & PredictEmpty);
+ return true;
+ }
+
+ if (m_structure.isTop())
+ return true;
+
+ if (!!value && value.isCell()) {
+ ASSERT(m_type & PredictCell);
+ return m_structure.contains(value.asCell()->structure());
+ }
+
+ return true;
+ }
+
bool validate(JSValue value) const
{
if (isTop())
return true;
+ if (!!m_value)
+ return m_value == value;
+
if (mergePredictions(m_type, predictionFromValue(value)) != m_type)
return false;
@@ -450,7 +537,7 @@ struct AbstractValue {
if (m_structure.isTop())
return true;
- if (value.isCell()) {
+ if (!!value && value.isCell()) {
ASSERT(m_type & PredictCell);
return m_structure.contains(value.asCell()->structure());
}
@@ -463,6 +550,12 @@ struct AbstractValue {
if (!(m_type & PredictCell))
ASSERT(m_structure.isClear());
+ if (isClear())
+ ASSERT(!m_value);
+
+ if (!!m_value)
+ ASSERT(mergePredictions(m_type, predictionFromValue(m_value)) == m_type);
+
// Note that it's possible for a prediction like (Final, []). This really means that
// the value is bottom and that any code that uses the value is unreachable. But
// we don't want to get pedantic about this as it would only increase the computational
@@ -473,11 +566,14 @@ struct AbstractValue {
{
fprintf(out, "(%s, ", predictionToString(m_type));
m_structure.dump(out);
+ if (!!m_value)
+ fprintf(out, ", %s", m_value.description());
fprintf(out, ")");
}
StructureAbstractValue m_structure;
PredictedType m_type;
+ JSValue m_value;
};
} } // namespace JSC::DFG