Skip to content

Commit bd19ce3

Browse files
committed
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/JavaScriptCore: 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): Canonical link: https://commits.webkit.org/211013@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244079 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 993e32a commit bd19ce3

17 files changed

Lines changed: 334 additions & 158 deletions

‎JSTests/ChangeLog‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2019-04-09 Saam barati <sbarati@apple.com>
2+
3+
Clean up Int52 code and some bugs in it
4+
https://bugs.webkit.org/show_bug.cgi?id=196639
5+
<rdar://problem/49515757>
6+
7+
Reviewed by Yusuke Suzuki.
8+
9+
* stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js: Added.
10+
111
2019-04-09 Tadeu Zagallo <tzagallo@apple.com>
212

313
ASSERTION FAILED: !scope.exception() || !hasProperty in JSObject::get
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ runDefault("--useConcurrentJIT=0", "--validateAbstractInterpreterStateProbability=1.0", "--validateAbstractInterpreterState=1")
2+
3+
function foo(a, v) {
4+
a[0] = v + 2000000000;
5+
}
6+
noInline(foo);
7+
8+
for (var i = 0; i < 100000; ++i) {
9+
foo({}, 1000000000);
10+
}

‎Source/JavaScriptCore/ChangeLog‎

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,121 @@
1+
2019-04-09 Saam barati <sbarati@apple.com>
2+
3+
Clean up Int52 code and some bugs in it
4+
https://bugs.webkit.org/show_bug.cgi?id=196639
5+
<rdar://problem/49515757>
6+
7+
Reviewed by Yusuke Suzuki.
8+
9+
This patch fixes bugs in our Int52 code. The primary change in this patch is
10+
adopting a segregated type lattice for Int52. Previously, for Int52 values,
11+
we represented them with SpecInt32Only and SpecInt52Only. For an Int52,
12+
SpecInt32Only meant that the value is in int32 range. And SpecInt52Only meant
13+
that the is outside of the int32 range.
14+
15+
However, this got confusing because we reused SpecInt32Only both for JSValue
16+
representations and Int52 representations. This actually lead to some bugs.
17+
18+
1. It's possible that roundtripping through Int52 representation would say
19+
it produces the wrong type. For example, consider this program and how we
20+
used to annotate types in AI:
21+
a: JSConstant(10.0) => m_type is SpecAnyIntAsDouble
22+
b: Int52Rep(@a) => m_type is SpecInt52Only
23+
c: ValueRep(@b) => m_type is SpecAnyIntAsDouble
24+
25+
In AI, for the above program, we'd say that @c produces SpecAnyIntAsDouble.
26+
However, the execution semantics are such that it'd actually produce a boxed
27+
Int32. This patch fixes the bug where we'd say that Int52Rep over SpecAnyIntAsDouble
28+
would produce SpecInt52Only. This is clearly wrong, as SpecAnyIntAsDouble can
29+
mean an int value in either int32 or int52 range.
30+
31+
2. AsbstractValue::validateTypeAcceptingBoxedInt52 was wrong in how it
32+
accepted Int52 values. It was wrong in two different ways:
33+
a: If the AbstractValue's type was SpecInt52Only, and the incoming value
34+
was a boxed double, but represented a value in int32 range, the incoming
35+
value would incorrectly validate as being acceptable. However, we should
36+
have rejected this value.
37+
b: If the AbstractValue's type was SpecInt32Only, and the incoming value
38+
was an Int32 boxed in a double, this would not validate, even though
39+
it should have validated.
40+
41+
Solving 2 was easiest if we segregated out the Int52 type into its own
42+
lattice. This patch makes a new Int52 lattice, which is composed of
43+
SpecInt32AsInt52 and SpecNonInt32AsInt52.
44+
45+
The conversion rules are now really simple.
46+
47+
Int52 rep => JSValue rep
48+
SpecInt32AsInt52 => SpecInt32Only
49+
SpecNonInt32AsInt52 => SpecAnyIntAsDouble
50+
51+
JSValue rep => Int52 rep
52+
SpecInt32Only => SpecInt32AsInt52
53+
SpecAnyIntAsDouble => SpecInt52Any
54+
55+
With these rules, the program in (1) will now correctly report that @c
56+
returns SpecInt32Only | SpecAnyIntAsDouble.
57+
58+
* bytecode/SpeculatedType.cpp:
59+
(JSC::dumpSpeculation):
60+
(JSC::speculationToAbbreviatedString):
61+
(JSC::int52AwareSpeculationFromValue):
62+
(JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
63+
(JSC::speculationFromString):
64+
* bytecode/SpeculatedType.h:
65+
(JSC::isInt32SpeculationForArithmetic):
66+
(JSC::isInt32OrBooleanSpeculationForArithmetic):
67+
(JSC::isAnyInt52Speculation):
68+
(JSC::isIntAnyFormat):
69+
(JSC::isInt52Speculation): Deleted.
70+
(JSC::isAnyIntSpeculation): Deleted.
71+
* dfg/DFGAbstractInterpreterInlines.h:
72+
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
73+
* dfg/DFGAbstractValue.cpp:
74+
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
75+
(JSC::DFG::AbstractValue::checkConsistency const):
76+
* dfg/DFGAbstractValue.h:
77+
(JSC::DFG::AbstractValue::isInt52Any const):
78+
(JSC::DFG::AbstractValue::validateTypeAcceptingBoxedInt52 const):
79+
* dfg/DFGFixupPhase.cpp:
80+
(JSC::DFG::FixupPhase::fixupArithMul):
81+
(JSC::DFG::FixupPhase::fixupNode):
82+
(JSC::DFG::FixupPhase::fixupGetPrototypeOf):
83+
(JSC::DFG::FixupPhase::fixupToThis):
84+
(JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
85+
(JSC::DFG::FixupPhase::observeUseKindOnNode):
86+
(JSC::DFG::FixupPhase::fixIntConvertingEdge):
87+
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
88+
(JSC::DFG::FixupPhase::fixupCompareStrictEqAndSameValue):
89+
(JSC::DFG::FixupPhase::fixupChecksInBlock):
90+
* dfg/DFGGraph.h:
91+
(JSC::DFG::Graph::addShouldSpeculateInt52):
92+
(JSC::DFG::Graph::binaryArithShouldSpeculateInt52):
93+
(JSC::DFG::Graph::unaryArithShouldSpeculateInt52):
94+
(JSC::DFG::Graph::addShouldSpeculateAnyInt): Deleted.
95+
(JSC::DFG::Graph::binaryArithShouldSpeculateAnyInt): Deleted.
96+
(JSC::DFG::Graph::unaryArithShouldSpeculateAnyInt): Deleted.
97+
* dfg/DFGNode.h:
98+
(JSC::DFG::Node::shouldSpeculateInt52):
99+
(JSC::DFG::Node::shouldSpeculateAnyInt): Deleted.
100+
* dfg/DFGPredictionPropagationPhase.cpp:
101+
* dfg/DFGSpeculativeJIT.cpp:
102+
(JSC::DFG::SpeculativeJIT::setIntTypedArrayLoadResult):
103+
(JSC::DFG::SpeculativeJIT::compileArithAdd):
104+
(JSC::DFG::SpeculativeJIT::compileArithSub):
105+
(JSC::DFG::SpeculativeJIT::compileArithNegate):
106+
* dfg/DFGSpeculativeJIT64.cpp:
107+
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
108+
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
109+
* dfg/DFGUseKind.h:
110+
(JSC::DFG::typeFilterFor):
111+
* dfg/DFGVariableAccessData.cpp:
112+
(JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
113+
(JSC::DFG::VariableAccessData::couldRepresentInt52Impl):
114+
* ftl/FTLLowerDFGToB3.cpp:
115+
(JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub):
116+
(JSC::FTL::DFG::LowerDFGToB3::compileArithNegate):
117+
(JSC::FTL::DFG::LowerDFGToB3::setIntTypedArrayLoadResult):
118+
1119
2019-04-09 Tadeu Zagallo <tzagallo@apple.com>
2120

3121
ASSERTION FAILED: !scope.exception() || !hasProperty in JSObject::get

‎Source/JavaScriptCore/bytecode/SpeculatedType.cpp‎

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,11 @@ void dumpSpeculation(PrintStream& outStream, SpeculatedType value)
249249
isTop = false;
250250
}
251251

252-
if (value & SpecInt52Only)
253-
strOut.print("Int52");
252+
if (value & SpecInt32AsInt52)
253+
strOut.print("Int32AsInt52");
254+
255+
if (value & SpecNonInt32AsInt52)
256+
strOut.print("NonInt32AsInt52");
254257

255258
if ((value & SpecBytecodeDouble) == SpecBytecodeDouble)
256259
strOut.print("BytecodeDouble");
@@ -343,10 +346,12 @@ static const char* speculationToAbbreviatedString(SpeculatedType prediction)
343346
return "<Int32>";
344347
if (isAnyIntAsDoubleSpeculation(prediction))
345348
return "<AnyIntAsDouble>";
346-
if (isInt52Speculation(prediction))
347-
return "<Int52>";
348-
if (isAnyIntSpeculation(prediction))
349-
return "<AnyInt>";
349+
if (prediction == SpecNonInt32AsInt52)
350+
return "<NonInt32AsInt52>";
351+
if (prediction == SpecInt32AsInt52)
352+
return "<Int32AsInt52>";
353+
if (isAnyInt52Speculation(prediction))
354+
return "<Int52Any>";
350355
if (isDoubleSpeculation(prediction))
351356
return "<Double>";
352357
if (isFullNumberSpeculation(prediction))
@@ -510,6 +515,18 @@ SpeculatedType speculationFromValue(JSValue value)
510515
return SpecOther;
511516
}
512517

518+
SpeculatedType int52AwareSpeculationFromValue(JSValue value)
519+
{
520+
if (!value.isAnyInt())
521+
return speculationFromValue(value);
522+
523+
int64_t intValue = value.asAnyInt();
524+
bool isI32 = static_cast<int64_t>(static_cast<int32_t>(intValue)) == intValue;
525+
if (isI32)
526+
return SpecInt32AsInt52;
527+
return SpecNonInt32AsInt52;
528+
}
529+
513530
TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType type)
514531
{
515532
if (isInt8ArraySpeculation(type))
@@ -578,8 +595,8 @@ SpeculatedType speculationFromJSType(JSType type)
578595
SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType type)
579596
{
580597
// SpecNonIntAsDouble includes negative zero (-0.0), which can be equal to 0 and 0.0 in the context of == and ===.
581-
if (type & (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble))
582-
type |= (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble);
598+
if (type & (SpecIntAnyFormat | SpecNonIntAsDouble))
599+
type |= (SpecIntAnyFormat | SpecNonIntAsDouble);
583600

584601
if (type & SpecString)
585602
type |= SpecString;
@@ -803,10 +820,14 @@ SpeculatedType speculationFromString(const char* speculation)
803820
return SpecNonBoolInt32;
804821
if (!strncmp(speculation, "SpecInt32Only", strlen("SpecInt32Only")))
805822
return SpecInt32Only;
806-
if (!strncmp(speculation, "SpecInt52Only", strlen("SpecInt52Only")))
807-
return SpecInt52Only;
808-
if (!strncmp(speculation, "SpecAnyInt", strlen("SpecAnyInt")))
809-
return SpecAnyInt;
823+
if (!strncmp(speculation, "SpecInt32AsInt52", strlen("SpecInt32AsInt52")))
824+
return SpecInt32AsInt52;
825+
if (!strncmp(speculation, "SpecNonInt32AsInt52", strlen("SpecNonInt32AsInt52")))
826+
return SpecNonInt32AsInt52;
827+
if (!strncmp(speculation, "SpecInt52Any", strlen("SpecInt52Any")))
828+
return SpecInt52Any;
829+
if (!strncmp(speculation, "SpecIntAnyFormat", strlen("SpecIntAnyFormat")))
830+
return SpecIntAnyFormat;
810831
if (!strncmp(speculation, "SpecAnyIntAsDouble", strlen("SpecAnyIntAsDouble")))
811832
return SpecAnyIntAsDouble;
812833
if (!strncmp(speculation, "SpecNonIntAsDouble", strlen("SpecNonIntAsDouble")))

‎Source/JavaScriptCore/bytecode/SpeculatedType.h‎

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,31 @@ static const SpeculatedType SpecCellOther = 1ull << 27;
7373
static const SpeculatedType SpecBoolInt32 = 1ull << 28; // It's definitely an Int32 with value 0 or 1.
7474
static const SpeculatedType SpecNonBoolInt32 = 1ull << 29; // It's definitely an Int32 with value other than 0 or 1.
7575
static const SpeculatedType SpecInt32Only = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32.
76-
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.
77-
static const SpeculatedType SpecAnyInt = SpecInt32Only | SpecInt52Only; // It's something that we can do machine int arithmetic on.
78-
static const SpeculatedType SpecAnyIntAsDouble = 1ull << 31; // It's definitely an Int52 and it's inside a double.
79-
static const SpeculatedType SpecNonIntAsDouble = 1ull << 32; // It's definitely not an Int52 but it's a real number and it's a double.
76+
77+
static const SpeculatedType SpecInt32AsInt52 = 1ull << 30; // It's an Int52 and it can fit in an int32.
78+
static const SpeculatedType SpecNonInt32AsInt52 = 1ull << 31; // It's an Int52 and it can't fit in an int32.
79+
static const SpeculatedType SpecInt52Any = SpecInt32AsInt52 | SpecNonInt32AsInt52; // It's any kind of Int52.
80+
81+
static const SpeculatedType SpecAnyIntAsDouble = 1ull << 32; // It's definitely an Int52 and it's inside a double.
82+
static const SpeculatedType SpecNonIntAsDouble = 1ull << 33; // It's definitely not an Int52 but it's a real number and it's a double.
8083
static const SpeculatedType SpecDoubleReal = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double.
81-
static const SpeculatedType SpecDoublePureNaN = 1ull << 33; // It's definitely a NaN that is safe to tag (i.e. pure).
82-
static const SpeculatedType SpecDoubleImpureNaN = 1ull << 34; // It's definitely a NaN that is unsafe to tag (i.e. impure).
84+
static const SpeculatedType SpecDoublePureNaN = 1ull << 34; // It's definitely a NaN that is safe to tag (i.e. pure).
85+
static const SpeculatedType SpecDoubleImpureNaN = 1ull << 35; // It's definitely a NaN that is unsafe to tag (i.e. impure).
8386
static const SpeculatedType SpecDoubleNaN = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN.
8487
static const SpeculatedType SpecBytecodeDouble = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN.
8588
static const SpeculatedType SpecFullDouble = SpecDoubleReal | SpecDoubleNaN; // It's either a non-NaN or a NaN double.
8689
static const SpeculatedType SpecBytecodeRealNumber = SpecInt32Only | SpecDoubleReal; // It's either an Int32 or a DoubleReal.
87-
static const SpeculatedType SpecFullRealNumber = SpecAnyInt | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or a Int52.
90+
static const SpeculatedType SpecFullRealNumber = SpecInt32Only | SpecInt52Any | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or an Int52.
8891
static const SpeculatedType SpecBytecodeNumber = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
89-
static const SpeculatedType SpecFullNumber = SpecAnyInt | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
90-
static const SpeculatedType SpecBoolean = 1ull << 35; // It's definitely a Boolean.
91-
static const SpeculatedType SpecOther = 1ull << 36; // It's definitely either Null or Undefined.
92+
static const SpeculatedType SpecIntAnyFormat = SpecInt52Any | SpecInt32Only | SpecAnyIntAsDouble;
93+
94+
static const SpeculatedType SpecFullNumber = SpecIntAnyFormat | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
95+
static const SpeculatedType SpecBoolean = 1ull << 36; // It's definitely a Boolean.
96+
static const SpeculatedType SpecOther = 1ull << 37; // It's definitely either Null or Undefined.
9297
static const SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined.
93-
static const SpeculatedType SpecEmpty = 1ull << 37; // It's definitely an empty value marker.
94-
static const SpeculatedType SpecBigInt = 1ull << 38; // It's definitely a BigInt.
95-
static const SpeculatedType SpecDataViewObject = 1ull << 39; // It's definitely a JSDataView.
98+
static const SpeculatedType SpecEmpty = 1ull << 38; // It's definitely an empty value marker.
99+
static const SpeculatedType SpecBigInt = 1ull << 39; // It's definitely a BigInt.
100+
static const SpeculatedType SpecDataViewObject = 1ull << 40; // It's definitely a JSDataView.
96101
static const SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue.
97102
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.
98103
static const SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecBigInt; // It's definitely a JSCell.
@@ -337,27 +342,27 @@ inline bool isInt32OrBooleanSpeculation(SpeculatedType value)
337342

338343
inline bool isInt32SpeculationForArithmetic(SpeculatedType value)
339344
{
340-
return !(value & (SpecFullDouble | SpecInt52Only));
345+
return !(value & (SpecFullDouble | SpecInt52Any));
341346
}
342347

343348
inline bool isInt32OrBooleanSpeculationForArithmetic(SpeculatedType value)
344349
{
345-
return !(value & (SpecFullDouble | SpecInt52Only));
350+
return !(value & (SpecFullDouble | SpecInt52Any));
346351
}
347352

348353
inline bool isInt32OrBooleanSpeculationExpectingDefined(SpeculatedType value)
349354
{
350355
return isInt32OrBooleanSpeculation(value & ~SpecOther);
351356
}
352357

353-
inline bool isInt52Speculation(SpeculatedType value)
358+
inline bool isAnyInt52Speculation(SpeculatedType value)
354359
{
355-
return value == SpecInt52Only;
360+
return !!value && (value & SpecInt52Any) == value;
356361
}
357362

358-
inline bool isAnyIntSpeculation(SpeculatedType value)
363+
inline bool isIntAnyFormat(SpeculatedType value)
359364
{
360-
return !!value && (value & SpecAnyInt) == value;
365+
return !!value && (value & SpecIntAnyFormat) == value;
361366
}
362367

363368
inline bool isAnyIntAsDoubleSpeculation(SpeculatedType value)
@@ -483,6 +488,9 @@ SpeculatedType speculationFromClassInfo(const ClassInfo*);
483488
SpeculatedType speculationFromStructure(Structure*);
484489
SpeculatedType speculationFromCell(JSCell*);
485490
JS_EXPORT_PRIVATE SpeculatedType speculationFromValue(JSValue);
491+
// If it's an anyInt(), it'll return speculated types from the Int52 lattice.
492+
// Otherwise, it'll return types from the JSValue lattice.
493+
JS_EXPORT_PRIVATE SpeculatedType int52AwareSpeculationFromValue(JSValue);
486494
SpeculatedType speculationFromJSType(JSType);
487495

488496
SpeculatedType speculationFromTypedArrayType(TypedArrayType); // only valid for typed views.

0 commit comments

Comments
 (0)