Diff
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/ChangeLog (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/ChangeLog 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/ChangeLog 2014-02-18 11:39:05 UTC (rev 164282)
@@ -1,5 +1,40 @@
2013-09-10 Filip Pizlo <fpi...@apple.com>
+ Introduce a SpecInt48 type and be more careful about what we mean by "Top"
+ https://bugs.webkit.org/show_bug.cgi?id=121116
+
+ Reviewed by Oliver Hunt.
+
+ SpecInt48 will mean that we have something that would be a double if it was a JSValue,
+ but it's profitable to represent it as something other than a double.
+
+ SpecInt48AsDouble means that it has a value that could have been represented like
+ SpecInt48, but we're making a heuristic decision not to do it.
+
+ * bytecode/SpeculatedType.h:
+ (JSC::isInt48Speculation):
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::::executeEffects):
+ (JSC::DFG::::clobberCapturedVars):
+ * dfg/DFGAbstractValue.cpp:
+ (JSC::DFG::AbstractValue::filter):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::makeHeapTop):
+ (JSC::DFG::AbstractValue::makeBytecodeTop):
+ (JSC::DFG::AbstractValue::isHeapTop):
+ (JSC::DFG::AbstractValue::heapTop):
+ (JSC::DFG::AbstractValue::validateType):
+ (JSC::DFG::AbstractValue::validate):
+ (JSC::DFG::AbstractValue::makeTop):
+ * dfg/DFGInPlaceAbstractState.cpp:
+ (JSC::DFG::InPlaceAbstractState::initialize):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::noticeOSREntry):
+ * dfg/DFGUseKind.h:
+ (JSC::DFG::typeFilterFor):
+
+2013-09-10 Filip Pizlo <fpi...@apple.com>
+
SpecType should have SpecInt48AsDouble
https://bugs.webkit.org/show_bug.cgi?id=121065
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.cpp (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2014-02-18 11:39:05 UTC (rev 164282)
@@ -166,6 +166,11 @@
else
isTop = false;
+ if (value & SpecInt48)
+ myOut.print("Int48");
+ else
+ isTop = false;
+
if (value & SpecNonIntAsDouble)
myOut.print("Nonintasdouble");
else
@@ -240,6 +245,8 @@
return "<Int32>";
if (isInt48AsDoubleSpeculation(prediction))
return "<Int48AsDouble>";
+ if (isInt48Speculation(prediction))
+ return "<Int48>";
if (isDoubleSpeculation(prediction))
return "<Double>";
if (isNumberSpeculation(prediction))
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.h (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.h 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.h 2014-02-18 11:39:05 UTC (rev 164282)
@@ -62,19 +62,21 @@
static const SpeculatedType SpecCellOther = 0x00040000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
static const SpeculatedType SpecCell = 0x0007ffff; // It's definitely a JSCell.
static const SpeculatedType SpecInt32 = 0x00800000; // It's definitely an Int32.
-static const SpeculatedType SpecInt48AsDouble = 0x01000000; // It's definitely an Int48 and it's inside a double.
-static const SpeculatedType SpecInteger = 0x01800000; // It's definitely some kind of integer.
-static const SpeculatedType SpecNonIntAsDouble = 0x02000000; // It's definitely not an Int48 but it's a real number and it's a double.
-static const SpeculatedType SpecDoubleReal = 0x03000000; // It's definitely a non-NaN double.
-static const SpeculatedType SpecDoubleNaN = 0x04000000; // It's definitely a NaN.
-static const SpeculatedType SpecDouble = 0x07000000; // It's either a non-NaN or a NaN double.
-static const SpeculatedType SpecRealNumber = 0x03800000; // It's either an Int32 or a DoubleReal.
-static const SpeculatedType SpecNumber = 0x07800000; // It's either an Int32 or a Double.
-static const SpeculatedType SpecBoolean = 0x08000000; // It's definitely a Boolean.
-static const SpeculatedType SpecOther = 0x10000000; // It's definitely none of the above.
-static const SpeculatedType SpecTop = 0x1fffffff; // It can be any of the above.
-static const SpeculatedType SpecEmpty = 0x20000000; // It's definitely an empty value marker.
-static const SpeculatedType SpecEmptyOrTop = 0x3fffffff; // It can be any of the above.
+static const SpeculatedType SpecInt48 = 0x01000000; // It's definitely an Int48, it's inside a double, but it doesn't need to be.
+static const SpeculatedType SpecInt48AsDouble = 0x02000000; // It's definitely an Int48 and it's inside a double.
+static const SpeculatedType SpecInteger = 0x03800000; // It's definitely some kind of integer.
+static const SpeculatedType SpecNonIntAsDouble = 0x04000000; // It's definitely not an Int48 but it's a real number and it's a double.
+static const SpeculatedType SpecDoubleReal = 0x07000000; // It's definitely a non-NaN double.
+static const SpeculatedType SpecDoubleNaN = 0x08000000; // It's definitely a NaN.
+static const SpeculatedType SpecDouble = 0x0f000000; // It's either a non-NaN or a NaN double.
+static const SpeculatedType SpecRealNumber = 0x07800000; // It's either an Int32 or a DoubleReal.
+static const SpeculatedType SpecNumber = 0x0f800000; // It's either an Int32 or a Double.
+static const SpeculatedType SpecBoolean = 0x10000000; // It's definitely a Boolean.
+static const SpeculatedType SpecOther = 0x20000000; // It's definitely none of the above.
+static const SpeculatedType SpecHeapTop = 0x3fffffff; // It can be any of the above.
+static const SpeculatedType SpecEmpty = 0x40000000; // It's definitely an empty value marker.
+static const SpeculatedType SpecBytecodeTop = 0x7fffffff; // It can be any of the above.
+static const SpeculatedType SpecFullTop = 0x7fffffff; // It can be any of the above plus anything the DFG chooses.
typedef bool (*SpeculatedTypeChecker)(SpeculatedType);
@@ -245,6 +247,11 @@
return isInt32Speculation(value & ~SpecOther);
}
+inline bool isInt48Speculation(SpeculatedType value)
+{
+ return value == SpecInt48;
+}
+
inline bool isInt48AsDoubleSpeculation(SpeculatedType value)
{
return value == SpecInt48AsDouble;
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2014-02-18 11:39:05 UTC (rev 164282)
@@ -143,7 +143,7 @@
ASSERT(m_graph.m_form == SSA);
VariableAccessData* variable = node->variableAccessData();
AbstractValue& value = m_state.variables().operand(variable->local());
- ASSERT(value.isTop());
+ ASSERT(value.isHeapTop());
FiltrationResult result =
value.filter(typeFilterFor(useKindFor(variable->flushFormat())));
ASSERT_UNUSED(result, result == FiltrationOK);
@@ -772,7 +772,7 @@
break;
case Array::Generic:
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case Array::String:
if (node->arrayMode().isOutOfBounds()) {
@@ -787,24 +787,24 @@
// so we're going with TOP for now. The same thing applies to
// clobbering the world.
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
} else
forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
break;
case Array::Arguments:
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case Array::Int32:
if (node->arrayMode().isOutOfBounds()) {
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
} else
forNode(node).setType(SpecInt32);
break;
case Array::Double:
if (node->arrayMode().isOutOfBounds()) {
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
} else if (node->arrayMode().isSaneChain())
forNode(node).setType(SpecDouble);
else
@@ -815,7 +815,7 @@
case Array::SlowPutArrayStorage:
if (node->arrayMode().isOutOfBounds())
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case Array::Int8Array:
forNode(node).setType(SpecInt32);
@@ -896,11 +896,11 @@
case ArrayPop:
node->setCanExit(true);
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case RegExpExec:
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case RegExpTest:
@@ -983,7 +983,7 @@
SpeculatedType type = source.m_type;
if (type & ~(SpecNumber | SpecString | SpecBoolean))
- type = (SpecTop & ~SpecCell) | SpecString;
+ type = (SpecHeapTop & ~SpecCell) | SpecString;
destination.setType(type);
if (destination.isClear())
@@ -1138,7 +1138,7 @@
clobberWorld(node->codeOrigin, clobberLimit);
// We currently make no guarantee about what this returns because it does not
// speculate that the length property is actually a length.
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case GetMyArgumentByVal:
@@ -1146,7 +1146,7 @@
// We know that this executable does not escape its arguments, so we can optimize
// the arguments a bit. Note that this ends up being further optimized by the
// ArgumentsSimplificationPhase.
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case GetMyArgumentByValSafe:
@@ -1155,7 +1155,7 @@
// a getter. We don't speculate against this.
clobberWorld(node->codeOrigin, clobberLimit);
// And the result is unknown.
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case NewFunction: {
@@ -1206,7 +1206,7 @@
break;
case GetClosureVar:
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case PutClosureVar:
@@ -1234,7 +1234,7 @@
if (status.specificValue())
forNode(node).set(m_graph, status.specificValue());
else
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
filter(node->child1(), status.structureSet());
m_state.setFoundConstants(true);
@@ -1243,7 +1243,7 @@
}
}
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case GetArrayLength:
@@ -1401,7 +1401,7 @@
}
case GetByOffset: {
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
}
@@ -1456,7 +1456,7 @@
break;
case GetGlobalVar:
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case GlobalVarWatchpoint:
@@ -1500,7 +1500,7 @@
case Construct:
node->setCanExit(true);
clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).makeTop();
+ forNode(node).makeHeapTop();
break;
case ForceOSRExit:
@@ -1572,18 +1572,18 @@
for (size_t i = capturedVars.size(); i--;) {
if (!capturedVars.quickGet(i))
continue;
- m_state.variables().local(i).makeTop();
+ m_state.variables().local(i).makeHeapTop();
}
} else {
for (size_t i = m_codeBlock->m_numVars; i--;) {
if (m_codeBlock->isCaptured(i))
- m_state.variables().local(i).makeTop();
+ m_state.variables().local(i).makeHeapTop();
}
}
for (size_t i = m_state.variables().numberOfArguments(); i--;) {
if (m_codeBlock->isCaptured(argumentToOperand(i)))
- m_state.variables().argument(i).makeTop();
+ m_state.variables().argument(i).makeHeapTop();
}
}
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.cpp 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.cpp 2014-02-18 11:39:05 UTC (rev 164282)
@@ -125,12 +125,9 @@
FiltrationResult AbstractValue::filter(SpeculatedType type)
{
- if (isClear())
+ if ((m_type & type) == m_type)
return FiltrationOK;
- if (type == SpecTop)
- return isClear() ? Contradiction : FiltrationOK;
-
m_type &= type;
// It's possible that prior to this filter() call we had, say, (Final, TOP), and
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.h (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.h 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.h 2014-02-18 11:39:05 UTC (rev 164282)
@@ -62,16 +62,16 @@
bool isClear() const { return m_type == SpecNone; }
bool operator!() const { return isClear(); }
- void makeTop()
+ void makeHeapTop()
{
- m_type |= SpecTop; // The state may have included SpecEmpty, in which case we want this to become SpecEmptyOrTop.
- m_arrayModes = ALL_ARRAY_MODES;
- m_currentKnownStructure.makeTop();
- m_futurePossibleStructure.makeTop();
- m_value = JSValue();
- checkConsistency();
+ makeTop(SpecHeapTop);
}
+ void makeBytecodeTop()
+ {
+ makeTop(SpecBytecodeTop);
+ }
+
void clobberStructures()
{
if (m_type & SpecCell) {
@@ -89,9 +89,9 @@
m_value = JSValue();
}
- bool isTop() const
+ bool isHeapTop() const
{
- return m_type == SpecTop && m_currentKnownStructure.isTop() && m_futurePossibleStructure.isTop();
+ return (m_type | SpecHeapTop) == m_type && m_currentKnownStructure.isTop() && m_futurePossibleStructure.isTop();
}
bool valueIsTop() const
@@ -104,10 +104,10 @@
return m_value;
}
- static AbstractValue top()
+ static AbstractValue heapTop()
{
AbstractValue result;
- result.makeTop();
+ result.makeHeapTop();
return result;
}
@@ -195,7 +195,7 @@
bool validateType(JSValue value) const
{
- if (isTop())
+ if (isHeapTop())
return true;
if (mergeSpeculations(m_type, speculationFromValue(value)) != m_type)
@@ -211,7 +211,7 @@
bool validate(JSValue value) const
{
- if (isTop())
+ if (isHeapTop())
return true;
if (!!m_value && m_value != value)
@@ -363,6 +363,16 @@
m_arrayModes = ALL_ARRAY_MODES;
}
+ void makeTop(SpeculatedType top)
+ {
+ m_type |= top;
+ m_arrayModes = ALL_ARRAY_MODES;
+ m_currentKnownStructure.makeTop();
+ m_futurePossibleStructure.makeTop();
+ m_value = JSValue();
+ checkConsistency();
+ }
+
void setFuturePossibleStructure(Graph&, Structure* structure);
void filterValueByType();
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp 2014-02-18 11:39:05 UTC (rev 164282)
@@ -108,14 +108,14 @@
root->cfaFoundConstants = false;
for (size_t i = 0; i < root->valuesAtHead.numberOfArguments(); ++i) {
if (m_graph.m_form == SSA) {
- root->valuesAtHead.argument(i).makeTop();
+ root->valuesAtHead.argument(i).makeHeapTop();
continue;
}
Node* node = root->variablesAtHead.argument(i);
ASSERT(node->op() == SetArgument);
if (!node->variableAccessData()->shouldUnboxIfPossible()) {
- root->valuesAtHead.argument(i).makeTop();
+ root->valuesAtHead.argument(i).makeHeapTop();
continue;
}
@@ -128,14 +128,12 @@
else if (isCellSpeculation(prediction))
root->valuesAtHead.argument(i).setType(SpecCell);
else
- root->valuesAtHead.argument(i).makeTop();
-
- root->valuesAtTail.argument(i).clear();
+ root->valuesAtHead.argument(i).makeHeapTop();
}
for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
Node* node = root->variablesAtHead.local(i);
if (node && node->variableAccessData()->isCaptured())
- root->valuesAtHead.local(i).makeTop();
+ root->valuesAtHead.local(i).makeHeapTop();
else
root->valuesAtHead.local(i).clear();
root->valuesAtTail.local(i).clear();
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGJITCompiler.h (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGJITCompiler.h 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGJITCompiler.h 2014-02-18 11:39:05 UTC (rev 164282)
@@ -445,12 +445,12 @@
for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
Node* node = basicBlock.variablesAtHead.argument(argument);
if (!node || !node->shouldGenerate())
- entry->m_expectedValues.argument(argument).makeTop();
+ entry->m_expectedValues.argument(argument).makeHeapTop();
}
for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
Node* node = basicBlock.variablesAtHead.local(local);
if (!node || !node->shouldGenerate())
- entry->m_expectedValues.local(local).makeTop();
+ entry->m_expectedValues.local(local).makeHeapTop();
else if (node->variableAccessData()->shouldUseDoubleFormat())
entry->m_localsForcedDouble.set(local);
}
Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGUseKind.h (164281 => 164282)
--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGUseKind.h 2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGUseKind.h 2014-02-18 11:39:05 UTC (rev 164282)
@@ -62,7 +62,7 @@
{
switch (useKind) {
case UntypedUse:
- return SpecEmptyOrTop; // TOP isn't good enough; untyped uses may use the normally unseen empty value, in the case of lazy registers.
+ return SpecFullTop;
case Int32Use:
case KnownInt32Use:
return SpecInt32;
@@ -97,7 +97,7 @@
return SpecOther;
default:
RELEASE_ASSERT_NOT_REACHED();
- return SpecTop;
+ return SpecFullTop;
}
}