Title: [260683] trunk
Revision
260683
Author
[email protected]
Date
2020-04-24 17:34:59 -0700 (Fri, 24 Apr 2020)

Log Message

Return BigInt32 whenever we can
https://bugs.webkit.org/show_bug.cgi?id=210922

Reviewed by Yusuke Suzuki.

JSTests:

* microbenchmarks/sunspider-sha1-big-int.js: Added.
(hex_sha1):
(b64_sha1):
(str_sha1):
(hex_hmac_sha1):
(b64_hmac_sha1):
(str_hmac_sha1):
(bigIntToInt32):
(sha1_vm_test):
(core_sha1):
(sha1_ft):
(sha1_kt):
(core_hmac_sha1):
(safe_add):
(rol):
(str2binb):
(binb2hex):
(binb2b64):
(run):

Source/_javascript_Core:

This patch makes it so our runtime functions for big int math on heap
big ints converts the result to a big int 32 when possible.
        
The inspiration for this patch came from converting SunSpider's sha1 benchmark to
using big ints. I found that that original implementation of big int 32
was a ~35% slowdown here. This patch speeds it up by 86% from ToT, and
36% faster than before big int 32 was introduced.
        
To make this sound in the DFG/FTL, we are currently reporting that all
HeapBigInt math ops return SpecBigInt, instead of SpecHeapBigInt.
However, we want to do better in a follow up. We need some kind of profiling
system where we determine if we should speculate if the result is big int
32, a heap big int, or both:
https://bugs.webkit.org/show_bug.cgi?id=210982

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileValueBitNot):
(JSC::DFG::SpeculativeJIT::compileValueBitwiseOp):
(JSC::DFG::SpeculativeJIT::compileValueLShiftOp):
(JSC::DFG::SpeculativeJIT::compileValueBitRShift):
(JSC::DFG::SpeculativeJIT::compileValueAdd):
(JSC::DFG::SpeculativeJIT::compileValueSub):
(JSC::DFG::SpeculativeJIT::compileValueMul):
(JSC::DFG::SpeculativeJIT::compileValueDiv):
(JSC::DFG::SpeculativeJIT::compileValueMod):
(JSC::DFG::SpeculativeJIT::compileValuePow):
* jit/JITOperations.cpp:
* jsc.cpp:
(functionCreateBigInt32):
* runtime/BigIntConstructor.cpp:
(JSC::toBigInt):
(JSC::callBigIntConstructor):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/JSBigInt.cpp:
(JSC::JSBigInt::exponentiateHeap):
(JSC::JSBigInt::multiplyHeap):
(JSC::JSBigInt::divideHeap):
(JSC::JSBigInt::unaryMinusHeap):
(JSC::JSBigInt::remainderHeap):
(JSC::JSBigInt::incHeap):
(JSC::JSBigInt::decHeap):
(JSC::JSBigInt::addHeap):
(JSC::JSBigInt::subHeap):
(JSC::JSBigInt::bitwiseAndHeap):
(JSC::JSBigInt::bitwiseOrHeap):
(JSC::JSBigInt::bitwiseXorHeap):
(JSC::JSBigInt::leftShiftHeap):
(JSC::JSBigInt::signedRightShiftHeap):
(JSC::JSBigInt::bitwiseNotHeap):
(JSC::JSBigInt::absoluteAdd):
(JSC::JSBigInt::absoluteSub):
(JSC::JSBigInt::parseInt):
(JSC::JSBigInt::exponentiate): Deleted.
(JSC::JSBigInt::multiply): Deleted.
(JSC::JSBigInt::divide): Deleted.
(JSC::JSBigInt::unaryMinus): Deleted.
(JSC::JSBigInt::remainder): Deleted.
(JSC::JSBigInt::inc): Deleted.
(JSC::JSBigInt::dec): Deleted.
(JSC::JSBigInt::add): Deleted.
(JSC::JSBigInt::sub): Deleted.
(JSC::JSBigInt::bitwiseAnd): Deleted.
(JSC::JSBigInt::bitwiseOr): Deleted.
(JSC::JSBigInt::bitwiseXor): Deleted.
(JSC::JSBigInt::leftShift): Deleted.
(JSC::JSBigInt::signedRightShift): Deleted.
(JSC::JSBigInt::bitwiseNot): Deleted.
* runtime/JSBigInt.h:
* runtime/JSCJSValue.h:
(JSC::jsBigInt32):
* runtime/JSCJSValueInlines.h:
(JSC::JSValue::JSValue):
* runtime/Operations.cpp:
(JSC::jsAddSlowCase):
* runtime/Operations.h:
(JSC::jsSub):
(JSC::jsMul):
(JSC::jsDiv):
(JSC::jsInc):
(JSC::jsDec):
(JSC::jsBitwiseNot):
(JSC::shift):
(JSC::bitwiseBinaryOp):

Source/WebCore:

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::readBigInt):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (260682 => 260683)


--- trunk/JSTests/ChangeLog	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/JSTests/ChangeLog	2020-04-25 00:34:59 UTC (rev 260683)
@@ -1,3 +1,30 @@
+2020-04-24  Saam Barati  <[email protected]>
+
+        Return BigInt32 whenever we can
+        https://bugs.webkit.org/show_bug.cgi?id=210922
+
+        Reviewed by Yusuke Suzuki.
+
+        * microbenchmarks/sunspider-sha1-big-int.js: Added.
+        (hex_sha1):
+        (b64_sha1):
+        (str_sha1):
+        (hex_hmac_sha1):
+        (b64_hmac_sha1):
+        (str_hmac_sha1):
+        (bigIntToInt32):
+        (sha1_vm_test):
+        (core_sha1):
+        (sha1_ft):
+        (sha1_kt):
+        (core_hmac_sha1):
+        (safe_add):
+        (rol):
+        (str2binb):
+        (binb2hex):
+        (binb2b64):
+        (run):
+
 2020-04-24  Yusuke Suzuki  <[email protected]>
 
         [JSC] DFG compare should speculate BigInt well

Added: trunk/JSTests/microbenchmarks/sunspider-sha1-big-int.js (0 => 260683)


