Title: [244079] trunk
Revision
244079
Author
sbar...@apple.com
Date
2019-04-09 09:06:48 -0700 (Tue, 09 Apr 2019)

Log Message

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.

JSTests:

* stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js: Added.

Source/_javascript_Core:

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):

Modified Paths

Added Paths

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;
         }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to