Diff
Modified: trunk/JSTests/ChangeLog (244078 => 244079)
--- trunk/JSTests/ChangeLog 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/JSTests/ChangeLog 2019-04-09 16:06:48 UTC (rev 244079)
@@ -1,3 +1,13 @@
+2019-04-09 Saam barati <sbar...@apple.com>
+
+ Clean up Int52 code and some bugs in it
+ https://bugs.webkit.org/show_bug.cgi?id=196639
+ <rdar://problem/49515757>
+
+ Reviewed by Yusuke Suzuki.
+
+ * stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js: Added.
+
2019-04-09 Tadeu Zagallo <tzaga...@apple.com>
ASSERTION FAILED: !scope.exception() || !hasProperty in JSObject::get
Added: trunk/JSTests/stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js (0 => 244079)
--- trunk/JSTests/stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js (rev 0)
+++ trunk/JSTests/stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js 2019-04-09 16:06:48 UTC (rev 244079)
@@ -0,0 +1,10 @@
+//@ runDefault("--useConcurrentJIT=0", "--validateAbstractInterpreterStateProbability=1.0", "--validateAbstractInterpreterState=1")
+
+function foo(a, v) {
+ a[0] = v + 2000000000;
+}
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+ foo({}, 1000000000);
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (244078 => 244079)
--- trunk/Source/_javascript_Core/ChangeLog 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-04-09 16:06:48 UTC (rev 244079)
@@ -1,3 +1,121 @@
+2019-04-09 Saam barati <sbar...@apple.com>
+
+ Clean up Int52 code and some bugs in it
+ https://bugs.webkit.org/show_bug.cgi?id=196639
+ <rdar://problem/49515757>
+
+ Reviewed by Yusuke Suzuki.
+
+ This patch fixes bugs in our Int52 code. The primary change in this patch is
+ adopting a segregated type lattice for Int52. Previously, for Int52 values,
+ we represented them with SpecInt32Only and SpecInt52Only. For an Int52,
+ SpecInt32Only meant that the value is in int32 range. And SpecInt52Only meant
+ that the is outside of the int32 range.
+
+ However, this got confusing because we reused SpecInt32Only both for JSValue
+ representations and Int52 representations. This actually lead to some bugs.
+
+ 1. It's possible that roundtripping through Int52 representation would say
+ it produces the wrong type. For example, consider this program and how we
+ used to annotate types in AI:
+ a: JSConstant(10.0) => m_type is SpecAnyIntAsDouble
+ b: Int52Rep(@a) => m_type is SpecInt52Only
+ c: ValueRep(@b) => m_type is SpecAnyIntAsDouble
+
+ In AI, for the above program, we'd say that @c produces SpecAnyIntAsDouble.
+ However, the execution semantics are such that it'd actually produce a boxed
+ Int32. This patch fixes the bug where we'd say that Int52Rep over SpecAnyIntAsDouble
+ would produce SpecInt52Only. This is clearly wrong, as SpecAnyIntAsDouble can
+ mean an int value in either int32 or int52 range.
+
+ 2. AsbstractValue::validateTypeAcceptingBoxedInt52 was wrong in how it
+ accepted Int52 values. It was wrong in two different ways:
+ a: If the AbstractValue's type was SpecInt52Only, and the incoming value
+ was a boxed double, but represented a value in int32 range, the incoming
+ value would incorrectly validate as being acceptable. However, we should
+ have rejected this value.
+ b: If the AbstractValue's type was SpecInt32Only, and the incoming value
+ was an Int32 boxed in a double, this would not validate, even though
+ it should have validated.
+
+ Solving 2 was easiest if we segregated out the Int52 type into its own
+ lattice. This patch makes a new Int52 lattice, which is composed of
+ SpecInt32AsInt52 and SpecNonInt32AsInt52.
+
+ The conversion rules are now really simple.
+
+ Int52 rep => JSValue rep
+ SpecInt32AsInt52 => SpecInt32Only
+ SpecNonInt32AsInt52 => SpecAnyIntAsDouble
+
+ JSValue rep => Int52 rep
+ SpecInt32Only => SpecInt32AsInt52
+ SpecAnyIntAsDouble => SpecInt52Any
+
+ With these rules, the program in (1) will now correctly report that @c
+ returns SpecInt32Only | SpecAnyIntAsDouble.
+
+ * bytecode/SpeculatedType.cpp:
+ (JSC::dumpSpeculation):
+ (JSC::speculationToAbbreviatedString):
+ (JSC::int52AwareSpeculationFromValue):
+ (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
+ (JSC::speculationFromString):
+ * bytecode/SpeculatedType.h:
+ (JSC::isInt32SpeculationForArithmetic):
+ (JSC::isInt32OrBooleanSpeculationForArithmetic):
+ (JSC::isAnyInt52Speculation):
+ (JSC::isIntAnyFormat):
+ (JSC::isInt52Speculation): Deleted.
+ (JSC::isAnyIntSpeculation): Deleted.
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGAbstractValue.cpp:
+ (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+ (JSC::DFG::AbstractValue::checkConsistency const):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::isInt52Any const):
+ (JSC::DFG::AbstractValue::validateTypeAcceptingBoxedInt52 const):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupArithMul):
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::fixupGetPrototypeOf):
+ (JSC::DFG::FixupPhase::fixupToThis):
+ (JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
+ (JSC::DFG::FixupPhase::observeUseKindOnNode):
+ (JSC::DFG::FixupPhase::fixIntConvertingEdge):
+ (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
+ (JSC::DFG::FixupPhase::fixupCompareStrictEqAndSameValue):
+ (JSC::DFG::FixupPhase::fixupChecksInBlock):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::addShouldSpeculateInt52):
+ (JSC::DFG::Graph::binaryArithShouldSpeculateInt52):
+ (JSC::DFG::Graph::unaryArithShouldSpeculateInt52):
+ (JSC::DFG::Graph::addShouldSpeculateAnyInt): Deleted.
+ (JSC::DFG::Graph::binaryArithShouldSpeculateAnyInt): Deleted.
+ (JSC::DFG::Graph::unaryArithShouldSpeculateAnyInt): Deleted.
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::shouldSpeculateInt52):
+ (JSC::DFG::Node::shouldSpeculateAnyInt): Deleted.
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::setIntTypedArrayLoadResult):
+ (JSC::DFG::SpeculativeJIT::compileArithAdd):
+ (JSC::DFG::SpeculativeJIT::compileArithSub):
+ (JSC::DFG::SpeculativeJIT::compileArithNegate):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+ * dfg/DFGUseKind.h:
+ (JSC::DFG::typeFilterFor):
+ * dfg/DFGVariableAccessData.cpp:
+ (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
+ (JSC::DFG::VariableAccessData::couldRepresentInt52Impl):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub):
+ (JSC::FTL::DFG::LowerDFGToB3::compileArithNegate):
+ (JSC::FTL::DFG::LowerDFGToB3::setIntTypedArrayLoadResult):
+
2019-04-09 Tadeu Zagallo <tzaga...@apple.com>
ASSERTION FAILED: !scope.exception() || !hasProperty in JSObject::get
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -249,8 +249,11 @@
isTop = false;
}
- if (value & SpecInt52Only)
- strOut.print("Int52");
+ if (value & SpecInt32AsInt52)
+ strOut.print("Int32AsInt52");
+
+ if (value & SpecNonInt32AsInt52)
+ strOut.print("NonInt32AsInt52");
if ((value & SpecBytecodeDouble) == SpecBytecodeDouble)
strOut.print("BytecodeDouble");
@@ -343,10 +346,12 @@
return "<Int32>";
if (isAnyIntAsDoubleSpeculation(prediction))
return "<AnyIntAsDouble>";
- if (isInt52Speculation(prediction))
- return "<Int52>";
- if (isAnyIntSpeculation(prediction))
- return "<AnyInt>";
+ if (prediction == SpecNonInt32AsInt52)
+ return "<NonInt32AsInt52>";
+ if (prediction == SpecInt32AsInt52)
+ return "<Int32AsInt52>";
+ if (isAnyInt52Speculation(prediction))
+ return "<Int52Any>";
if (isDoubleSpeculation(prediction))
return "<Double>";
if (isFullNumberSpeculation(prediction))
@@ -510,6 +515,18 @@
return SpecOther;
}
+SpeculatedType int52AwareSpeculationFromValue(JSValue value)
+{
+ if (!value.isAnyInt())
+ return speculationFromValue(value);
+
+ int64_t intValue = value.asAnyInt();
+ bool isI32 = static_cast<int64_t>(static_cast<int32_t>(intValue)) == intValue;
+ if (isI32)
+ return SpecInt32AsInt52;
+ return SpecNonInt32AsInt52;
+}
+
TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType type)
{
if (isInt8ArraySpeculation(type))
@@ -578,8 +595,8 @@
SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType type)
{
// SpecNonIntAsDouble includes negative zero (-0.0), which can be equal to 0 and 0.0 in the context of == and ===.
- if (type & (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble))
- type |= (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble);
+ if (type & (SpecIntAnyFormat | SpecNonIntAsDouble))
+ type |= (SpecIntAnyFormat | SpecNonIntAsDouble);
if (type & SpecString)
type |= SpecString;
@@ -803,10 +820,14 @@
return SpecNonBoolInt32;
if (!strncmp(speculation, "SpecInt32Only", strlen("SpecInt32Only")))
return SpecInt32Only;
- if (!strncmp(speculation, "SpecInt52Only", strlen("SpecInt52Only")))
- return SpecInt52Only;
- if (!strncmp(speculation, "SpecAnyInt", strlen("SpecAnyInt")))
- return SpecAnyInt;
+ if (!strncmp(speculation, "SpecInt32AsInt52", strlen("SpecInt32AsInt52")))
+ return SpecInt32AsInt52;
+ if (!strncmp(speculation, "SpecNonInt32AsInt52", strlen("SpecNonInt32AsInt52")))
+ return SpecNonInt32AsInt52;
+ if (!strncmp(speculation, "SpecInt52Any", strlen("SpecInt52Any")))
+ return SpecInt52Any;
+ if (!strncmp(speculation, "SpecIntAnyFormat", strlen("SpecIntAnyFormat")))
+ return SpecIntAnyFormat;
if (!strncmp(speculation, "SpecAnyIntAsDouble", strlen("SpecAnyIntAsDouble")))
return SpecAnyIntAsDouble;
if (!strncmp(speculation, "SpecNonIntAsDouble", strlen("SpecNonIntAsDouble")))
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.h (244078 => 244079)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.h 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.h 2019-04-09 16:06:48 UTC (rev 244079)
@@ -73,26 +73,31 @@
static const SpeculatedType SpecBoolInt32 = 1ull << 28; // It's definitely an Int32 with value 0 or 1.
static const SpeculatedType SpecNonBoolInt32 = 1ull << 29; // It's definitely an Int32 with value other than 0 or 1.
static const SpeculatedType SpecInt32Only = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32.
-static const SpeculatedType SpecInt52Only = 1ull << 30; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32.
-static const SpeculatedType SpecAnyInt = SpecInt32Only | SpecInt52Only; // It's something that we can do machine int arithmetic on.
-static const SpeculatedType SpecAnyIntAsDouble = 1ull << 31; // It's definitely an Int52 and it's inside a double.
-static const SpeculatedType SpecNonIntAsDouble = 1ull << 32; // It's definitely not an Int52 but it's a real number and it's a double.
+
+static const SpeculatedType SpecInt32AsInt52 = 1ull << 30; // It's an Int52 and it can fit in an int32.
+static const SpeculatedType SpecNonInt32AsInt52 = 1ull << 31; // It's an Int52 and it can't fit in an int32.
+static const SpeculatedType SpecInt52Any = SpecInt32AsInt52 | SpecNonInt32AsInt52; // It's any kind of Int52.
+
+static const SpeculatedType SpecAnyIntAsDouble = 1ull << 32; // It's definitely an Int52 and it's inside a double.
+static const SpeculatedType SpecNonIntAsDouble = 1ull << 33; // It's definitely not an Int52 but it's a real number and it's a double.
static const SpeculatedType SpecDoubleReal = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double.
-static const SpeculatedType SpecDoublePureNaN = 1ull << 33; // It's definitely a NaN that is safe to tag (i.e. pure).
-static const SpeculatedType SpecDoubleImpureNaN = 1ull << 34; // It's definitely a NaN that is unsafe to tag (i.e. impure).
+static const SpeculatedType SpecDoublePureNaN = 1ull << 34; // It's definitely a NaN that is safe to tag (i.e. pure).
+static const SpeculatedType SpecDoubleImpureNaN = 1ull << 35; // It's definitely a NaN that is unsafe to tag (i.e. impure).
static const SpeculatedType SpecDoubleNaN = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN.
static const SpeculatedType SpecBytecodeDouble = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN.
static const SpeculatedType SpecFullDouble = SpecDoubleReal | SpecDoubleNaN; // It's either a non-NaN or a NaN double.
static const SpeculatedType SpecBytecodeRealNumber = SpecInt32Only | SpecDoubleReal; // It's either an Int32 or a DoubleReal.
-static const SpeculatedType SpecFullRealNumber = SpecAnyInt | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or a Int52.
+static const SpeculatedType SpecFullRealNumber = SpecInt32Only | SpecInt52Any | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or an Int52.
static const SpeculatedType SpecBytecodeNumber = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
-static const SpeculatedType SpecFullNumber = SpecAnyInt | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
-static const SpeculatedType SpecBoolean = 1ull << 35; // It's definitely a Boolean.
-static const SpeculatedType SpecOther = 1ull << 36; // It's definitely either Null or Undefined.
+static const SpeculatedType SpecIntAnyFormat = SpecInt52Any | SpecInt32Only | SpecAnyIntAsDouble;
+
+static const SpeculatedType SpecFullNumber = SpecIntAnyFormat | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
+static const SpeculatedType SpecBoolean = 1ull << 36; // It's definitely a Boolean.
+static const SpeculatedType SpecOther = 1ull << 37; // It's definitely either Null or Undefined.
static const SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined.
-static const SpeculatedType SpecEmpty = 1ull << 37; // It's definitely an empty value marker.
-static const SpeculatedType SpecBigInt = 1ull << 38; // It's definitely a BigInt.
-static const SpeculatedType SpecDataViewObject = 1ull << 39; // It's definitely a JSDataView.
+static const SpeculatedType SpecEmpty = 1ull << 38; // It's definitely an empty value marker.
+static const SpeculatedType SpecBigInt = 1ull << 39; // It's definitely a BigInt.
+static const SpeculatedType SpecDataViewObject = 1ull << 40; // It's definitely a JSDataView.
static const SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue.
static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecWeakMapObject | SpecWeakSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther | SpecDataViewObject; // Bitmask used for testing for any kind of object prediction.
static const SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecBigInt; // It's definitely a JSCell.
@@ -337,12 +342,12 @@
inline bool isInt32SpeculationForArithmetic(SpeculatedType value)
{
- return !(value & (SpecFullDouble | SpecInt52Only));
+ return !(value & (SpecFullDouble | SpecInt52Any));
}
inline bool isInt32OrBooleanSpeculationForArithmetic(SpeculatedType value)
{
- return !(value & (SpecFullDouble | SpecInt52Only));
+ return !(value & (SpecFullDouble | SpecInt52Any));
}
inline bool isInt32OrBooleanSpeculationExpectingDefined(SpeculatedType value)
@@ -350,14 +355,14 @@
return isInt32OrBooleanSpeculation(value & ~SpecOther);
}
-inline bool isInt52Speculation(SpeculatedType value)
+inline bool isAnyInt52Speculation(SpeculatedType value)
{
- return value == SpecInt52Only;
+ return !!value && (value & SpecInt52Any) == value;
}
-inline bool isAnyIntSpeculation(SpeculatedType value)
+inline bool isIntAnyFormat(SpeculatedType value)
{
- return !!value && (value & SpecAnyInt) == value;
+ return !!value && (value & SpecIntAnyFormat) == value;
}
inline bool isAnyIntAsDoubleSpeculation(SpeculatedType value)
@@ -483,6 +488,9 @@
SpeculatedType speculationFromStructure(Structure*);
SpeculatedType speculationFromCell(JSCell*);
JS_EXPORT_PRIVATE SpeculatedType speculationFromValue(JSValue);
+// If it's an anyInt(), it'll return speculated types from the Int52 lattice.
+// Otherwise, it'll return types from the JSValue lattice.
+JS_EXPORT_PRIVATE SpeculatedType int52AwareSpeculationFromValue(JSValue);
SpeculatedType speculationFromJSType(JSType);
SpeculatedType speculationFromTypedArrayType(TypedArrayType); // only valid for typed views.
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2019-04-09 16:06:48 UTC (rev 244079)
@@ -481,7 +481,7 @@
setConstant(node, jsNumber(static_cast<uint32_t>(machineInt)));
break;
}
- setNonCellTypeForNode(node, SpecAnyInt);
+ setNonCellTypeForNode(node, SpecInt52Any);
break;
}
if (child && child.isInt32()) {
@@ -607,8 +607,9 @@
setConstant(node, child);
break;
}
-
- setNonCellTypeForNode(node, SpecAnyInt);
+
+ setTypeForNode(node, forNode(node->child1()).m_type);
+ forNode(node).fixTypeForRepresentation(m_graph, node);
break;
}
@@ -667,7 +668,7 @@
break;
}
}
- setNonCellTypeForNode(node, SpecAnyInt);
+ setNonCellTypeForNode(node, SpecInt52Any);
break;
case DoubleRepUse:
if (left && right && left.isNumber() && right.isNumber()) {
@@ -767,7 +768,7 @@
break;
}
}
- setNonCellTypeForNode(node, SpecAnyInt);
+ setNonCellTypeForNode(node, SpecInt52Any);
break;
case DoubleRepUse:
if (left && right && left.isNumber() && right.isNumber()) {
@@ -830,7 +831,7 @@
break;
}
}
- setNonCellTypeForNode(node, SpecAnyInt);
+ setNonCellTypeForNode(node, SpecInt52Any);
break;
case DoubleRepUse:
if (child && child.isNumber()) {
@@ -890,7 +891,7 @@
break;
}
}
- setNonCellTypeForNode(node, SpecAnyInt);
+ setNonCellTypeForNode(node, SpecInt52Any);
break;
case DoubleRepUse:
if (left && right && left.isNumber() && right.isNumber()) {
@@ -2130,8 +2131,8 @@
case Array::Uint32Array:
if (node->shouldSpeculateInt32())
setNonCellTypeForNode(node, SpecInt32Only);
- else if (enableInt52() && node->shouldSpeculateAnyInt())
- setNonCellTypeForNode(node, SpecAnyInt);
+ else if (node->shouldSpeculateInt52())
+ setNonCellTypeForNode(node, SpecInt52Any);
else
setNonCellTypeForNode(node, SpecAnyIntAsDouble);
break;
@@ -3875,7 +3876,7 @@
if (data.isSigned)
setNonCellTypeForNode(node, SpecInt32Only);
else
- setNonCellTypeForNode(node, SpecAnyInt);
+ setNonCellTypeForNode(node, SpecInt52Any);
}
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -134,8 +134,8 @@
if (m_value.isInt32())
m_value = jsDoubleNumber(m_value.asNumber());
}
- if (m_type & SpecAnyInt) {
- m_type &= ~SpecAnyInt;
+ if (m_type & SpecIntAnyFormat) {
+ m_type &= ~SpecIntAnyFormat;
m_type |= SpecAnyIntAsDouble;
}
if (m_type & ~SpecFullDouble)
@@ -142,14 +142,30 @@
DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for double node has type outside SpecFullDouble.\n").data());
} else if (representation == NodeResultInt52) {
if (m_type & SpecAnyIntAsDouble) {
+ // AnyIntAsDouble can produce i32 or i52. SpecAnyIntAsDouble doesn't bound the magnitude of the value.
m_type &= ~SpecAnyIntAsDouble;
- m_type |= SpecInt52Only;
+ m_type |= SpecInt52Any;
}
- if (m_type & ~SpecAnyInt)
- DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for int52 node has type outside SpecAnyInt.\n").data());
+
+ if (m_type & SpecInt32Only) {
+ m_type &= ~SpecInt32Only;
+ m_type |= SpecInt32AsInt52;
+ }
+
+ if (m_type & ~SpecInt52Any)
+ DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for int52 node has type outside SpecInt52Any.\n").data());
+
+ if (m_value) {
+ DFG_ASSERT(graph, node, m_value.isAnyInt());
+ m_type = int52AwareSpeculationFromValue(m_value);
+ }
} else {
- if (m_type & SpecInt52Only) {
- m_type &= ~SpecInt52Only;
+ if (m_type & SpecInt32AsInt52) {
+ m_type &= ~SpecInt32AsInt52;
+ m_type |= SpecInt32Only;
+ }
+ if (m_type & SpecNonInt32AsInt52) {
+ m_type &= ~SpecNonInt32AsInt52;
m_type |= SpecAnyIntAsDouble;
}
if (m_type & ~SpecBytecodeTop)
@@ -415,22 +431,21 @@
void AbstractValue::checkConsistency() const
{
if (!(m_type & SpecCell)) {
- ASSERT(m_structure.isClear());
- ASSERT(!m_arrayModes);
+ RELEASE_ASSERT(m_structure.isClear());
+ RELEASE_ASSERT(!m_arrayModes);
}
if (isClear())
- ASSERT(!m_value);
+ RELEASE_ASSERT(!m_value);
- if (!!m_value) {
- SpeculatedType type = m_type;
- // This relaxes the assertion below a bit, since we don't know the representation of the
- // node.
- if (type & SpecInt52Only)
- type |= SpecAnyIntAsDouble;
- ASSERT(mergeSpeculations(type, speculationFromValue(m_value)) == type);
+ if (m_type & SpecInt52Any) {
+ if (m_type != SpecFullTop)
+ RELEASE_ASSERT(isAnyInt52Speculation(m_type));
}
-
+
+ if (!!m_value)
+ RELEASE_ASSERT(validateTypeAcceptingBoxedInt52(m_value));
+
// 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
@@ -441,7 +456,7 @@
{
m_structure.assertIsRegistered(graph);
}
-#endif
+#endif // !ASSERT_DISABLED
ResultType AbstractValue::resultType() const
{
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h 2019-04-09 16:06:48 UTC (rev 244079)
@@ -201,6 +201,11 @@
{
return !m_value && m_type;
}
+
+ bool isInt52Any() const
+ {
+ return !(m_type & ~SpecInt52Any);
+ }
JSValue value() const
{
@@ -506,23 +511,19 @@
bool validateTypeAcceptingBoxedInt52(JSValue value) const
{
- if (isHeapTop())
+ if (isBytecodeTop())
return true;
- // Constant folding always represents Int52's in a double (i.e. AnyIntAsDouble).
- // So speculationFromValue(value) for an Int52 value will return AnyIntAsDouble,
- // and that's fine - the type validates just fine.
- SpeculatedType type = m_type;
- if (type & SpecInt52Only)
- type |= SpecAnyIntAsDouble;
-
- if (mergeSpeculations(type, speculationFromValue(value)) != type)
- return false;
-
- if (value.isEmpty()) {
- ASSERT(m_type & SpecEmpty);
+ if (m_type & SpecInt52Any) {
+ ASSERT(!(m_type & ~SpecInt52Any));
+
+ if (mergeSpeculations(m_type, int52AwareSpeculationFromValue(value)) != m_type)
+ return false;
return true;
}
+
+ if (mergeSpeculations(m_type, speculationFromValue(value)) != m_type)
+ return false;
return true;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -126,7 +126,7 @@
node->setArithMode(Arith::CheckOverflowAndNegativeZero);
return;
}
- if (m_graph.binaryArithShouldSpeculateAnyInt(node, FixupPass)) {
+ if (m_graph.binaryArithShouldSpeculateInt52(node, FixupPass)) {
fixEdge<Int52RepUse>(leftChild);
fixEdge<Int52RepUse>(rightChild);
if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()) || leftChild.node() == rightChild.node())
@@ -326,7 +326,7 @@
break;
}
- if (m_graph.unaryArithShouldSpeculateAnyInt(node, FixupPass)) {
+ if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
node->setOp(ArithNegate);
fixEdge<Int52RepUse>(node->child1());
if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
@@ -450,7 +450,7 @@
node->clearFlags(NodeMustGenerate);
break;
}
- if (m_graph.unaryArithShouldSpeculateAnyInt(node, FixupPass)) {
+ if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
fixEdge<Int52RepUse>(node->child1());
if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
node->setArithMode(Arith::CheckOverflow);
@@ -681,8 +681,7 @@
node->clearFlags(NodeMustGenerate);
break;
}
- if (enableInt52()
- && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
+ if (Node::shouldSpeculateInt52(node->child1().node(), node->child2().node())) {
fixEdge<Int52RepUse>(node->child1());
fixEdge<Int52RepUse>(node->child2());
node->clearFlags(NodeMustGenerate);
@@ -936,7 +935,7 @@
case Array::Uint32Array:
if (node->shouldSpeculateInt32())
break;
- if (node->shouldSpeculateAnyInt() && enableInt52())
+ if (node->shouldSpeculateInt52())
node->setResult(NodeResultInt52);
else
node->setResult(NodeResultDouble);
@@ -1015,7 +1014,7 @@
fixEdge<Int32Use>(child2);
if (child3->shouldSpeculateInt32())
fixIntOrBooleanEdge(child3);
- else if (child3->shouldSpeculateAnyInt())
+ else if (child3->shouldSpeculateInt52())
fixEdge<Int52RepUse>(child3);
else
fixDoubleOrBooleanEdge(child3);
@@ -1060,7 +1059,7 @@
// just call the function when that happens. But the FTL is totally cool with those
// conversions.
if (!child->shouldSpeculateInt32()
- && !child->shouldSpeculateAnyInt()
+ && !child->shouldSpeculateInt52()
&& !(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL()))
badNews = true;
}
@@ -1081,7 +1080,7 @@
Edge& child = m_graph.child(node, 2 + i);
if (child->shouldSpeculateInt32())
fixIntOrBooleanEdge(child);
- else if (child->shouldSpeculateAnyInt())
+ else if (child->shouldSpeculateInt52())
fixEdge<Int52RepUse>(child);
else {
RELEASE_ASSERT(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL());
@@ -1095,7 +1094,7 @@
if (node->arrayMode().type() == Array::Uint32Array) {
// NOTE: This means basically always doing Int52.
- if (node->shouldSpeculateAnyInt() && enableInt52())
+ if (node->shouldSpeculateInt52())
node->setResult(NodeResultInt52);
else
node->setResult(NodeResultDouble);
@@ -1519,7 +1518,7 @@
break;
}
- if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
+ if (node->child1()->shouldSpeculateInt52()) {
insertCheck<Int52RepUse>(node->child1().node());
m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
break;
@@ -2180,7 +2179,7 @@
case NumberToStringWithRadix: {
if (node->child1()->shouldSpeculateInt32())
fixEdge<Int32Use>(node->child1());
- else if (enableInt52() && node->child1()->shouldSpeculateAnyInt())
+ else if (node->child1()->shouldSpeculateInt52())
fixEdge<Int52RepUse>(node->child1());
else
fixEdge<DoubleRepUse>(node->child1());
@@ -2614,7 +2613,7 @@
m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
return;
}
- if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
+ if (node->child1()->shouldSpeculateInt52()) {
insertCheck<Int52RepUse>(node->child1().node());
m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
return;
@@ -2670,7 +2669,7 @@
return;
}
- if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
+ if (node->child1()->shouldSpeculateInt52()) {
fixEdge<Int52RepUse>(node->child1());
node->convertToIdentity();
node->setResult(NodeResultInt52);
@@ -2904,7 +2903,7 @@
return;
}
- if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
+ if (node->child1()->shouldSpeculateInt52()) {
fixEdge<Int52RepUse>(node->child1());
node->clearFlags(NodeMustGenerate);
return;
@@ -3225,7 +3224,7 @@
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
break;
case Int52RepUse:
- if (isAnyIntSpeculation(variable->prediction()))
+ if (isAnyInt52Speculation(variable->prediction()))
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
break;
case CellUse:
@@ -3316,7 +3315,7 @@
}
UseKind useKind;
- if (node->shouldSpeculateAnyInt())
+ if (node->shouldSpeculateInt52())
useKind = Int52RepUse;
else if (node->shouldSpeculateNumber())
useKind = DoubleRepUse;
@@ -3413,7 +3412,7 @@
return true;
}
- if (m_graph.addShouldSpeculateAnyInt(node)) {
+ if (m_graph.addShouldSpeculateInt52(node)) {
fixEdge<Int52RepUse>(node->child1());
fixEdge<Int52RepUse>(node->child2());
node->setArithMode(Arith::CheckOverflow);
@@ -3732,8 +3731,7 @@
node->setOpAndDefaultFlags(CompareStrictEq);
return;
}
- if (enableInt52()
- && Node::shouldSpeculateAnyInt(node->child1().node(), node->child2().node())) {
+ if (Node::shouldSpeculateInt52(node->child1().node(), node->child2().node())) {
fixEdge<Int52RepUse>(node->child1());
fixEdge<Int52RepUse>(node->child2());
node->setOpAndDefaultFlags(CompareStrictEq);
@@ -3973,11 +3971,11 @@
ASSERT(indexForChecks != UINT_MAX);
if (edge->isAnyIntConstant()) {
result = m_insertionSet.insertNode(
- indexForChecks, SpecAnyInt, Int52Constant, originForChecks,
+ indexForChecks, SpecInt52Any, Int52Constant, originForChecks,
OpInfo(edge->constant()));
} else if (edge->hasDoubleResult()) {
result = m_insertionSet.insertNode(
- indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
+ indexForChecks, SpecInt52Any, Int52Rep, originForChecks,
Edge(edge.node(), DoubleRepAnyIntUse));
} else if (edge->shouldSpeculateInt32ForArithmetic()) {
result = m_insertionSet.insertNode(
@@ -3985,7 +3983,7 @@
Edge(edge.node(), Int32Use));
} else {
result = m_insertionSet.insertNode(
- indexForChecks, SpecAnyInt, Int52Rep, originForChecks,
+ indexForChecks, SpecInt52Any, Int52Rep, originForChecks,
Edge(edge.node(), AnyIntUse));
}
Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.h 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h 2019-04-09 16:06:48 UTC (rev 244079)
@@ -284,7 +284,7 @@
return addSpeculationMode(add, pass) != DontSpeculateInt32;
}
- bool addShouldSpeculateAnyInt(Node* add)
+ bool addShouldSpeculateInt52(Node* add)
{
if (!enableInt52())
return false;
@@ -295,27 +295,23 @@
if (hasExitSite(add, Int52Overflow))
return false;
- if (Node::shouldSpeculateAnyInt(left, right))
+ if (Node::shouldSpeculateInt52(left, right))
return true;
- auto shouldSpeculateAnyIntForAdd = [](Node* node) {
- auto isAnyIntSpeculationForAdd = [](SpeculatedType value) {
- return !!value && (value & (SpecAnyInt | SpecAnyIntAsDouble)) == value;
- };
-
+ auto shouldSpeculateInt52ForAdd = [] (Node* node) {
// When DoubleConstant node appears, it means that users explicitly write a constant in their code with double form instead of integer form (1.0 instead of 1).
// In that case, we should honor this decision: using it as integer is not appropriate.
if (node->op() == DoubleConstant)
return false;
- return isAnyIntSpeculationForAdd(node->prediction());
+ return isIntAnyFormat(node->prediction());
};
- // Allow AnyInt ArithAdd only when the one side of the binary operation should be speculated AnyInt. It is a bit conservative
+ // Allow Int52 ArithAdd only when the one side of the binary operation should be speculated Int52. It is a bit conservative
// decision. This is because Double to Int52 conversion is not so cheap. Frequent back-and-forth conversions between Double and Int52
// rather hurt the performance. If the one side of the operation is already Int52, the cost for constructing ArithAdd becomes
// cheap since only one Double to Int52 conversion could be required.
// This recovers some regression in assorted tests while keeping kraken crypto improvements.
- if (!left->shouldSpeculateAnyInt() && !right->shouldSpeculateAnyInt())
+ if (!left->shouldSpeculateInt52() && !right->shouldSpeculateInt52())
return false;
auto usesAsNumbers = [](Node* node) {
@@ -329,7 +325,7 @@
if (!usesAsNumbers(add))
return false;
- return shouldSpeculateAnyIntForAdd(left) && shouldSpeculateAnyIntForAdd(right);
+ return shouldSpeculateInt52ForAdd(left) && shouldSpeculateInt52ForAdd(right);
}
bool binaryArithShouldSpeculateInt32(Node* node, PredictionPass pass)
@@ -341,7 +337,7 @@
&& node->canSpeculateInt32(node->sourceFor(pass));
}
- bool binaryArithShouldSpeculateAnyInt(Node* node, PredictionPass pass)
+ bool binaryArithShouldSpeculateInt52(Node* node, PredictionPass pass)
{
if (!enableInt52())
return false;
@@ -349,7 +345,7 @@
Node* left = node->child1().node();
Node* right = node->child2().node();
- return Node::shouldSpeculateAnyInt(left, right)
+ return Node::shouldSpeculateInt52(left, right)
&& node->canSpeculateInt52(pass)
&& !hasExitSite(node, Int52Overflow);
}
@@ -360,11 +356,11 @@
&& node->canSpeculateInt32(pass);
}
- bool unaryArithShouldSpeculateAnyInt(Node* node, PredictionPass pass)
+ bool unaryArithShouldSpeculateInt52(Node* node, PredictionPass pass)
{
if (!enableInt52())
return false;
- return node->child1()->shouldSpeculateAnyInt()
+ return node->child1()->shouldSpeculateInt52()
&& node->canSpeculateInt52(pass)
&& !hasExitSite(node, Int52Overflow);
}
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2019-04-09 16:06:48 UTC (rev 244079)
@@ -2346,9 +2346,9 @@
return isInt32OrBooleanSpeculationExpectingDefined(prediction());
}
- bool shouldSpeculateAnyInt()
+ bool shouldSpeculateInt52()
{
- return isAnyIntSpeculation(prediction());
+ return enableInt52() && isAnyInt52Speculation(prediction());
}
bool shouldSpeculateDouble()
@@ -2609,9 +2609,9 @@
&& op2->shouldSpeculateInt32OrBooleanExpectingDefined();
}
- static bool shouldSpeculateAnyInt(Node* op1, Node* op2)
+ static bool shouldSpeculateInt52(Node* op1, Node* op2)
{
- return op1->shouldSpeculateAnyInt() && op2->shouldSpeculateAnyInt();
+ return enableInt52() && op1->shouldSpeculateInt52() && op2->shouldSpeculateInt52();
}
static bool shouldSpeculateNumber(Node* op1, Node* op2)
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -156,8 +156,8 @@
case GetLocal: {
VariableAccessData* variable = node->variableAccessData();
SpeculatedType prediction = variable->prediction();
- if (!variable->couldRepresentInt52() && (prediction & SpecInt52Only))
- prediction = (prediction | SpecAnyIntAsDouble) & ~SpecInt52Only;
+ if (!variable->couldRepresentInt52() && (prediction & SpecNonInt32AsInt52))
+ prediction = (prediction | SpecAnyIntAsDouble) & ~SpecNonInt32AsInt52;
if (prediction)
changed |= mergePrediction(prediction);
break;
@@ -173,7 +173,7 @@
if (node->canSpeculateInt32(m_pass))
changed |= mergePrediction(SpecInt32Only);
else if (enableInt52())
- changed |= mergePrediction(SpecAnyInt);
+ changed |= mergePrediction(SpecInt52Any);
else
changed |= mergePrediction(SpecBytecodeNumber);
break;
@@ -188,8 +188,8 @@
&& isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
changed |= mergePrediction(SpecInt32Only);
- else if (m_graph.addShouldSpeculateAnyInt(node))
- changed |= mergePrediction(SpecInt52Only);
+ else if (m_graph.addShouldSpeculateInt52(node))
+ changed |= mergePrediction(SpecInt52Any);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
} else if (isStringOrStringObjectSpeculation(left) || isStringOrStringObjectSpeculation(right)) {
@@ -217,8 +217,8 @@
if (left && right) {
if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
changed |= mergePrediction(SpecInt32Only);
- else if (m_graph.addShouldSpeculateAnyInt(node))
- changed |= mergePrediction(SpecInt52Only);
+ else if (m_graph.addShouldSpeculateInt52(node))
+ changed |= mergePrediction(SpecInt52Any);
else if (isFullNumberOrBooleanSpeculation(left) && isFullNumberOrBooleanSpeculation(right))
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
else if (node->mayHaveNonIntResult() || (left & SpecBytecodeDouble) || (right & SpecBytecodeDouble))
@@ -238,8 +238,8 @@
&& isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
changed |= mergePrediction(SpecInt32Only);
- else if (m_graph.addShouldSpeculateAnyInt(node))
- changed |= mergePrediction(SpecInt52Only);
+ else if (m_graph.addShouldSpeculateInt52(node))
+ changed |= mergePrediction(SpecInt52Any);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
} else if (node->mayHaveNonIntResult() || (left & SpecBytecodeDouble) || (right & SpecBytecodeDouble))
@@ -259,8 +259,8 @@
&& isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
changed |= mergePrediction(SpecInt32Only);
- else if (m_graph.addShouldSpeculateAnyInt(node))
- changed |= mergePrediction(SpecInt52Only);
+ else if (m_graph.addShouldSpeculateInt52(node))
+ changed |= mergePrediction(SpecInt52Any);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
} else if (isBigIntSpeculation(left) && isBigIntSpeculation(right))
@@ -283,8 +283,8 @@
if (prediction) {
if (isInt32OrBooleanSpeculation(prediction) && node->canSpeculateInt32(m_pass))
changed |= mergePrediction(SpecInt32Only);
- else if (m_graph.unaryArithShouldSpeculateAnyInt(node, m_pass))
- changed |= mergePrediction(SpecInt52Only);
+ else if (m_graph.unaryArithShouldSpeculateInt52(node, m_pass))
+ changed |= mergePrediction(SpecInt52Any);
else if (isBytecodeNumberSpeculation(prediction))
changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
else {
@@ -326,8 +326,8 @@
&& isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
changed |= mergePrediction(SpecInt32Only);
- else if (m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
- changed |= mergePrediction(SpecInt52Only);
+ else if (m_graph.binaryArithShouldSpeculateInt52(node, m_pass))
+ changed |= mergePrediction(SpecInt52Any);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
} else if (op == ValueMul && isBigIntSpeculation(left) && isBigIntSpeculation(right))
@@ -427,7 +427,7 @@
if (isInt32SpeculationForArithmetic(node->getHeapPrediction()) && node->op() == GetByVal)
changed |= mergePrediction(SpecInt32Only);
else if (enableInt52())
- changed |= mergePrediction(SpecAnyInt);
+ changed |= mergePrediction(SpecInt52Any);
else
changed |= mergePrediction(SpecInt32Only | SpecAnyIntAsDouble);
break;
@@ -459,8 +459,8 @@
break;
}
- if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
- changed |= mergePrediction(SpecAnyInt);
+ if (node->child1()->shouldSpeculateInt52()) {
+ changed |= mergePrediction(SpecInt52Any);
break;
}
@@ -567,7 +567,7 @@
if (isFullNumberSpeculation(left)
&& isFullNumberSpeculation(right)
&& !m_graph.addShouldSpeculateInt32(node, m_pass)
- && !m_graph.addShouldSpeculateAnyInt(node))
+ && !m_graph.addShouldSpeculateInt52(node))
ballot = VoteDouble;
else
ballot = VoteValue;
@@ -587,7 +587,7 @@
if (isFullNumberSpeculation(left)
&& isFullNumberSpeculation(right)
&& !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)
- && !m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
+ && !m_graph.binaryArithShouldSpeculateInt52(node, m_pass))
ballot = VoteDouble;
else
ballot = VoteValue;
@@ -643,7 +643,7 @@
if (isDoubleSpeculation(prediction))
node->variableAccessData()->vote(VoteDouble, weight);
else if (!isFullNumberSpeculation(prediction)
- || isInt32Speculation(prediction) || isAnyIntSpeculation(prediction))
+ || isInt32Speculation(prediction) || isAnyInt52Speculation(prediction))
node->variableAccessData()->vote(VoteValue, weight);
break;
}
@@ -734,10 +734,7 @@
{
switch (m_currentNode->op()) {
case JSConstant: {
- SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
- if (type == SpecAnyIntAsDouble && enableInt52())
- type = SpecInt52Only;
- setPrediction(type);
+ setPrediction(speculationFromValue(m_currentNode->asJSValue()));
break;
}
case DoubleConstant: {
@@ -1048,7 +1045,7 @@
case FiatInt52: {
RELEASE_ASSERT(enableInt52());
- setPrediction(SpecAnyInt);
+ setPrediction(SpecInt52Any);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -2919,7 +2919,8 @@
}
#if USE(JSVALUE64)
- if (node->shouldSpeculateAnyInt()) {
+ if (node->shouldSpeculateInt52()) {
+ ASSERT(enableInt52());
m_jit.zeroExtend32ToPtr(resultReg, resultReg);
strictInt52Result(resultReg, node);
return;
@@ -4326,8 +4327,8 @@
// Will we need an overflow check? If we can prove that neither input can be
// Int52 then the overflow check will not be necessary.
- if (!m_state.forNode(node->child1()).couldBeType(SpecInt52Only)
- && !m_state.forNode(node->child2()).couldBeType(SpecInt52Only)) {
+ if (!m_state.forNode(node->child1()).couldBeType(SpecNonInt32AsInt52)
+ && !m_state.forNode(node->child2()).couldBeType(SpecNonInt32AsInt52)) {
SpeculateWhicheverInt52Operand op1(this, node->child1());
SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
GPRTemporary result(this, Reuse, op1);
@@ -4512,8 +4513,8 @@
// Will we need an overflow check? If we can prove that neither input can be
// Int52 then the overflow check will not be necessary.
- if (!m_state.forNode(node->child1()).couldBeType(SpecInt52Only)
- && !m_state.forNode(node->child2()).couldBeType(SpecInt52Only)) {
+ if (!m_state.forNode(node->child1()).couldBeType(SpecNonInt32AsInt52)
+ && !m_state.forNode(node->child2()).couldBeType(SpecNonInt32AsInt52)) {
SpeculateWhicheverInt52Operand op1(this, node->child1());
SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
GPRTemporary result(this, Reuse, op1);
@@ -4596,7 +4597,7 @@
case Int52RepUse: {
ASSERT(shouldCheckOverflow(node->arithMode()));
- if (!m_state.forNode(node->child1()).couldBeType(SpecInt52Only)) {
+ if (!m_state.forNode(node->child1()).couldBeType(SpecNonInt32AsInt52)) {
SpeculateWhicheverInt52Operand op1(this, node->child1());
GPRTemporary result(this);
GPRReg op1GPR = op1.gpr();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -942,7 +942,7 @@
}
case DataFormatJS: {
- DFG_ASSERT(m_jit.graph(), m_currentNode, !(type & SpecInt52Only));
+ DFG_ASSERT(m_jit.graph(), m_currentNode, !(type & SpecInt52Any));
// Check the value is an integer.
GPRReg gpr = info.gpr();
m_gprs.lock(gpr);
@@ -1027,7 +1027,7 @@
ASSERT(desiredFormat == DataFormatInt52 || desiredFormat == DataFormatStrictInt52);
AbstractValue& value = m_state.forNode(edge);
- m_interpreter.filter(value, SpecAnyInt);
+ m_interpreter.filter(value, SpecInt52Any);
if (value.isClear()) {
if (mayHaveTypeCheck(edge.useKind()))
terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
Modified: trunk/Source/_javascript_Core/dfg/DFGUseKind.h (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGUseKind.h 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGUseKind.h 2019-04-09 16:06:48 UTC (rev 244079)
@@ -102,7 +102,7 @@
case KnownInt32Use:
return SpecInt32Only;
case Int52RepUse:
- return SpecAnyInt;
+ return SpecInt52Any;
case AnyIntUse:
return SpecInt32Only | SpecAnyIntAsDouble;
case NumberUse:
Modified: trunk/Source/_javascript_Core/dfg/DFGVariableAccessData.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/dfg/DFGVariableAccessData.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/dfg/DFGVariableAccessData.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -156,7 +156,7 @@
SpeculatedType type = m_prediction;
if (type & ~SpecBytecodeNumber)
type |= SpecDoublePureNaN;
- if (type & SpecAnyInt)
+ if (type & (SpecInt32Only | SpecInt52Any))
type |= SpecAnyIntAsDouble;
return checkAndSet(m_prediction, type);
}
@@ -180,8 +180,8 @@
return false;
// The argument-aware prediction -- which merges all of an (inlined or machine)
- // argument's variable access datas' predictions -- must possibly be AnyInt.
- return !(argumentAwarePrediction() & ~SpecAnyInt);
+ // argument's variable access datas' predictions -- must possibly be Int52Any.
+ return isAnyInt52Speculation(argumentAwarePrediction());
}
FlushFormat VariableAccessData::flushFormat()
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (244078 => 244079)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2019-04-09 15:57:45 UTC (rev 244078)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2019-04-09 16:06:48 UTC (rev 244079)
@@ -2326,8 +2326,8 @@
}
case Int52RepUse: {
- if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
- && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
+ if (!abstractValue(m_node->child1()).couldBeType(SpecNonInt32AsInt52)
+ && !abstractValue(m_node->child2()).couldBeType(SpecNonInt32AsInt52)) {
Int52Kind kind;
LValue left = lowWhicheverInt52(m_node->child1(), kind);
LValue right = lowInt52(m_node->child2(), kind);
@@ -3023,7 +3023,7 @@
}
case Int52RepUse: {
- if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
+ if (!abstractValue(m_node->child1()).couldBeType(SpecNonInt32AsInt52)) {
Int52Kind kind;
LValue value = lowWhicheverInt52(m_node->child1(), kind);
LValue result = m_out.neg(value);
@@ -14637,7 +14637,7 @@
return;
}
- if (m_node->shouldSpeculateAnyInt()) {
+ if (m_node->shouldSpeculateInt52()) {
setStrictInt52(m_out.zeroExt(result, Int64));
return;
}