--- trunk/JSTests/microbenchmarks/sunspider-sha1-big-int.js	                        (rev 0)
+++ trunk/JSTests/microbenchmarks/sunspider-sha1-big-int.js	2020-04-25 00:34:59 UTC (rev 260683)
@@ -0,0 +1,256 @@
+/*
+ * A _javascript_ implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS PUB 180-1
+ * Version 2.1a Copyright Paul Johnston 2000 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0n;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
+function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
+function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
+function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
+function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
+function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
+
+function bigIntToInt32(b) {
+    return parseInt(b.toString(), 10);
+}
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha1_vm_test()
+{
+    return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
+}
+
+/*
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
+ */
+//x == str
+//len == i32
+function core_sha1(x, len)
+{
+    /* append padding */
+
+    if (x[len >> 5] === undefined)
+        x[len >> 5] = 0n;
+    if (x[((len + 64 >> 9) << 4) + 15] === undefined)
+        x[((len + 64 >> 9) << 4) + 15] = 0n;
+
+    x[len >> 5] |= 0x80n << (24n - BigInt(len) % 32n);
+    x[((len + 64 >> 9) << 4) + 15] = BigInt(len);
+
+    var w = Array(80);
+    for (let i = 0; i < w.length; ++i) {
+        w[i] = 0n;
+    }
+    var a = 1732584193n;
+    var b = -271733879n;
+    var c = -1732584194n;
+    var d =  271733878n;
+    var e = -1009589776n;
+
+    for(var i = 0; i < x.length; i += 16)
+    {
+        var olda = a;
+        var oldb = b;
+        var oldc = c;
+        var oldd = d;
+        var olde = e;
+
+        for(var j = 0; j < 80; j++)
+        {
+            if (j < 16) w[j] = x[i + j] || 0n;
+            else w[j] = rol((w[j-3] || 0n) ^ (w[j-8] || 0n) ^ (w[j-14] || 0n) ^ (w[j-16] || 0n), 1);
+            var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
+                safe_add(safe_add(e, w[j]), sha1_kt(BigInt(j))));
+            e = d;
+            d = c;
+
+            c = rol(b, 30);
+            b = a;
+            a = t;
+        }
+
+        a = safe_add(a, olda);
+        b = safe_add(b, oldb);
+        c = safe_add(c, oldc);
+        d = safe_add(d, oldd);
+        e = safe_add(e, olde);
+    }
+    return Array(a, b, c, d, e);
+
+}
+
+/*
+ * Perform the appropriate triplet combination function for the current
+ * iteration
+ */
+function sha1_ft(t, b, c, d)
+{
+    if(t < 20) return (b & c) | ((~b) & d);
+    if(t < 40) return b ^ c ^ d;
+    if(t < 60) return (b & c) | (b & d) | (c & d);
+    return b ^ c ^ d;
+}
+
+/*
+ * Determine the appropriate additive constant for the current iteration
+ */
+function sha1_kt(t)
+{
+    return (t < 20n) ?  1518500249n : (t < 40n) ?  1859775393n :
+        (t < 60n) ? -1894007588n : -899497514n;
+}
+
+/*
+ * Calculate the HMAC-SHA1 of a key and some data
+ */
+function core_hmac_sha1(key, data)
+{
+    throw new Error("Bad")
+    var bkey = str2binb(key);
+    if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
+
+    var ipad = Array(16), opad = Array(16);
+    for(var i = 0; i < 16; i++)
+    {
+        ipad[i] = bkey[i] ^ 0x36363636n;
+        opad[i] = bkey[i] ^ 0x5C5C5C5Cn;
+    }
+
+    var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
+    return core_sha1(opad.concat(hash), 512 + 160);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+// bigints
+function safe_add(x, y)
+{
+    var lsw = (x & 0xFFFFn) + (y & 0xFFFFn);
+    var msw = ((x >> 16n) & 0xFFFFn) + ((y >> 16n) & 0xFFFFn) + ((lsw >> 16n) & 0xFFFFn);
+    let r = (msw << 16n) | (lsw & 0xFFFFn);
+    return r;
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+// bigints arguments
+function rol(num, cnt)
+{
+    let rhs = (num >> (32n - BigInt(cnt)));
+    let mask = BigInt((1 << cnt) - 1);
+    rhs = rhs & mask;
+    let result = ((num << BigInt(cnt)) & 0xFFFFFFFFn) | rhs;
+    return result;
+}
+
+/*
+ * Convert an 8-bit or 16-bit string to an array of big-endian words
+ * In 8-bit function, characters >255 have their hi-byte silently ignored.
+ */
+function str2binb(str)
+{
+    var bin = Array();
+    var mask = ((1 << chrsz) - 1);
+    for (var i = 0; i < str.length * chrsz; i += chrsz) {
+        if (bin[i>>5] === undefined)
+            bin[i>>5] = 0n;
+        bin[i>>5] |= BigInt((str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32));
+    }
+    return bin;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+
+/*
+ * Convert an array of big-endian words to a hex string.
+ */
+function binb2hex(binarray)
+{
+    var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+    var str = "";
+    for(var i = 0; i < binarray.length * 4; i++)
+    {
+        str += hex_tab.charAt(bigIntToInt32((binarray[i>>2] >> BigInt((3 - i%4)*8+4)) & 0xFn)) +
+            hex_tab.charAt(bigIntToInt32((binarray[i>>2] >> BigInt((3 - i%4)*8)) & 0xFn));
+    }
+    return str;
+}
+
+/*
+ * Convert an array of big-endian words to a base-64 string
+ */
+function binb2b64(binarray)
+{
+    var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+    var str = "";
+    for(var i = 0; i < binarray.length * 4; i += 3)
+    {
+        var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
+            | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
+            |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
+        for(var j = 0; j < 4; j++)
+        {
+            if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+            else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+        }
+    }
+    return str;
+}
+
+
+function run() {
+    var plainText =
+"Two households, both alike in dignity,\n\
+In fair Verona, where we lay our scene,\n\
+From ancient grudge break to new mutiny,\n\
+Where civil blood makes civil hands unclean.\n\
+From forth the fatal loins of these two foes\n\
+A pair of star-cross'd lovers take their life;\n\
+Whole misadventured piteous overthrows\n\
+Do with their death bury their parents' strife.\n\
+The fearful passage of their death-mark'd love,\n\
+And the continuance of their parents' rage,\n\
+Which, but their children's end, nought could remove,\n\
+Is now the two hours' traffic of our stage;\n\
+The which if you with patient ears attend,\n\
+What here shall miss, our toil shall strive to mend.";
+
+    for (var i = 0; i <4; i++) {
+        plainText += plainText;
+    }
+
+    var sha1Output = hex_sha1(plainText);
+
+    var expected = "2524d264def74cce2498bf112bedf00e6c0b796d";
+    if (sha1Output != expected)
+        throw "ERROR: bad result: expected " + expected + " but got " + sha1Output;
+}
+
+
+let start = Date.now();
+for (let i = 0; i < 5; ++i)
+    run();
+// print("benchmark time:", Date.now() - start, "ms");

Modified: trunk/Source/_javascript_Core/ChangeLog (260682 => 260683)


--- trunk/Source/_javascript_Core/ChangeLog	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-04-25 00:34:59 UTC (rev 260683)
@@ -1,3 +1,101 @@
+2020-04-24  Saam Barati  <[email protected]>
+
+        Return BigInt32 whenever we can
+        https://bugs.webkit.org/show_bug.cgi?id=210922
+
+        Reviewed by Yusuke Suzuki.
+
+        This patch makes it so our runtime functions for big int math on heap
+        big ints converts the result to a big int 32 when possible.
+        
+        The inspiration for this patch came from converting SunSpider's sha1 benchmark to
+        using big ints. I found that that original implementation of big int 32
+        was a ~35% slowdown here. This patch speeds it up by 86% from ToT, and
+        36% faster than before big int 32 was introduced.
+        
+        To make this sound in the DFG/FTL, we are currently reporting that all
+        HeapBigInt math ops return SpecBigInt, instead of SpecHeapBigInt.
+        However, we want to do better in a follow up. We need some kind of profiling
+        system where we determine if we should speculate if the result is big int
+        32, a heap big int, or both:
+        https://bugs.webkit.org/show_bug.cgi?id=210982
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileValueBitNot):
+        (JSC::DFG::SpeculativeJIT::compileValueBitwiseOp):
+        (JSC::DFG::SpeculativeJIT::compileValueLShiftOp):
+        (JSC::DFG::SpeculativeJIT::compileValueBitRShift):
+        (JSC::DFG::SpeculativeJIT::compileValueAdd):
+        (JSC::DFG::SpeculativeJIT::compileValueSub):
+        (JSC::DFG::SpeculativeJIT::compileValueMul):
+        (JSC::DFG::SpeculativeJIT::compileValueDiv):
+        (JSC::DFG::SpeculativeJIT::compileValueMod):
+        (JSC::DFG::SpeculativeJIT::compileValuePow):
+        * jit/JITOperations.cpp:
+        * jsc.cpp:
+        (functionCreateBigInt32):
+        * runtime/BigIntConstructor.cpp:
+        (JSC::toBigInt):
+        (JSC::callBigIntConstructor):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/JSBigInt.cpp:
+        (JSC::JSBigInt::exponentiateHeap):
+        (JSC::JSBigInt::multiplyHeap):
+        (JSC::JSBigInt::divideHeap):
+        (JSC::JSBigInt::unaryMinusHeap):
+        (JSC::JSBigInt::remainderHeap):
+        (JSC::JSBigInt::incHeap):
+        (JSC::JSBigInt::decHeap):
+        (JSC::JSBigInt::addHeap):
+        (JSC::JSBigInt::subHeap):
+        (JSC::JSBigInt::bitwiseAndHeap):
+        (JSC::JSBigInt::bitwiseOrHeap):
+        (JSC::JSBigInt::bitwiseXorHeap):
+        (JSC::JSBigInt::leftShiftHeap):
+        (JSC::JSBigInt::signedRightShiftHeap):
+        (JSC::JSBigInt::bitwiseNotHeap):
+        (JSC::JSBigInt::absoluteAdd):
+        (JSC::JSBigInt::absoluteSub):
+        (JSC::JSBigInt::parseInt):
+        (JSC::JSBigInt::exponentiate): Deleted.
+        (JSC::JSBigInt::multiply): Deleted.
+        (JSC::JSBigInt::divide): Deleted.
+        (JSC::JSBigInt::unaryMinus): Deleted.
+        (JSC::JSBigInt::remainder): Deleted.
+        (JSC::JSBigInt::inc): Deleted.
+        (JSC::JSBigInt::dec): Deleted.
+        (JSC::JSBigInt::add): Deleted.
+        (JSC::JSBigInt::sub): Deleted.
+        (JSC::JSBigInt::bitwiseAnd): Deleted.
+        (JSC::JSBigInt::bitwiseOr): Deleted.
+        (JSC::JSBigInt::bitwiseXor): Deleted.
+        (JSC::JSBigInt::leftShift): Deleted.
+        (JSC::JSBigInt::signedRightShift): Deleted.
+        (JSC::JSBigInt::bitwiseNot): Deleted.
+        * runtime/JSBigInt.h:
+        * runtime/JSCJSValue.h:
+        (JSC::jsBigInt32):
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::JSValue):
+        * runtime/Operations.cpp:
+        (JSC::jsAddSlowCase):
+        * runtime/Operations.h:
+        (JSC::jsSub):
+        (JSC::jsMul):
+        (JSC::jsDiv):
+        (JSC::jsInc):
+        (JSC::jsDec):
+        (JSC::jsBitwiseNot):
+        (JSC::shift):
+        (JSC::bitwiseBinaryOp):
+
 2020-04-24  Michael Catanzaro  <[email protected]>
 
         [GTK][WPE][JSCOnly] compile error when -DWTF_CPU_ARM64_CORTEXA53=ON set for arm64

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (260682 => 260683)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2020-04-25 00:34:59 UTC (rev 260683)
@@ -508,10 +508,13 @@
 #else
             RELEASE_ASSERT_NOT_REACHED();
 #endif
-        } else if (node->child1().useKind() == HeapBigIntUse)
-            setTypeForNode(node, SpecHeapBigInt);
-        else if (node->child1().useKind() == AnyBigIntUse)
+        } else if (node->child1().useKind() == HeapBigIntUse) {
+            // FIXME: We will want an arithmetic mode here that allows us to speculate or dictate
+            // the format of our result:
+            // https://bugs.webkit.org/show_bug.cgi?id=210982
             setTypeForNode(node, SpecBigInt);
+        } else if (node->child1().useKind() == AnyBigIntUse)
+            setTypeForNode(node, SpecBigInt);
         else {
             clobberWorld();
             setTypeForNode(node, SpecInt32Only | SpecBigInt);
@@ -563,10 +566,13 @@
 #else
             DFG_CRASH(m_graph, node, "No BigInt32 support");
 #endif
-        } else if (node->binaryUseKind() == HeapBigIntUse)
-            setTypeForNode(node, SpecHeapBigInt);
-        else if (node->binaryUseKind() == AnyBigIntUse)
+        } else if (node->isBinaryUseKind(HeapBigIntUse)) {
+            // FIXME: We will want an arithmetic mode here that allows us to speculate or dictate
+            // the format of our result:
+            // https://bugs.webkit.org/show_bug.cgi?id=210982
             setTypeForNode(node, SpecBigInt);
+        } else if (node->binaryUseKind() == AnyBigIntUse)
+            setTypeForNode(node, SpecBigInt);
         else {
             clobberWorld();
             setTypeForNode(node, SpecInt32Only | SpecBigInt);
@@ -755,10 +761,13 @@
 
     case ValueSub:
     case ValueAdd: {
-        if (node->binaryUseKind() == HeapBigIntUse)
-            setTypeForNode(node, SpecHeapBigInt);
-        else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+        if (node->isBinaryUseKind(HeapBigIntUse)) {
+            // FIXME: We will want an arithmetic mode here that allows us to speculate or dictate
+            // the format of our result:
+            // https://bugs.webkit.org/show_bug.cgi?id=210982
             setTypeForNode(node, SpecBigInt);
+        } else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+            setTypeForNode(node, SpecBigInt);
         else {
             DFG_ASSERT(m_graph, node, node->binaryUseKind() == UntypedUse);
             clobberWorld();
@@ -996,7 +1005,10 @@
             setNonCellTypeForNode(node, typeOfDoubleIncOrDec(forNode(node->child1()).m_type));
             break;
         case HeapBigIntUse:
-            setTypeForNode(node, SpecHeapBigInt);
+            // FIXME: We will want an arithmetic mode here that allows us to speculate or dictate
+            // the format of our result:
+            // https://bugs.webkit.org/show_bug.cgi?id=210982
+            setTypeForNode(node, SpecBigInt);
             break;
         case AnyBigIntUse:
         case BigInt32Use:
@@ -1023,10 +1035,13 @@
             break;
         }
 
-        if (node->binaryUseKind() == HeapBigIntUse)
-            setTypeForNode(node, SpecHeapBigInt);
-        else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+        if (node->isBinaryUseKind(HeapBigIntUse)) {
+            // FIXME: We will want an arithmetic mode here that allows us to speculate or dictate
+            // the format of our result:
+            // https://bugs.webkit.org/show_bug.cgi?id=210982
             setTypeForNode(node, SpecBigInt);
+        } else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+            setTypeForNode(node, SpecBigInt);
         else {
             clobberWorld();
             setTypeForNode(node, SpecBytecodeNumber | SpecBigInt);
@@ -1036,10 +1051,13 @@
 
     case ValueMul: {
         // FIXME: why is this code not shared with ValueSub?
-        if (node->binaryUseKind() == HeapBigIntUse)
-            setTypeForNode(node, SpecHeapBigInt);
-        else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+        if (node->isBinaryUseKind(HeapBigIntUse)) {
+            // FIXME: We will want an arithmetic mode here that allows us to speculate or dictate
+            // the format of our result:
+            // https://bugs.webkit.org/show_bug.cgi?id=210982
             setTypeForNode(node, SpecBigInt);
+        } else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+            setTypeForNode(node, SpecBigInt);
         else {
             clobberWorld();
             setTypeForNode(node, SpecBytecodeNumber | SpecBigInt);
@@ -1102,10 +1120,13 @@
         if (handleConstantDivOp(node))
             break;
 
-        if (node->binaryUseKind() == HeapBigIntUse)
-            setTypeForNode(node, SpecHeapBigInt);
-        else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+        if (node->isBinaryUseKind(HeapBigIntUse)) {
+            // FIXME: We will want an arithmetic mode here that allows us to speculate or dictate
+            // the format of our result:
+            // https://bugs.webkit.org/show_bug.cgi?id=210982
             setTypeForNode(node, SpecBigInt);
+        } else if (node->binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)
+            setTypeForNode(node, SpecBigInt);
         else {
             clobberWorld();
             setTypeForNode(node, SpecBytecodeNumber | SpecBigInt);

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -214,7 +214,7 @@
 #if USE(BIGINT32)
             } else if (node->child1()->shouldSpeculateBigInt32()) {
                 node->setOp(op == Inc ? ValueAdd : ValueSub);
-                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(JSValue(JSValue::JSBigInt32, 1))));
+                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(jsBigInt32(1))));
                 node->children.setChild2(Edge(nodeConstantOne));
                 fixEdge<BigInt32Use>(node->child1());
                 fixEdge<BigInt32Use>(node->child2());
@@ -224,7 +224,7 @@
                 // FIXME: the freezing does not appear useful (since the JSCell is kept alive by vm), but it refuses to compile otherwise.
                 // FIXME: we might optimize inc/dec to a specialized function call instead in that case.
                 node->setOp(op == Inc ? ValueAdd : ValueSub);
-                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(JSValue(JSValue::JSBigInt32, 1))));
+                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(jsBigInt32(1))));
                 node->children.setChild2(Edge(nodeConstantOne));
                 fixEdge<AnyBigIntUse>(node->child1());
                 fixEdge<AnyBigIntUse>(node->child2());

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -1338,7 +1338,7 @@
     RELEASE_AND_RETURN(scope, regexp->test(globalObject, input));
 }
 
