Log Message
[JSC] Add fast path for BigInt32 left-shift https://bugs.webkit.org/show_bug.cgi?id=211029
Reviewed by Saam Barati. JSTests: * stress/bigint-left-shift-overflow.js: Added. (shouldBe): (leftShift): (noInline): * stress/bigint-right-shift-large.js: Added. (shouldBe): Source/_javascript_Core: Currently, the left-shift operation misses the fast path for BigInt32 <> BigInt32 case. This patch adds it. We also fixes prediction-propagation for left/right shift to use existing heap prediction instead of polluting the result with SpecBigInt. This offer 4.5% improvement in microbenchmarks/sunspider-sha1-big-int.js. * dfg/DFGPredictionPropagationPhase.cpp: * runtime/Operations.h: (JSC::shift):
Modified Paths
- trunk/JSTests/ChangeLog
- trunk/Source/_javascript_Core/ChangeLog
- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp
- trunk/Source/_javascript_Core/runtime/Operations.h
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (260710 => 260711)
--- trunk/JSTests/ChangeLog 2020-04-25 23:47:40 UTC (rev 260710)
+++ trunk/JSTests/ChangeLog 2020-04-25 23:56:40 UTC (rev 260711)
@@ -1,3 +1,17 @@
+2020-04-25 Yusuke Suzuki <[email protected]>
+
+ [JSC] Add fast path for BigInt32 left-shift
+ https://bugs.webkit.org/show_bug.cgi?id=211029
+
+ Reviewed by Saam Barati.
+
+ * stress/bigint-left-shift-overflow.js: Added.
+ (shouldBe):
+ (leftShift):
+ (noInline):
+ * stress/bigint-right-shift-large.js: Added.
+ (shouldBe):
+
2020-04-25 Paulo Matos <[email protected]>
Skip stress/butterfly-zero-unused-butterfly-properties.js on MIPS
Added: trunk/JSTests/stress/bigint-left-shift-overflow.js (0 => 260711)
--- trunk/JSTests/stress/bigint-left-shift-overflow.js (rev 0)
+++ trunk/JSTests/stress/bigint-left-shift-overflow.js 2020-04-25 23:56:40 UTC (rev 260711)
@@ -0,0 +1,104 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+let max = 0x7fffffff;
+let min = -0x7fffffff - 1;
+let bigIntMax = BigInt(max);
+let bigIntMin = BigInt(min);
+
+function leftShift(a, b)
+{
+ return a << b;
+}
+noInline(leftShift);
+
+{
+ let results = [
+ [ 2147483647n, -2147483648n ],
+ [ 2147483646n, -2147483648n ],
+ [ 2147483644n, -2147483648n ],
+ [ 2147483640n, -2147483648n ],
+ [ 2147483632n, -2147483648n ],
+ [ 2147483616n, -2147483648n ],
+ [ 2147483584n, -2147483648n ],
+ [ 2147483520n, -2147483648n ],
+ [ 2147483392n, -2147483648n ],
+ [ 2147483136n, -2147483648n ],
+ [ 2147482624n, -2147483648n ],
+ [ 2147481600n, -2147483648n ],
+ [ 2147479552n, -2147483648n ],
+ [ 2147475456n, -2147483648n ],
+ [ 2147467264n, -2147483648n ],
+ [ 2147450880n, -2147483648n ],
+ [ 2147418112n, -2147483648n ],
+ [ 2147352576n, -2147483648n ],
+ [ 2147221504n, -2147483648n ],
+ [ 2146959360n, -2147483648n ],
+ [ 2146435072n, -2147483648n ],
+ [ 2145386496n, -2147483648n ],
+ [ 2143289344n, -2147483648n ],
+ [ 2139095040n, -2147483648n ],
+ [ 2130706432n, -2147483648n ],
+ [ 2113929216n, -2147483648n ],
+ [ 2080374784n, -2147483648n ],
+ [ 2013265920n, -2147483648n ],
+ [ 1879048192n, -2147483648n ],
+ [ 1610612736n, -2147483648n ],
+ [ 1073741824n, -2147483648n ],
+ [ 0n, -2147483648n ],
+ ];
+
+ let index = 0;
+ for (let i = 0; i < 32; ++i) {
+ let bigIntShift = BigInt(i);
+ shouldBe(leftShift(bigIntMax >> bigIntShift, bigIntShift), results[index][0]);
+ shouldBe(leftShift(bigIntMin >> bigIntShift, bigIntShift), results[index][1]);
+ ++index;
+ }
+}
+
+{
+ let results = [
+ [2147483648n, -2147483649n],
+ [2147483648n, -2147483650n],
+ [2147483648n, -2147483652n],
+ [2147483648n, -2147483656n],
+ [2147483648n, -2147483664n],
+ [2147483648n, -2147483680n],
+ [2147483648n, -2147483712n],
+ [2147483648n, -2147483776n],
+ [2147483648n, -2147483904n],
+ [2147483648n, -2147484160n],
+ [2147483648n, -2147484672n],
+ [2147483648n, -2147485696n],
+ [2147483648n, -2147487744n],
+ [2147483648n, -2147491840n],
+ [2147483648n, -2147500032n],
+ [2147483648n, -2147516416n],
+ [2147483648n, -2147549184n],
+ [2147483648n, -2147614720n],
+ [2147483648n, -2147745792n],
+ [2147483648n, -2148007936n],
+ [2147483648n, -2148532224n],
+ [2147483648n, -2149580800n],
+ [2147483648n, -2151677952n],
+ [2147483648n, -2155872256n],
+ [2147483648n, -2164260864n],
+ [2147483648n, -2181038080n],
+ [2147483648n, -2214592512n],
+ [2147483648n, -2281701376n],
+ [2147483648n, -2415919104n],
+ [2147483648n, -2684354560n],
+ [2147483648n, -3221225472n],
+ [2147483648n, -4294967296n],
+ ];
+ let index = 0;
+ for (let i = 0; i < 32; ++i) {
+ let bigIntShift = BigInt(i);
+ shouldBe(leftShift((bigIntMax >> bigIntShift) + 1n, bigIntShift), results[index][0]);
+ shouldBe(leftShift((bigIntMin >> bigIntShift) - 1n, bigIntShift), results[index][1]);
+ ++index;
+ }
+}
Added: trunk/JSTests/stress/bigint-right-shift-large.js (0 => 260711)
--- trunk/JSTests/stress/bigint-right-shift-large.js (rev 0)
+++ trunk/JSTests/stress/bigint-right-shift-large.js 2020-04-25 23:56:40 UTC (rev 260711)
@@ -0,0 +1,6 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+shouldBe(0b100000000000000n >> 32n, 0n);
Modified: trunk/Source/_javascript_Core/ChangeLog (260710 => 260711)
--- trunk/Source/_javascript_Core/ChangeLog 2020-04-25 23:47:40 UTC (rev 260710)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-04-25 23:56:40 UTC (rev 260711)
@@ -1,3 +1,18 @@
+2020-04-25 Yusuke Suzuki <[email protected]>
+
+ [JSC] Add fast path for BigInt32 left-shift
+ https://bugs.webkit.org/show_bug.cgi?id=211029
+
+ Reviewed by Saam Barati.
+
+ Currently, the left-shift operation misses the fast path for BigInt32 <> BigInt32 case. This patch adds it. We also fixes
+ prediction-propagation for left/right shift to use existing heap prediction instead of polluting the result with SpecBigInt.
+ This offer 4.5% improvement in microbenchmarks/sunspider-sha1-big-int.js.
+
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * runtime/Operations.h:
+ (JSC::shift):
+
2020-04-25 Ross Kirsling <[email protected]>
Unreviewed fix for JSC Debug tests following r210853.
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (260710 => 260711)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2020-04-25 23:47:40 UTC (rev 260710)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2020-04-25 23:56:40 UTC (rev 260711)
@@ -185,9 +185,7 @@
SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (isBigIntSpeculation(left) && isBigIntSpeculation(right))
- changed |= mergePrediction(SpecBigInt);
- else if (isFullNumberOrBooleanSpeculationExpectingDefined(left) && isFullNumberOrBooleanSpeculationExpectingDefined(right))
+ if (isFullNumberOrBooleanSpeculationExpectingDefined(left) && isFullNumberOrBooleanSpeculationExpectingDefined(right))
changed |= mergePrediction(SpecInt32Only);
else
changed |= mergePrediction(node->getHeapPrediction());
Modified: trunk/Source/_javascript_Core/runtime/Operations.h (260710 => 260711)
--- trunk/Source/_javascript_Core/runtime/Operations.h 2020-04-25 23:47:40 UTC (rev 260710)
+++ trunk/Source/_javascript_Core/runtime/Operations.h 2020-04-25 23:56:40 UTC (rev 260711)
@@ -764,11 +764,21 @@
isLeft = !isLeft;
rightInt32 = -rightInt32;
}
+ ASSERT(rightInt32 >= 0);
// This std::min is a bit hacky, but required because in C++ it is undefined behavior to do a shift where the right operand is greater or equal to the bit-width of the left operand.
if (!isLeft)
return jsBigInt32(leftInt32 >> std::min(rightInt32, 31));
+ // Do some checks to detect overflow of left-shift. But this is much cheaper compared to allocating two JSBigInt and perform shift operations in JSBigInt.
+ if (!leftInt32)
+ return jsBigInt32(0);
+ if (rightInt32 < 32) {
+ int64_t result64 = static_cast<int64_t>(leftInt32) << rightInt32;
+ if (static_cast<int64_t>(static_cast<int32_t>(result64)) == result64)
+ return jsBigInt32(static_cast<int32_t>(result64));
+ }
+
// In the case of a left shift we can overflow. I deal with this by allocating HeapBigInts.
// FIXME: it might be possible to do something smarter, trying to do the left shift and detecting somehow if it overflowed.
JSBigInt* leftHeapBigInt = JSBigInt::createFrom(vm, leftInt32);
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
