Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (199234 => 199235)
--- trunk/Source/_javascript_Core/ChangeLog 2016-04-08 17:50:22 UTC (rev 199234)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-04-08 18:07:25 UTC (rev 199235)
@@ -1,3 +1,24 @@
+2016-04-08 Benjamin Poulain <[email protected]>
+
+ UInt32ToNumber should have an Int52 path
+ https://bugs.webkit.org/show_bug.cgi?id=125704
+
+ Reviewed by Filip Pizlo.
+
+ When dealing with big numbers, fall back to Int52 instead
+ of double when possible.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileUInt32ToNumber):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileUInt32ToNumber):
+
2016-04-08 Brian Burg <[email protected]>
Web Inspector: protocol generator should emit an error when 'type' is used instead of '$ref'
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (199234 => 199235)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2016-04-08 17:50:22 UTC (rev 199234)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2016-04-08 18:07:25 UTC (rev 199235)
@@ -299,6 +299,14 @@
case UInt32ToNumber: {
JSValue child = forNode(node->child1()).value();
if (doesOverflow(node->arithMode())) {
+ if (enableInt52()) {
+ if (child && child.isMachineInt()) {
+ setConstant(node, jsNumber(child.asMachineInt()));
+ break;
+ }
+ forNode(node).setType(SpecMachineInt);
+ break;
+ }
if (child && child.isInt32()) {
uint32_t value = child.asInt32();
setConstant(node, jsNumber(value));
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (199234 => 199235)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-04-08 17:50:22 UTC (rev 199234)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-04-08 18:07:25 UTC (rev 199235)
@@ -140,8 +140,8 @@
node->setArithMode(Arith::CheckOverflow);
else {
node->setArithMode(Arith::DoOverflow);
- node->setResult(NodeResultDouble);
node->clearFlags(NodeMustGenerate);
+ node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
}
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (199234 => 199235)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2016-04-08 17:50:22 UTC (rev 199234)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2016-04-08 18:07:25 UTC (rev 199235)
@@ -238,10 +238,10 @@
}
case UInt32ToNumber: {
- // FIXME: Support Int52.
- // https://bugs.webkit.org/show_bug.cgi?id=125704
if (node->canSpeculateInt32(m_pass))
changed |= mergePrediction(SpecInt32);
+ else if (enableInt52())
+ changed |= mergePrediction(SpecMachineInt);
else
changed |= mergePrediction(SpecBytecodeNumber);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (199234 => 199235)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-04-08 17:50:22 UTC (rev 199234)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-04-08 18:07:25 UTC (rev 199235)
@@ -2130,9 +2130,13 @@
void SpeculativeJIT::compileUInt32ToNumber(Node* node)
{
if (doesOverflow(node->arithMode())) {
- // We know that this sometimes produces doubles. So produce a double every
- // time. This at least allows subsequent code to not have weird conditionals.
-
+ if (enableInt52()) {
+ SpeculateInt32Operand op1(this, node->child1());
+ GPRTemporary result(this, Reuse, op1);
+ m_jit.zeroExtend32ToPtr(op1.gpr(), result.gpr());
+ strictInt52Result(result.gpr(), node);
+ return;
+ }
SpeculateInt32Operand op1(this, node->child1());
FPRTemporary result(this);
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (199234 => 199235)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-04-08 17:50:22 UTC (rev 199234)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-04-08 18:07:25 UTC (rev 199235)
@@ -2125,10 +2125,10 @@
LValue value = lowInt32(m_node->child1());
if (doesOverflow(m_node->arithMode())) {
- setDouble(m_out.unsignedToDouble(value));
+ setStrictInt52(m_out.zeroExtPtr(value));
return;
}
-
+
speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
setInt32(value);
}
Added: trunk/Source/_javascript_Core/tests/stress/uint32-to-number-overflows-to-uint52.js (0 => 199235)
--- trunk/Source/_javascript_Core/tests/stress/uint32-to-number-overflows-to-uint52.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/uint32-to-number-overflows-to-uint52.js 2016-04-08 18:07:25 UTC (rev 199235)
@@ -0,0 +1,50 @@
+function simpleArith(number)
+{
+ return (number >>> 0) + 1;
+}
+noInline(simpleArith);
+
+for (let i = 0; i < 1e6; ++i) {
+ let simpleArithResult = simpleArith(i);
+ if (simpleArithResult !== i + 1)
+ throw "Failed simpleArith(i) at i = " + i;
+
+ simpleArithResult = simpleArith(2147483647);
+ if (simpleArithResult !== 2147483648)
+ throw "Failed simpleArith(2147483647)";
+
+ simpleArithResult = simpleArith(-1);
+ if (simpleArithResult !== 4294967296)
+ throw "Failed simpleArith(-1) at i = " + i;
+}
+
+// Make it OSR Exit.
+if (simpleArith({ valueOf: function() { return 5; }}) !== 6)
+ throw "Failed simpleArith({ toValue: function() { return 5; }}";
+if (simpleArith("WebKit!") !== 1)
+ throw "Failed simpleArith({ toValue: function() { return 5; }}";
+
+
+function compareToLargeNumber(value)
+{
+ return (value >>> 0) < 4294967294;
+}
+noInline(compareToLargeNumber);
+
+for (let i = 0; i < 1e6; ++i) {
+ let compareResult = compareToLargeNumber(i);
+ if (compareResult !== true)
+ throw "Failed compareToLargeNumber(i) at i = " + i;
+
+ compareResult = compareToLargeNumber(-3);
+ if (compareResult !== true)
+ throw "Failed compareToLargeNumber(4294967293) at i = " + i;
+
+ compareResult = compareToLargeNumber(-2);
+ if (compareResult !== false)
+ throw "Failed compareToLargeNumber(4294967294) at i = " + i;
+
+ compareResult = compareToLargeNumber(-1);
+ if (compareResult !== false)
+ throw "Failed compareToLargeNumber(4294967295) at i = " + i;
+}
\ No newline at end of file