-JSCell* JIT_OPERATION operationSubHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationSubHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1347,10 +1347,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::sub(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::sub(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationBitNotHeapBigInt(JSGlobalObject* globalObject, JSCell* op1)
+EncodedJSValue JIT_OPERATION operationBitNotHeapBigInt(JSGlobalObject* globalObject, JSCell* op1)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1358,10 +1358,10 @@
 
     JSBigInt* operand = jsCast<JSBigInt*>(op1);
 
-    return JSBigInt::bitwiseNot(globalObject, operand);
+    return JSValue::encode(JSBigInt::bitwiseNot(globalObject, operand));
 }
 
-JSCell* JIT_OPERATION operationMulHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationMulHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1370,10 +1370,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
 
-    return JSBigInt::multiply(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::multiply(globalObject, leftOperand, rightOperand));
 }
     
-JSCell* JIT_OPERATION operationModHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationModHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1382,10 +1382,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::remainder(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::remainder(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationDivHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationDivHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1394,10 +1394,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::divide(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::divide(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationPowHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationPowHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1406,10 +1406,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::exponentiate(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::exponentiate(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationBitAndHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationBitAndHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1418,10 +1418,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
 
-    return JSBigInt::bitwiseAnd(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::bitwiseAnd(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationBitLShiftHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationBitLShiftHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1430,10 +1430,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
 
-    return JSBigInt::leftShift(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::leftShift(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationAddHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationAddHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1442,10 +1442,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::add(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::add(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationBitRShiftHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationBitRShiftHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1454,10 +1454,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::signedRightShift(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::signedRightShift(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationBitOrHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationBitOrHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1466,10 +1466,10 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::bitwiseOr(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::bitwiseOr(globalObject, leftOperand, rightOperand));
 }
 
-JSCell* JIT_OPERATION operationBitXorHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
+EncodedJSValue JIT_OPERATION operationBitXorHeapBigInt(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -1478,7 +1478,7 @@
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
 
-    return JSBigInt::bitwiseXor(globalObject, leftOperand, rightOperand);
+    return JSValue::encode(JSBigInt::bitwiseXor(globalObject, leftOperand, rightOperand));
 }
 
 size_t JIT_OPERATION operationCompareStrictEqCell(JSGlobalObject* globalObject, JSCell* op1, JSCell* op2)

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (260682 => 260683)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2020-04-25 00:34:59 UTC (rev 260683)
@@ -183,18 +183,18 @@
 size_t JIT_OPERATION operationRegExpTest(JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
 size_t JIT_OPERATION operationRegExpTestGeneric(JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
 size_t JIT_OPERATION operationCompareStrictEqCell(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationSubHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationMulHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationModHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationDivHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationPowHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationBitAndHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationBitNotHeapBigInt(JSGlobalObject*, JSCell* op1) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationBitOrHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationBitLShiftHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationAddHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationBitRShiftHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationBitXorHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationSubHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationMulHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationModHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationDivHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationPowHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationBitAndHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationBitNotHeapBigInt(JSGlobalObject*, JSCell* op1) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationBitOrHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationBitLShiftHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationAddHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationBitRShiftHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationBitXorHeapBigInt(JSGlobalObject*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
 size_t JIT_OPERATION operationSameValue(JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationCreateActivationDirect(VM*, Structure*, JSScope*, SymbolTable*, EncodedJSValue);
 JSCell* JIT_OPERATION operationCreateDirectArguments(VM*, Structure*, uint32_t length, uint32_t minCapacity);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -3575,12 +3575,12 @@
         speculateHeapBigInt(child1, operandGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        callOperation(operationBitNotHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), operandGPR);
+        callOperation(operationBitNotHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), operandGPR);
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
 
         return;
     }
@@ -3746,7 +3746,7 @@
     // FIXME: add support for mixed BigInt32 / HeapBigInt
 #endif
 
-    if (leftChild.useKind() == HeapBigIntUse && rightChild.useKind() == HeapBigIntUse) {
+    if (node->isBinaryUseKind(HeapBigIntUse)) {
         SpeculateCellOperand left(this, node->child1());
         SpeculateCellOperand right(this, node->child2());
         GPRReg leftGPR = left.gpr();
@@ -3756,18 +3756,18 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
         switch (op) {
         case ValueBitAnd:
-            callOperation(operationBitAndHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+            callOperation(operationBitAndHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
             break;
         case ValueBitXor:
-            callOperation(operationBitXorHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+            callOperation(operationBitXorHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
             break;
         case ValueBitOr:
-            callOperation(operationBitOrHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+            callOperation(operationBitOrHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
             break;
         default:
             RELEASE_ASSERT_NOT_REACHED();
@@ -3774,7 +3774,7 @@
         }
 
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -3947,12 +3947,12 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        callOperation(operationBitLShiftHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        callOperation(operationBitLShiftHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -3975,12 +3975,12 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
-        callOperation(operationBitRShiftHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
+        callOperation(operationBitRShiftHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
         m_jit.exceptionCheck();
 
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -4081,12 +4081,12 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
-        callOperation(operationAddHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
+        callOperation(operationAddHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
         m_jit.exceptionCheck();
 
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -4185,13 +4185,13 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        callOperation(operationSubHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        callOperation(operationSubHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
 
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -5014,13 +5014,13 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        callOperation(operationMulHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        callOperation(operationMulHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
 
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -5220,13 +5220,13 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        callOperation(operationDivHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        callOperation(operationDivHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
 
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -5511,13 +5511,13 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        callOperation(operationModHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        callOperation(operationModHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
 
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 
@@ -6078,13 +6078,13 @@
         speculateHeapBigInt(rightChild, rightGPR);
 
         flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        callOperation(operationPowHeapBigInt, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
+        callOperation(operationPowHeapBigInt, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), leftGPR, rightGPR);
 
         m_jit.exceptionCheck();
-        cellResult(resultGPR, node);
+        jsValueResult(resultRegs, node);
         return;
     }
 

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -2878,7 +2878,7 @@
     if (primValue.isBigInt32()) {
         int32_t value = primValue.bigInt32AsInt32();
         if (value != INT_MIN)
-            return JSValue::encode(JSValue(JSValue::JSBigInt32, -value));
+            return JSValue::encode(jsBigInt32(-value));
         primValue = JSBigInt::createFrom(vm, value);
     }
 #endif
@@ -2910,7 +2910,7 @@
     if (primValue.isBigInt32()) {
         int32_t value = primValue.bigInt32AsInt32();
         if (value != INT_MIN) {
-            auto result = JSValue(JSValue::JSBigInt32, -value);
+            auto result = jsBigInt32(-value);
             arithProfile->observeResult(result);
             return JSValue::encode(result);
         }
@@ -2918,7 +2918,7 @@
     }
 #endif
     if (primValue.isHeapBigInt()) {
-        JSBigInt* result = JSBigInt::unaryMinus(vm, primValue.asHeapBigInt());
+        JSValue result = JSBigInt::unaryMinus(vm, primValue.asHeapBigInt());
         arithProfile->observeResult(result);
         return JSValue::encode(result);
     }
@@ -2956,7 +2956,7 @@
     if (primValue.isBigInt32()) {
         int32_t value = primValue.bigInt32AsInt32();
         if (value != INT_MIN) {
-            auto result = JSValue(JSValue::JSBigInt32, -value);
+            auto result = jsBigInt32(-value);
             arithProfile->observeResult(result);
             return JSValue::encode(result);
         }
@@ -2964,7 +2964,7 @@
     }
 #endif
     if (primValue.isHeapBigInt()) {
-        JSBigInt* result = JSBigInt::unaryMinus(vm, primValue.asHeapBigInt());
+        JSValue result = JSBigInt::unaryMinus(vm, primValue.asHeapBigInt());
         arithProfile->observeResult(result);
         return JSValue::encode(result);
     }
@@ -3002,7 +3002,7 @@
     if (primValue.isBigInt32()) {
         int32_t value = primValue.bigInt32AsInt32();
         if (value != INT_MIN)
-            return JSValue::encode(JSValue(JSValue::JSBigInt32, -value));
+            return JSValue::encode(jsBigInt32(-value));
         primValue = JSBigInt::createFrom(vm, value);
     }
 #endif

Modified: trunk/Source/_javascript_Core/jsc.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/jsc.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/jsc.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -2290,15 +2290,15 @@
     ASSERT(bigIntValue.isHeapBigInt());
     JSBigInt* bigInt = jsCast<JSBigInt*>(bigIntValue);
     if (!bigInt->length())
-        return JSValue::encode(JSValue(JSValue::JSBigInt32, 0));
+        return JSValue::encode(jsBigInt32(0));
     if (bigInt->length() == 1) {
         JSBigInt::Digit digit = bigInt->digit(0);
         if (bigInt->sign()) {
             if (digit <= static_cast<uint64_t>(-static_cast<int64_t>(INT32_MIN)))
-                return JSValue::encode(JSValue(JSValue::JSBigInt32, static_cast<int32_t>(-static_cast<int64_t>(digit))));
+                return JSValue::encode(jsBigInt32(static_cast<int32_t>(-static_cast<int64_t>(digit))));
         } else {
             if (digit <= INT32_MAX)
-                return JSValue::encode(JSValue(JSValue::JSBigInt32, static_cast<int32_t>(digit)));
+                return JSValue::encode(jsBigInt32(static_cast<int32_t>(digit)));
         }
     }
     throwTypeError(globalObject, scope, "Out of range of BigInt32"_s);

Modified: trunk/Source/_javascript_Core/runtime/BigIntConstructor.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/BigIntConstructor.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/BigIntConstructor.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -86,7 +86,7 @@
 
     if (argument.isBoolean()) {
 #if USE(BIGINT32)
-        return JSValue(JSValue::JSBigInt32, argument.asBoolean());
+        return jsBigInt32(argument.asBoolean());
 #else
         return JSBigInt::createFrom(vm, argument.asBoolean());
 #endif
@@ -115,7 +115,7 @@
 
     if (primitive.isInt32()) {
 #if USE(BIGINT32)
-        return JSValue::encode(JSValue(JSValue::JSBigInt32, primitive.asInt32()));
+        return JSValue::encode(jsBigInt32(primitive.asInt32()));
 #else
         return JSValue::encode(JSBigInt::createFrom(vm, primitive.asInt32()));
 #endif

Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -547,7 +547,7 @@
     if (primValue.isBigInt32()) {
         int32_t value = primValue.bigInt32AsInt32();
         if (value != INT_MIN) {
-            auto result = JSValue(JSValue::JSBigInt32, -value);
+            auto result = jsBigInt32(-value);
             RETURN_WITH_PROFILING(result, {
                 updateArithProfileForUnaryArithOp(metadata, result, operand);
             });
@@ -557,7 +557,7 @@
 #endif
 
     if (primValue.isHeapBigInt()) {
-        JSBigInt* result = JSBigInt::unaryMinus(vm, primValue.asHeapBigInt());
+        JSValue result = JSBigInt::unaryMinus(vm, primValue.asHeapBigInt());
         RETURN_WITH_PROFILING(result, {
             updateArithProfileForUnaryArithOp(metadata, result, operand);
         });

Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/JSBigInt.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -237,7 +237,7 @@
     internalMultiplyAdd(this, factor, summand, length(), this);
 }
 
-JSBigInt* JSBigInt::exponentiate(JSGlobalObject* globalObject, JSBigInt* base, JSBigInt* exponent)
+JSBigInt* JSBigInt::exponentiateHeap(JSGlobalObject* globalObject, JSBigInt* base, JSBigInt* exponent)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -259,7 +259,7 @@
     if (base->length() == 1 && base->digit(0) == 1) {
         // (-1) ** even_number == 1.
         if (base->sign() && !(exponent->digit(0) & 1))
-            return JSBigInt::unaryMinus(vm, base);
+            return JSBigInt::unaryMinusHeap(vm, base);
 
         // (-1) ** odd_number == -1; 1 ** anything == 1.
         return base;
@@ -309,7 +309,7 @@
 
     n >>= 1;
     for (; n; n >>= 1) {
-        JSBigInt* maybeResult = JSBigInt::multiply(globalObject, runningSquare, runningSquare);
+        JSBigInt* maybeResult = JSBigInt::multiplyHeap(globalObject, runningSquare, runningSquare);
         RETURN_IF_EXCEPTION(scope, nullptr);
         runningSquare = maybeResult;
         if (n & 1) {
@@ -316,7 +316,7 @@
             if (!result)
                 result = runningSquare;
             else {
-                maybeResult = JSBigInt::multiply(globalObject, result, runningSquare);
+                maybeResult = JSBigInt::multiplyHeap(globalObject, result, runningSquare);
                 RETURN_IF_EXCEPTION(scope, nullptr);
                 result = maybeResult;
             }
@@ -326,7 +326,7 @@
     return result;
 }
 
-JSBigInt* JSBigInt::multiply(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::multiplyHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -348,7 +348,7 @@
     return result->rightTrim(vm);
 }
 
-JSBigInt* JSBigInt::divide(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::divideHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     // 1. If y is 0n, throw a RangeError exception.
     VM& vm = globalObject->vm();
@@ -370,7 +370,7 @@
     if (y->length() == 1) {
         Digit divisor = y->digit(0);
         if (divisor == 1)
-            return resultSign == x->sign() ? x : unaryMinus(vm, x);
+            return resultSign == x->sign() ? x : JSBigInt::unaryMinusHeap(vm, x);
 
         Digit remainder;
         absoluteDivWithDigitDivisor(vm, x, divisor, &quotient, remainder);
@@ -393,7 +393,7 @@
     return result;
 }
 
-JSBigInt* JSBigInt::unaryMinus(VM& vm, JSBigInt* x)
+JSBigInt* JSBigInt::unaryMinusHeap(VM& vm, JSBigInt* x)
 {
     if (x->isZero())
         return x;
@@ -403,7 +403,7 @@
     return result;
 }
 
-JSBigInt* JSBigInt::remainder(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::remainderHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     // 1. If y is 0n, throw a RangeError exception.
     VM& vm = globalObject->vm();
@@ -441,7 +441,7 @@
     return remainder->rightTrim(vm);
 }
 
-JSBigInt* JSBigInt::inc(JSGlobalObject* globalObject, JSBigInt* x)
+JSBigInt* JSBigInt::incHeap(JSGlobalObject* globalObject, JSBigInt* x)
 {
     if (!x->sign())
         return absoluteAddOne(globalObject, x, SignOption::Unsigned);
@@ -452,7 +452,7 @@
     return result;
 }
 
-JSBigInt* JSBigInt::dec(JSGlobalObject* globalObject, JSBigInt* x)
+JSBigInt* JSBigInt::decHeap(JSGlobalObject* globalObject, JSBigInt* x)
 {
     if (x->isZero()) {
         JSBigInt* result = createFrom(globalObject->vm(), 1);
@@ -464,7 +464,7 @@
     return absoluteAddOne(globalObject, x, SignOption::Signed);
 }
 
-JSBigInt* JSBigInt::add(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::addHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     VM& vm = globalObject->vm();
     bool xSign = x->sign();
@@ -483,7 +483,7 @@
     return absoluteSub(vm, y, x, !xSign);
 }
 
-JSBigInt* JSBigInt::sub(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::subHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     VM& vm = globalObject->vm();
     bool xSign = x->sign();
@@ -501,7 +501,7 @@
     return absoluteSub(vm, y, x, !xSign);
 }
 
-JSBigInt* JSBigInt::bitwiseAnd(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::bitwiseAndHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -536,7 +536,7 @@
     return absoluteAndNot(vm, x, y1);
 }
 
-JSBigInt* JSBigInt::bitwiseOr(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::bitwiseOrHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -577,7 +577,7 @@
     return absoluteAddOne(globalObject, result, SignOption::Signed);
 }
 
-JSBigInt* JSBigInt::bitwiseXor(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::bitwiseXorHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -615,7 +615,7 @@
     return absoluteAddOne(globalObject, result, SignOption::Signed);
 }
 
-JSBigInt* JSBigInt::leftShift(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::leftShiftHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     if (y->isZero() || x->isZero())
         return x;
@@ -626,7 +626,7 @@
     return leftShiftByAbsolute(globalObject, x, y);
 }
 
-JSBigInt* JSBigInt::signedRightShift(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::signedRightShiftHeap(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
 {
     if (y->isZero() || x->isZero())
         return x;
@@ -637,7 +637,7 @@
     return rightShiftByAbsolute(globalObject, x, y);
 }
 
-JSBigInt* JSBigInt::bitwiseNot(JSGlobalObject* globalObject, JSBigInt* x)
+JSBigInt* JSBigInt::bitwiseNotHeap(JSGlobalObject* globalObject, JSBigInt* x)
 {
     if (x->sign()) {
         // ~(-x) == ~(~(x-1)) == x-1
@@ -953,7 +953,7 @@
     }
 
     if (y->isZero())
-        return resultSign == x->sign() ? x : unaryMinus(vm, x);
+        return resultSign == x->sign() ? x : unaryMinusHeap(vm, x);
 
     JSBigInt* result = JSBigInt::tryCreateWithLength(globalObject, x->length() + 1);
     if (!result)
@@ -993,7 +993,7 @@
     }
 
     if (y->isZero())
-        return resultSign == x->sign() ? x : unaryMinus(vm, x);
+        return resultSign == x->sign() ? x : JSBigInt::unaryMinusHeap(vm, x);
 
     if (comparisonResult == ComparisonResult::Equal)
         return JSBigInt::createZero(vm);
@@ -1860,7 +1860,7 @@
 
     if (p == length) {
 #if USE(BIGINT32)
-        return JSValue(JSValue::JSBigInt32, 0);
+        return jsBigInt32(0);
 #else
         return createZero(vm);
 #endif
@@ -1974,7 +1974,7 @@
 
                 if (static_cast<int64_t>(static_cast<int32_t>(maybeResult)) == maybeResult) {
 #if USE(BIGINT32)
-                    return JSValue(JSValue::JSBigInt32, static_cast<int32_t>(maybeResult));
+                    return jsBigInt32(static_cast<int32_t>(maybeResult));
 #else
                     return JSBigInt::createFrom(vm, static_cast<int32_t>(maybeResult));
 #endif

Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.h (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/JSBigInt.h	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.h	2020-04-25 00:34:59 UTC (rev 260683)
@@ -86,7 +86,7 @@
     {
 #if USE(BIGINT32)
         if (value <= INT_MAX && value >= INT_MIN)
-            return JSValue(JSValue::JSBigInt32, static_cast<int32_t>(value));
+            return jsBigInt32(static_cast<int32_t>(value));
 #endif
 
         auto ptr = JSBigInt::createFrom(vm, value);
@@ -120,6 +120,32 @@
         GreaterThan,
         LessThan
     };
+
+    static ALWAYS_INLINE JSValue tryConvertToBigInt32(JSBigInt* bigInt)
+    {
+#if USE(BIGINT32)
+        if (UNLIKELY(!bigInt))
+            return JSValue();
+
+        if (bigInt->length() <= 1) {
+            if (!bigInt->length())
+                return jsBigInt32(0);
+            Digit digit = bigInt->digit(0);
+            if (bigInt->sign()) {
+                static constexpr uint64_t maxValue = -static_cast<int64_t>(std::numeric_limits<int32_t>::min());
+                if (digit <= maxValue)
+                    return jsBigInt32(static_cast<int32_t>(-static_cast<int64_t>(digit)));
+            } else {
+                static constexpr uint64_t maxValue = static_cast<uint64_t>(std::numeric_limits<int32_t>::max());
+                if (digit <= maxValue)
+                    return jsBigInt32(static_cast<int32_t>(digit));
+            }
+        }
+#endif
+
+        return bigInt;
+    }
+
     
     JS_EXPORT_PRIVATE static bool equals(JSBigInt*, JSBigInt*);
     bool equalsToNumber(JSValue);
@@ -135,28 +161,98 @@
     JSObject* toObject(JSGlobalObject*) const;
     inline bool toBoolean() const { return !isZero(); }
 
-    static JSBigInt* exponentiate(JSGlobalObject*, JSBigInt* base, JSBigInt* exponent);
+    ComparisonResult static compareToDouble(JSBigInt* x, double y);
 
-    static JSBigInt* multiply(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSBigInt* exponentiateHeap(JSGlobalObject*, JSBigInt* base, JSBigInt* exponent);
+    static JSValue exponentiate(JSGlobalObject* globalObject, JSBigInt* base, JSBigInt* exponent)
+    {
+        return tryConvertToBigInt32(exponentiateHeap(globalObject, base, exponent));
+    }
+
+    static JSBigInt* multiplyHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue multiply(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(multiplyHeap(globalObject, x, y));
+    }
     
-    ComparisonResult static compareToDouble(JSBigInt* x, double y);
+    static JSBigInt* incHeap(JSGlobalObject*, JSBigInt* x);
+    static JSValue inc(JSGlobalObject* globalObject, JSBigInt* x)
+    {
+        return tryConvertToBigInt32(incHeap(globalObject, x));
+    }
 
-    static JSBigInt* inc(JSGlobalObject*, JSBigInt* x);
-    static JSBigInt* dec(JSGlobalObject*, JSBigInt* x);
-    static JSBigInt* add(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* sub(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* divide(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* remainder(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* unaryMinus(VM&, JSBigInt* x);
+    static JSBigInt* decHeap(JSGlobalObject*, JSBigInt* x);
+    static JSValue dec(JSGlobalObject* globalObject, JSBigInt* x)
+    {
+        return tryConvertToBigInt32(decHeap(globalObject, x));
+    }
 
-    static JSBigInt* bitwiseAnd(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* bitwiseOr(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* bitwiseXor(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* bitwiseNot(JSGlobalObject*, JSBigInt* x);
+    static JSBigInt* addHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue add(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(addHeap(globalObject, x, y));
+    }
 
-    static JSBigInt* leftShift(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* signedRightShift(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSBigInt* subHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue sub(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return subHeap(globalObject, x, y);
+    }
 
+    static JSBigInt* divideHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue divide(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(divideHeap(globalObject, x, y));
+    }
+
+    static JSBigInt* remainderHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue remainder(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(remainderHeap(globalObject, x, y));
+    }
+
+    static JSBigInt* unaryMinusHeap(VM&, JSBigInt* x);
+    static JSValue unaryMinus(VM& vm, JSBigInt* x)
+    {
+        return tryConvertToBigInt32(unaryMinusHeap(vm, x));
+    }
+
+    static JSBigInt* bitwiseAndHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue bitwiseAnd(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(bitwiseAndHeap(globalObject, x, y));
+    }
+
+    static JSBigInt* bitwiseOrHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue bitwiseOr(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(bitwiseOrHeap(globalObject, x, y));
+    }
+
+    static JSBigInt* bitwiseXorHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue bitwiseXor(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(bitwiseXorHeap(globalObject, x, y));
+    }
+
+    static JSBigInt* bitwiseNotHeap(JSGlobalObject*, JSBigInt* x);
+    static JSValue bitwiseNot(JSGlobalObject* globalObject, JSBigInt* x)
+    {
+        return tryConvertToBigInt32(bitwiseNotHeap(globalObject, x));
+    }
+
+    static JSBigInt* leftShiftHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue leftShift(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(leftShiftHeap(globalObject, x, y));
+    }
+
+    static JSBigInt* signedRightShiftHeap(JSGlobalObject*, JSBigInt* x, JSBigInt* y);
+    static JSValue signedRightShift(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
+    {
+        return tryConvertToBigInt32(signedRightShiftHeap(globalObject, x, y));
+    }
+
     Digit digit(unsigned);
     void setDigit(unsigned, Digit); // Use only when initializing.
     JS_EXPORT_PRIVATE JSBigInt* rightTrim(VM&);

Modified: trunk/Source/_javascript_Core/runtime/JSCJSValue.h (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/JSCJSValue.h	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValue.h	2020-04-25 00:34:59 UTC (rev 260683)
@@ -178,7 +178,7 @@
     enum JSFalseTag { JSFalse };
     enum JSCellTag { JSCellType };
 #if USE(BIGINT32)
-    enum JSBigInt32Tag { JSBigInt32 };
+    enum EncodeAsBigInt32Tag { EncodeAsBigInt32 };
 #endif
     enum EncodeAsDoubleTag { EncodeAsDouble };
 
@@ -190,7 +190,7 @@
     JSValue(JSCell* ptr);
     JSValue(const JSCell* ptr);
 #if USE(BIGINT32)
-    JSValue(JSBigInt32Tag, int32_t);
+    JSValue(EncodeAsBigInt32Tag, int32_t);
 #endif
 
     // Numbers
@@ -577,6 +577,13 @@
     return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
 }
 
+#if USE(BIGINT32)
+ALWAYS_INLINE JSValue jsBigInt32(int32_t intValue)
+{
+    return JSValue(JSValue::EncodeAsBigInt32, intValue);
+}
+#endif
+
 ALWAYS_INLINE JSValue jsDoubleNumber(double d)
 {
     ASSERT(JSValue(JSValue::EncodeAsDouble, d).isNumber());

Modified: trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h	2020-04-25 00:34:59 UTC (rev 260683)
@@ -538,7 +538,7 @@
 #endif // USE(JSVALUE64)
 
 #if USE(BIGINT32)
-inline JSValue::JSValue(JSBigInt32Tag, int32_t value)
+inline JSValue::JSValue(EncodeAsBigInt32Tag, int32_t value)
 {
     uint64_t shiftedValue = static_cast<uint64_t>(static_cast<uint32_t>(value)) << 16;
     ASSERT(!(shiftedValue & NumberTag));

Modified: trunk/Source/_javascript_Core/runtime/Operations.cpp (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/Operations.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/Operations.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -77,7 +77,7 @@
         result += right;
         if (UNLIKELY(result.hasOverflowed()))
             return JSValue();
-        return JSValue(JSValue::JSBigInt32, result.unsafeGet());
+        return jsBigInt32(result.unsafeGet());
 #else
         UNUSED_PARAM(left);
         UNUSED_PARAM(right);

Modified: trunk/Source/_javascript_Core/runtime/Operations.h (260682 => 260683)


--- trunk/Source/_javascript_Core/runtime/Operations.h	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/_javascript_Core/runtime/Operations.h	2020-04-25 00:34:59 UTC (rev 260683)
@@ -589,7 +589,7 @@
         result -= right;
         if (UNLIKELY(result.hasOverflowed()))
             return JSValue();
-        return JSValue(JSValue::JSBigInt32, result.unsafeGet());
+        return jsBigInt32(result.unsafeGet());
 #else
         UNUSED_PARAM(left);
         UNUSED_PARAM(right);
@@ -611,7 +611,7 @@
         result *= right;
         if (result.hasOverflowed())
             return JSValue();
-        return JSValue(JSValue::JSBigInt32, result.unsafeGet());
+        return jsBigInt32(result.unsafeGet());
 #else
         UNUSED_PARAM(left);
         UNUSED_PARAM(right);
@@ -631,7 +631,7 @@
 #if USE(BIGINT32)
         if (!right)
             return JSValue();
-        return JSValue(JSValue::JSBigInt32, left / right);
+        return jsBigInt32(left / right);
 #else
         UNUSED_PARAM(left);
         UNUSED_PARAM(right);
@@ -686,7 +686,7 @@
         // FIXME: the following next few lines might benefit from being made into a helper function
         if (newValue > INT_MAX)
             return JSBigInt::createFrom(vm, newValue);
-        return JSValue(JSValue::JSBigInt32, static_cast<int32_t>(newValue));
+        return jsBigInt32(static_cast<int32_t>(newValue));
     }
 #endif
 
@@ -711,7 +711,7 @@
         // FIXME: the following next few lines might benefit from being made into a helper function
         if (newValue < INT_MIN)
             return JSBigInt::createFrom(vm, newValue);
-        return JSValue(JSValue::JSBigInt32, static_cast<int32_t>(newValue));
+        return jsBigInt32(static_cast<int32_t>(newValue));
     }
 #endif
 
@@ -732,7 +732,7 @@
 
 #if USE(BIGINT32)
     if (operandNumeric.isBigInt32())
-        return JSValue(JSValue::JSBigInt32, ~operandNumeric.bigInt32AsInt32());
+        return jsBigInt32(~operandNumeric.bigInt32AsInt32());
 #endif
 
     ASSERT(operandNumeric.isHeapBigInt());
@@ -767,7 +767,7 @@
 
         // 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 JSValue(JSValue::JSBigInt32, leftInt32 >> std::min(rightInt32, 31));
+            return jsBigInt32(leftInt32 >> std::min(rightInt32, 31));
 
         // 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.
@@ -826,7 +826,7 @@
 
 #if USE(BIGINT32)
     if (leftNumeric.isBigInt32() && rightNumeric.isBigInt32())
-        return JSValue(JSValue::JSBigInt32, int32Op(leftNumeric.bigInt32AsInt32(), rightNumeric.bigInt32AsInt32()));
+        return jsBigInt32(int32Op(leftNumeric.bigInt32AsInt32(), rightNumeric.bigInt32AsInt32()));
     // FIXME: add fast path for BigInt32 / HeapBigInt, and for HeapBigInt / BigInt32
     // In many cases these could be made more efficient than heap-allocating the small big-int and going through the generic path.
     // But it is quite tricky, not least because HeapBigInt use a sign bit whereas BigInt32 use 2-complement representation.

Modified: trunk/Source/WebCore/ChangeLog (260682 => 260683)


--- trunk/Source/WebCore/ChangeLog	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/WebCore/ChangeLog	2020-04-25 00:34:59 UTC (rev 260683)
@@ -1,3 +1,13 @@
+2020-04-24  Saam Barati  <[email protected]>
+
+        Return BigInt32 whenever we can
+        https://bugs.webkit.org/show_bug.cgi?id=210922
+
+        Reviewed by Yusuke Suzuki.
+
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneDeserializer::readBigInt):
+
 2020-04-24  Yusuke Suzuki  <[email protected]>
 
         [WTF] allThreads registration is racy with allThreads unregistration

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (260682 => 260683)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-04-24 23:56:38 UTC (rev 260682)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-04-25 00:34:59 UTC (rev 260683)
@@ -3005,7 +3005,7 @@
 
         if (!lengthInUint64) {
 #if USE(BIGINT32)
-            return JSValue(JSValue::JSBigInt32, 0);
+            return jsBigInt32(0);
 #else
             JSBigInt* bigInt = JSBigInt::createZero(m_lexicalGlobalObject->vm());
             m_gcBuffer.appendWithCrashOnOverflow(bigInt);
@@ -3022,10 +3022,10 @@
                 return JSValue();
             if (sign) {
                 if (digit64 <= static_cast<uint64_t>(-static_cast<int64_t>(INT32_MIN)))
-                    return JSValue(JSValue::JSBigInt32, static_cast<int32_t>(-static_cast<int64_t>(digit64)));
+                    return jsBigInt32(static_cast<int32_t>(-static_cast<int64_t>(digit64)));
             } else {
                 if (digit64 <= INT32_MAX)
-                    return JSValue(JSValue::JSBigInt32, static_cast<int32_t>(digit64));
+                    return jsBigInt32(static_cast<int32_t>(digit64));
             }
             ASSERT(digit64 != 0);
             JSBigInt* bigInt = JSBigInt::tryCreateWithLength(m_lexicalGlobalObject, 1);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to