Title: [267373] trunk
Revision
267373
Author
[email protected]
Date
2020-09-21 15:10:24 -0700 (Mon, 21 Sep 2020)

Log Message

[JSC] BigInt should work with Map / Set
https://bugs.webkit.org/show_bug.cgi?id=216667
JSTests:

<rdar://problem/69107221>

Reviewed by Robin Morisset.

* stress/bigint-and-map-set.js: Added.
(shouldBe):
(opaque1n):
(testMap):
(let.set new):
* stress/bigint-string-map-set.js: Added.
(shouldBe):
(testMap):
* stress/bigint32-map-set.js: Added.
(shouldBe):
(testMap):

Source/_javascript_Core:

Reviewed by Robin Morisset.

This patch makes BigInt supported in Map / Set.

1. In NormalizeMapKey, we always attempt to convert HeapBigInt to BigInt32 (if supported). So we ensure that,
    normalized BigInt has one unique form for BigInt32 range. This allows us to use hashing for BigInt32 bit pattern directly.
2. In MapHash, for BigInt32, we directly has the JSValue bits. For HeapBigInt, we calculate hash via Hasher.
3. In GetMapBucket, we consider HeapBigInt case correctly.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupNormalizeMapKey):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNormalizeMapKey):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileMapHash):
(JSC::FTL::DFG::LowerDFGToB3::compileNormalizeMapKey):
(JSC::FTL::DFG::LowerDFGToB3::compileGetMapBucket):
* runtime/HashMapImpl.h:
(JSC::normalizeMapKey):
(JSC::jsMapHash):
(JSC::concurrentJSMapHash):
* runtime/JSBigInt.cpp:
(JSC::JSBigInt::concurrentHash):
* runtime/JSBigInt.h:
(JSC::tryConvertToBigInt32):

Source/WebCore:

<rdar://problem/69107221>

Reviewed by Robin Morisset.

Strongly ensure that BigInt32 is always selected since Map / Set could use it as a key.

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

Source/WTF:

Reviewed by Robin Morisset.

* wtf/Hasher.h:
(WTF::Hasher::hash const):
(WTF::add):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (267372 => 267373)


--- trunk/JSTests/ChangeLog	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/JSTests/ChangeLog	2020-09-21 22:10:24 UTC (rev 267373)
@@ -1,5 +1,25 @@
 2020-09-21  Yusuke Suzuki  <[email protected]>
 
+        [JSC] BigInt should work with Map / Set
+        https://bugs.webkit.org/show_bug.cgi?id=216667
+        <rdar://problem/69107221>
+
+        Reviewed by Robin Morisset.
+
+        * stress/bigint-and-map-set.js: Added.
+        (shouldBe):
+        (opaque1n):
+        (testMap):
+        (let.set new):
+        * stress/bigint-string-map-set.js: Added.
+        (shouldBe):
+        (testMap):
+        * stress/bigint32-map-set.js: Added.
+        (shouldBe):
+        (testMap):
+
+2020-09-21  Yusuke Suzuki  <[email protected]>
+
         [JSC] Proxy should be trapped if base value is primitive
         https://bugs.webkit.org/show_bug.cgi?id=216764
 

Added: trunk/JSTests/stress/bigint-and-map-set.js (0 => 267373)


--- trunk/JSTests/stress/bigint-and-map-set.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint-and-map-set.js	2020-09-21 22:10:24 UTC (rev 267373)
@@ -0,0 +1,44 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function opaque1n()
+{
+    return 1n;
+}
+noInline(opaque1n);
+
+function testMap(map) {
+    map.set(1n, 42);
+    shouldBe(map.has(1n), true);
+    shouldBe(map.has(opaque1n()), true);
+    shouldBe(map.has(createHeapBigInt(opaque1n())), true);
+    shouldBe(map.get(1n), 42);
+    shouldBe(map.get(opaque1n()), 42);
+    shouldBe(map.get(createHeapBigInt(opaque1n())), 42);
+    map.set(1n, 40);
+    shouldBe(map.get(1n), 40);
+    shouldBe(map.get(opaque1n()), 40);
+    shouldBe(map.get(createHeapBigInt(opaque1n())), 40);
+}
+noInline(testMap);
+
+function testSet(set) {
+    set.add(1n);
+    shouldBe(set.has(1n), true);
+    shouldBe(set.has(opaque1n()), true);
+    shouldBe(set.has(createHeapBigInt(opaque1n())), true);
+    set.delete(createHeapBigInt(opaque1n()));
+    shouldBe(set.has(1n), false);
+    shouldBe(set.has(opaque1n()), false);
+    shouldBe(set.has(createHeapBigInt(opaque1n())), false);
+}
+noInline(testSet);
+
+let map = new Map();
+let set = new Set();
+for (let i = 0; i < 1e4; ++i) {
+    testMap(map);
+    testSet(set);
+}

Added: trunk/JSTests/stress/bigint-string-map-set.js (0 => 267373)


--- trunk/JSTests/stress/bigint-string-map-set.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint-string-map-set.js	2020-09-21 22:10:24 UTC (rev 267373)
@@ -0,0 +1,77 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function testMap(map, key)
+{
+    return map.has(key);
+}
+noInline(testMap);
+
+function testSet(set, key)
+{
+    return set.has(key);
+}
+noInline(testSet);
+
+let map = new Map();
+map.set("Hey", "Hey");
+map.set(null, null);
+map.set(1n, 1n);
+map.set(2n, 2n);
+map.set(0xffffffffffffffffn, 0xffffffffffffffffn);
+map.set("Hello", "Hello");
+
+let set = new Set();
+set.add("Hey");
+set.add(null);
+set.add(1n);
+set.add(2n);
+set.add(0xffffffffffffffffn);
+set.add("Hello");
+
+// String
+for (let i = 0; i < 1e4; ++i) {
+    shouldBe(testMap(map, "Hey"), true);
+    shouldBe(testSet(set, "Hey"), true);
+    shouldBe(testMap(map, "Hey1"), false);
+    shouldBe(testSet(set, "Hey1"), false);
+    shouldBe(testMap(map, "Hello"), true);
+    shouldBe(testSet(set, "Hello"), true);
+}
+
+// Cell
+for (let i = 0; i < 1e4; ++i) {
+    shouldBe(testMap(map, "Hey"), true);
+    shouldBe(testSet(set, "Hey"), true);
+    shouldBe(testMap(map, "Hey1"), false);
+    shouldBe(testSet(set, "Hey1"), false);
+    shouldBe(testMap(map, "Hello"), true);
+    shouldBe(testSet(set, "Hello"), true);
+    shouldBe(testMap(map, createHeapBigInt(0xffffffffffffffffn)), true);
+    shouldBe(testSet(set, createHeapBigInt(0xffffffffffffffffn)), true);
+    shouldBe(testMap(map, createHeapBigInt(0x1ffffffffffffffffn)), false);
+    shouldBe(testSet(set, createHeapBigInt(0x1ffffffffffffffffn)), false);
+}
+
+for (let i = 0; i < 1e4; ++i) {
+    shouldBe(testMap(map, "Hey"), true);
+    shouldBe(testSet(set, "Hey"), true);
+    shouldBe(testMap(map, "Hey1"), false);
+    shouldBe(testSet(set, "Hey1"), false);
+    shouldBe(testMap(map, "Hello"), true);
+    shouldBe(testSet(set, "Hello"), true);
+    shouldBe(testMap(map, createHeapBigInt(0xffffffffffffffffn)), true);
+    shouldBe(testSet(set, createHeapBigInt(0xffffffffffffffffn)), true);
+    shouldBe(testMap(map, createHeapBigInt(0x1ffffffffffffffffn)), false);
+    shouldBe(testSet(set, createHeapBigInt(0x1ffffffffffffffffn)), false);
+    shouldBe(testMap(map, createHeapBigInt(1n)), true);
+    shouldBe(testSet(set, createHeapBigInt(1n)), true);
+    shouldBe(testMap(map, 1n), true);
+    shouldBe(testSet(set, 1n), true);
+    shouldBe(testMap(map, 2n), true);
+    shouldBe(testSet(set, 2n), true);
+    shouldBe(testMap(map, 3n), false);
+    shouldBe(testSet(set, 3n), false);
+}

Added: trunk/JSTests/stress/bigint32-map-set.js (0 => 267373)


--- trunk/JSTests/stress/bigint32-map-set.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint32-map-set.js	2020-09-21 22:10:24 UTC (rev 267373)
@@ -0,0 +1,41 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function testMap(map, key)
+{
+    return map.has(key);
+}
+noInline(testMap);
+
+function testSet(set, key)
+{
+    return set.has(key);
+}
+noInline(testSet);
+
+let map = new Map();
+map.set("Hey", "Hey");
+map.set(null, null);
+map.set(1n, 1n);
+map.set(2n, 2n);
+map.set(0xffffffffffffffffn, 0xffffffffffffffffn);
+map.set("Hello", "Hello");
+
+let set = new Set();
+set.add("Hey");
+set.add(null);
+set.add(1n);
+set.add(2n);
+set.add(0xffffffffffffffffn);
+set.add("Hello");
+
+for (let i = 0; i < 1e4; ++i) {
+    shouldBe(testMap(map, 1n), true);
+    shouldBe(testSet(set, 1n), true);
+    shouldBe(testMap(map, 2n), true);
+    shouldBe(testSet(set, 2n), true);
+    shouldBe(testMap(map, 3n), false);
+    shouldBe(testSet(set, 3n), false);
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (267372 => 267373)


--- trunk/Source/_javascript_Core/ChangeLog	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-09-21 22:10:24 UTC (rev 267373)
@@ -1,3 +1,45 @@
+2020-09-21  Yusuke Suzuki  <[email protected]>
+
+        [JSC] BigInt should work with Map / Set
+        https://bugs.webkit.org/show_bug.cgi?id=216667
+
+        Reviewed by Robin Morisset.
+
+        This patch makes BigInt supported in Map / Set.
+
+        1. In NormalizeMapKey, we always attempt to convert HeapBigInt to BigInt32 (if supported). So we ensure that,
+            normalized BigInt has one unique form for BigInt32 range. This allows us to use hashing for BigInt32 bit pattern directly.
+        2. In MapHash, for BigInt32, we directly has the JSValue bits. For HeapBigInt, we calculate hash via Hasher.
+        3. In GetMapBucket, we consider HeapBigInt case correctly.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixupNormalizeMapKey):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNormalizeMapKey):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileMapHash):
+        (JSC::FTL::DFG::LowerDFGToB3::compileNormalizeMapKey):
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetMapBucket):
+        * runtime/HashMapImpl.h:
+        (JSC::normalizeMapKey):
+        (JSC::jsMapHash):
+        (JSC::concurrentJSMapHash):
+        * runtime/JSBigInt.cpp:
+        (JSC::JSBigInt::concurrentHash):
+        * runtime/JSBigInt.h:
+        (JSC::tryConvertToBigInt32):
+
 2020-09-21  Mark Lam  <[email protected]>
 
         Move some LLInt globals into JSC::Config.

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2020-09-21 22:10:24 UTC (rev 267373)
@@ -1381,7 +1381,7 @@
             break;
         }
 
-        SpeculatedType typeMaybeNormalized = (SpecFullNumber & ~SpecInt32Only);
+        SpeculatedType typeMaybeNormalized = (SpecFullNumber & ~SpecInt32Only) | SpecHeapBigInt;
         if (!(forNode(node->child1()).m_type & typeMaybeNormalized)) {
             m_state.setShouldTryConstantFolding(true);
             forNode(node) = forNode(node->child1());

Modified: trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -994,7 +994,7 @@
             }
 
             case NormalizeMapKey: {
-                SpeculatedType typeMaybeNormalized = (SpecFullNumber & ~SpecInt32Only);
+                SpeculatedType typeMaybeNormalized = (SpecFullNumber & ~SpecInt32Only) | SpecHeapBigInt;
                 if (m_state.forNode(node->child1()).m_type & typeMaybeNormalized)
                     break;
 

Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -164,7 +164,7 @@
     case SuperSamplerBegin:
     case SuperSamplerEnd:
     case CPUIntrinsic:
-    case NormalizeMapKey:
+    case NormalizeMapKey: // HeapBigInt => BigInt32 conversion does not involve GC.
     case GetMapBucketHead:
     case GetMapBucketNext:
     case LoadKeyFromMapBucket:
@@ -517,6 +517,10 @@
         case Int32Use:
         case SymbolUse:
         case ObjectUse:
+#if USE(BIGINT32)
+        case BigInt32Use:
+#endif
+        case HeapBigIntUse:
             return false;
         default:
             // We might resolve a rope.

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -2377,6 +2377,10 @@
                 fixEdge<BooleanUse>(node->child2());
             else if (node->child2()->shouldSpeculateInt32())
                 fixEdge<Int32Use>(node->child2());
+#if USE(BIGINT32)
+            else if (node->child2()->shouldSpeculateBigInt32())
+                fixEdge<BigInt32Use>(node->child2());
+#endif
             else if (node->child2()->shouldSpeculateSymbol())
                 fixEdge<SymbolUse>(node->child2());
             else if (node->child2()->shouldSpeculateObject())
@@ -2383,6 +2387,8 @@
                 fixEdge<ObjectUse>(node->child2());
             else if (node->child2()->shouldSpeculateString())
                 fixEdge<StringUse>(node->child2());
+            else if (node->child2()->shouldSpeculateHeapBigInt())
+                fixEdge<HeapBigIntUse>(node->child2());
             else if (node->child2()->shouldSpeculateCell())
                 fixEdge<CellUse>(node->child2());
             else
@@ -2436,6 +2442,18 @@
                 break;
             }
 
+#if USE(BIGINT32)
+            if (node->child1()->shouldSpeculateBigInt32()) {
+                fixEdge<BigInt32Use>(node->child1());
+                break;
+            }
+#endif
+
+            if (node->child1()->shouldSpeculateHeapBigInt()) {
+                fixEdge<HeapBigIntUse>(node->child1());
+                break;
+            }
+
             if (node->child1()->shouldSpeculateCell()) {
                 fixEdge<CellUse>(node->child1());
                 break;
@@ -3996,11 +4014,13 @@
             return;
         }
 
-        if (node->child1()->shouldSpeculateCell()) {
-            fixEdge<CellUse>(node->child1());
+#if USE(BIGINT32)
+        if (node->child1()->shouldSpeculateBigInt32()) {
+            fixEdge<BigInt32Use>(node->child1());
             node->convertToIdentity();
             return;
         }
+#endif
 
         fixEdge<UntypedUse>(node->child1());
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -3212,6 +3212,14 @@
     return putDynamicVar(globalObject, vm, scope, value, impl, getPutInfoBits, isStrictMode);
 }
 
+EncodedJSValue JIT_OPERATION operationNormalizeMapKey(VM* vmPointer, EncodedJSValue input)
+{
+    VM& vm = *vmPointer;
+    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
+    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
+    return JSValue::encode(normalizeMapKey(JSValue::decode(input)));
+}
+
 UCPUStrictInt32 JIT_OPERATION operationMapHash(JSGlobalObject* globalObject, EncodedJSValue input)
 {
     VM& vm = globalObject->vm();

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2020-09-21 22:10:24 UTC (rev 267373)
@@ -243,6 +243,7 @@
 char* JIT_OPERATION operationInt52ToStringWithValidRadix(JSGlobalObject*, int64_t, int32_t);
 char* JIT_OPERATION operationDoubleToStringWithValidRadix(JSGlobalObject*, double, int32_t);
 
+EncodedJSValue JIT_OPERATION operationNormalizeMapKey(VM*, EncodedJSValue input) WTF_INTERNAL;
 UCPUStrictInt32 JIT_OPERATION operationMapHash(JSGlobalObject*, EncodedJSValue input);
 JSCell* JIT_OPERATION operationJSMapFindBucket(JSGlobalObject*, JSCell*, EncodedJSValue, int32_t);
 JSCell* JIT_OPERATION operationJSSetFindBucket(JSGlobalObject*, JSCell*, EncodedJSValue, int32_t);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -12517,6 +12517,11 @@
     CCallHelpers::JumpList passThroughCases;
     CCallHelpers::JumpList doneCases;
 
+    auto isNotCell = m_jit.branchIfNotCell(keyRegs);
+    passThroughCases.append(m_jit.branchIfNotHeapBigInt(keyRegs.payloadGPR()));
+    auto slowPath = m_jit.jump();
+    isNotCell.link(&m_jit);
+
     passThroughCases.append(m_jit.branchIfNotNumber(keyRegs, scratchGPR));
     passThroughCases.append(m_jit.branchIfInt32(keyRegs));
 
@@ -12539,6 +12544,7 @@
 
     passThroughCases.link(&m_jit);
     m_jit.moveValueRegs(keyRegs, resultRegs);
+    addSlowPathGenerator(slowPathCall(slowPath, this, operationNormalizeMapKey, resultRegs, &vm(), keyRegs));
 
     doneCases.link(&m_jit);
     jsValueResult(resultRegs, node);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -4431,6 +4431,9 @@
 
     case MapHash: {
         switch (node->child1().useKind()) {
+#if USE(BIGINT32)
+        case BigInt32Use:
+#endif
         case BooleanUse:
         case Int32Use:
         case SymbolUse:
@@ -4450,6 +4453,20 @@
             strictInt32Result(resultGPR, node);
             break;
         }
+        case HeapBigIntUse: {
+            SpeculateCellOperand input(this, node->child1());
+            GPRReg inputGPR = input.gpr();
+
+            speculateHeapBigInt(node->child1(), inputGPR);
+
+            flushRegisters();
+            GPRFlushedCallResult result(this);
+            GPRReg resultGPR = result.gpr();
+            callOperation(operationMapHash, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), inputGPR);
+            m_jit.exceptionCheck();
+            strictInt32Result(resultGPR, node);
+            break;
+        }
         case CellUse:
         case StringUse: {
             SpeculateCellOperand input(this, node->child1());
@@ -4472,8 +4489,10 @@
                 speculateString(node->child1(), inputGPR);
             else {
                 auto isString = m_jit.branchIfString(inputGPR);
+                auto isHeapBigInt = m_jit.branchIfHeapBigInt(inputGPR);
                 m_jit.move(inputGPR, resultGPR);
                 m_jit.wangsInt64Hash(resultGPR, tempGPR);
+                addSlowPathGenerator(slowPathCall(isHeapBigInt, this, operationMapHash, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), inputGPR));
                 done.append(m_jit.jump());
                 isString.link(&m_jit);
             }
@@ -4515,6 +4534,7 @@
         MacroAssembler::JumpList done;
         straightHash.append(m_jit.branchIfNotCell(inputGPR));
         MacroAssembler::JumpList slowPath;
+        auto isHeapBigInt = m_jit.branchIfHeapBigInt(inputGPR);
         straightHash.append(m_jit.branchIfNotString(inputGPR));
         m_jit.loadPtr(MacroAssembler::Address(inputGPR, JSString::offsetOfValue()), resultGPR);
         slowPath.append(m_jit.branchIfRopeStringImpl(resultGPR));
@@ -4526,6 +4546,7 @@
         straightHash.link(&m_jit);
         m_jit.move(inputGPR, resultGPR);
         m_jit.wangsInt64Hash(resultGPR, tempGPR);
+        addSlowPathGenerator(slowPathCall(isHeapBigInt, this, operationMapHash, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), inputGPR));
         done.append(m_jit.jump());
 
         slowPath.link(&m_jit);
@@ -4596,6 +4617,9 @@
         // Perform Object.is()
         switch (node->child2().useKind()) {
         case BooleanUse:
+#if USE(BIGINT32)
+        case BigInt32Use:
+#endif
         case Int32Use:
         case SymbolUse:
         case ObjectUse: {
@@ -4604,11 +4628,26 @@
             break;
         }
         case CellUse: {
+            // if (bucket.isString()) {
+            //     if (key.isString())
+            //         => slow path
+            // } else if (bucket.isHeapBigInt()) {
+            //     if (key.isHeapBigInt())
+            //         => slow path
+            // }
             done.append(m_jit.branch64(MacroAssembler::Equal, bucketGPR, keyGPR));
             loopAround.append(m_jit.branchIfNotCell(JSValueRegs(bucketGPR)));
-            loopAround.append(m_jit.branchIfNotString(bucketGPR));
+
+            auto isBucketString = m_jit.branchIfString(bucketGPR);
+            loopAround.append(m_jit.branchIfNotHeapBigInt(bucketGPR));
+
+            // bucket is HeapBigInt.
+            slowPathCases.append(m_jit.branchIfHeapBigInt(keyGPR));
+            loopAround.append(m_jit.jump());
+
+            // bucket is String.
+            isBucketString.link(&m_jit);
             loopAround.append(m_jit.branchIfNotString(keyGPR));
-            // They're both strings.
             slowPathCases.append(m_jit.jump());
             break;
         }
@@ -4619,6 +4658,13 @@
             slowPathCases.append(m_jit.jump());
             break;
         }
+        case HeapBigIntUse: {
+            done.append(m_jit.branch64(MacroAssembler::Equal, bucketGPR, keyGPR)); // They're definitely the same value, we found the bucket we were looking for!
+            loopAround.append(m_jit.branchIfNotCell(JSValueRegs(bucketGPR)));
+            loopAround.append(m_jit.branchIfNotHeapBigInt(bucketGPR));
+            slowPathCases.append(m_jit.jump());
+            break;
+        }
         case UntypedUse: { 
             done.append(m_jit.branch64(MacroAssembler::Equal, bucketGPR, keyGPR)); // They're definitely the same value, we found the bucket we were looking for!
             // The input key and bucket's key are already normalized. So if 64-bit compare fails and one is not a cell, they're definitely not equal.
@@ -4626,11 +4672,16 @@
             // first is a cell here.
             loopAround.append(m_jit.branchIfNotCell(JSValueRegs(keyGPR)));
             // Both are cells here.
-            loopAround.append(m_jit.branchIfNotString(bucketGPR));
-            // The first is a string here.
-            slowPathCases.append(m_jit.branchIfString(keyGPR));
-            // The first is a string, but the second is not, we continue to loop around.
+            auto isBucketString = m_jit.branchIfString(bucketGPR);
+            // bucket is not String.
+            loopAround.append(m_jit.branchIfNotHeapBigInt(bucketGPR));
+            // bucket is HeapBigInt.
+            slowPathCases.append(m_jit.branchIfHeapBigInt(keyGPR));
             loopAround.append(m_jit.jump());
+            // bucket is String.
+            isBucketString.link(&m_jit);
+            loopAround.append(m_jit.branchIfNotString(keyGPR));
+            slowPathCases.append(m_jit.jump());
             break;
         }
         default:

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -11244,6 +11244,9 @@
     {
         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
         switch (m_node->child1().useKind()) {
+#if USE(BIGINT32)
+        case BigInt32Use:
+#endif
         case BooleanUse:
         case Int32Use:
         case SymbolUse:
@@ -11254,9 +11257,17 @@
             return;
         }
 
+        case HeapBigIntUse: {
+            LValue key = lowHeapBigInt(m_node->child1());
+            setInt32(m_out.castToInt32(vmCall(Int64, operationMapHash, weakPointer(globalObject), key)));
+            return;
+        }
+
         case CellUse: {
             LBasicBlock isString = m_out.newBlock();
             LBasicBlock notString = m_out.newBlock();
+            LBasicBlock isHeapBigIntCase = m_out.newBlock();
+            LBasicBlock notStringHeapBigIntCase = m_out.newBlock();
             LBasicBlock continuation = m_out.newBlock();
 
             LValue value = lowCell(m_node->child1());
@@ -11268,12 +11279,19 @@
             ValueFromBlock stringResult = m_out.anchor(mapHashString(value, m_node->child1()));
             m_out.jump(continuation);
 
-            m_out.appendTo(notString, continuation);
+            m_out.appendTo(notString, isHeapBigIntCase);
+            m_out.branch(isHeapBigInt(value, (provenType(m_node->child1()) & ~SpecString)), unsure(isHeapBigIntCase), unsure(notStringHeapBigIntCase));
+
+            m_out.appendTo(isHeapBigIntCase, notStringHeapBigIntCase);
+            ValueFromBlock heapBigIntResult = m_out.anchor(m_out.castToInt32(vmCall(Int64, operationMapHash, weakPointer(globalObject), value)));
+            m_out.jump(continuation);
+
+            m_out.appendTo(notStringHeapBigIntCase, continuation);
             ValueFromBlock notStringResult = m_out.anchor(wangsInt64Hash(value));
             m_out.jump(continuation);
 
             m_out.appendTo(continuation, lastNext);
-            setInt32(m_out.phi(Int32, stringResult, notStringResult));
+            setInt32(m_out.phi(Int32, stringResult, heapBigIntResult, notStringResult));
             return;
         }
 
@@ -11294,6 +11312,7 @@
         LBasicBlock slowCase = m_out.newBlock();
         LBasicBlock straightHash = m_out.newBlock();
         LBasicBlock isStringCase = m_out.newBlock();
+        LBasicBlock notStringCase = m_out.newBlock();
         LBasicBlock nonEmptyStringCase = m_out.newBlock();
         LBasicBlock continuation = m_out.newBlock();
 
@@ -11300,11 +11319,14 @@
         m_out.branch(
             isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(straightHash));
 
-        LBasicBlock lastNext = m_out.appendTo(isCellCase, isStringCase);
+        LBasicBlock lastNext = m_out.appendTo(isCellCase, notStringCase);
         LValue isString = m_out.equal(m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoType), m_out.constInt32(StringType));
         m_out.branch(
-            isString, unsure(isStringCase), unsure(straightHash));
+            isString, unsure(isStringCase), unsure(notStringCase));
 
+        m_out.appendTo(notStringCase, isStringCase);
+        m_out.branch(isHeapBigInt(value, (provenType(m_node->child1()) & ~SpecString)), unsure(slowCase), unsure(straightHash));
+
         m_out.appendTo(isStringCase, nonEmptyStringCase);
         m_out.branch(isRopeString(value, m_node->child1()), rarely(slowCase), usually(nonEmptyStringCase));
 
@@ -11331,6 +11353,9 @@
     {
         ASSERT(m_node->child1().useKind() == UntypedUse);
 
+        LBasicBlock isCellCase = m_out.newBlock();
+        LBasicBlock notCellCase = m_out.newBlock();
+        LBasicBlock isHeapBigIntCase = m_out.newBlock();
         LBasicBlock isNumberCase = m_out.newBlock();
         LBasicBlock notInt32NumberCase = m_out.newBlock();
         LBasicBlock notNaNCase = m_out.newBlock();
@@ -11337,10 +11362,20 @@
         LBasicBlock convertibleCase = m_out.newBlock();
         LBasicBlock continuation = m_out.newBlock();
 
-        LBasicBlock lastNext = m_out.insertNewBlocksBefore(isNumberCase);
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(isCellCase);
 
         LValue key = lowJSValue(m_node->child1());
         ValueFromBlock fastResult = m_out.anchor(key);
+        m_out.branch(isNotCell(key, provenType(m_node->child1())), unsure(notCellCase), unsure(isCellCase));
+
+        m_out.appendTo(isCellCase, isHeapBigIntCase);
+        m_out.branch(isNotHeapBigInt(key, (provenType(m_node->child1()) & SpecCellCheck)), unsure(continuation), unsure(isHeapBigIntCase));
+
+        m_out.appendTo(isHeapBigIntCase, notCellCase);
+        ValueFromBlock bigIntResult = m_out.anchor(vmCall(Int64, operationNormalizeMapKey, m_vmValue, key));
+        m_out.jump(continuation);
+
+        m_out.appendTo(notCellCase, isNumberCase);
         m_out.branch(isNotNumber(key), unsure(continuation), unsure(isNumberCase));
 
         m_out.appendTo(isNumberCase, notInt32NumberCase);
@@ -11362,7 +11397,7 @@
         m_out.jump(continuation);
 
         m_out.appendTo(continuation, lastNext);
-        setJSValue(m_out.phi(Int64, fastResult, normalizedNaNResult, doubleResult, boxedIntResult));
+        setJSValue(m_out.phi(Int64, fastResult, bigIntResult, normalizedNaNResult, doubleResult, boxedIntResult));
     }
 
     void compileGetMapBucket()
@@ -11418,6 +11453,9 @@
         // Perform Object.is()
         switch (m_node->child2().useKind()) {
         case BooleanUse:
+#if USE(BIGINT32)
+        case BigInt32Use:
+#endif
         case Int32Use:
         case SymbolUse:
         case ObjectUse: {
@@ -11441,10 +11479,28 @@
                 unsure(slowPath), unsure(loopAround));
             break;
         }
+        case HeapBigIntUse: {
+            LBasicBlock notBitEqual = m_out.newBlock();
+            LBasicBlock bucketKeyIsCell = m_out.newBlock();
+
+            m_out.branch(m_out.equal(key, bucketKey),
+                unsure(continuation), unsure(notBitEqual));
+
+            m_out.appendTo(notBitEqual, bucketKeyIsCell);
+            m_out.branch(isCell(bucketKey),
+                unsure(bucketKeyIsCell), unsure(loopAround));
+
+            m_out.appendTo(bucketKeyIsCell, loopAround);
+            m_out.branch(isHeapBigInt(bucketKey),
+                unsure(slowPath), unsure(loopAround));
+            break;
+        }
         case CellUse: {
             LBasicBlock notBitEqual = m_out.newBlock();
             LBasicBlock bucketKeyIsCell = m_out.newBlock();
             LBasicBlock bucketKeyIsString = m_out.newBlock();
+            LBasicBlock bucketKeyIsNotString = m_out.newBlock();
+            LBasicBlock bucketKeyIsHeapBigInt = m_out.newBlock();
 
             m_out.branch(m_out.equal(key, bucketKey),
                 unsure(continuation), unsure(notBitEqual));
@@ -11455,11 +11511,19 @@
 
             m_out.appendTo(bucketKeyIsCell, bucketKeyIsString);
             m_out.branch(isString(bucketKey),
-                unsure(bucketKeyIsString), unsure(loopAround));
+                unsure(bucketKeyIsString), unsure(bucketKeyIsNotString));
 
-            m_out.appendTo(bucketKeyIsString, loopAround);
-            m_out.branch(isString(key),
+            m_out.appendTo(bucketKeyIsString, bucketKeyIsNotString);
+            m_out.branch(isString(key, provenType(m_node->child2())),
                 unsure(slowPath), unsure(loopAround));
+
+            m_out.appendTo(bucketKeyIsNotString, bucketKeyIsHeapBigInt);
+            m_out.branch(isHeapBigInt(bucketKey),
+                unsure(bucketKeyIsHeapBigInt), unsure(loopAround));
+
+            m_out.appendTo(bucketKeyIsHeapBigInt, loopAround);
+            m_out.branch(isHeapBigInt(key, provenType(m_node->child2())),
+                unsure(slowPath), unsure(loopAround));
             break;
         }
         case UntypedUse: {
@@ -11467,6 +11531,8 @@
             LBasicBlock bucketKeyIsCell = m_out.newBlock();
             LBasicBlock bothAreCells = m_out.newBlock();
             LBasicBlock bucketKeyIsString = m_out.newBlock();
+            LBasicBlock bucketKeyIsNotString = m_out.newBlock();
+            LBasicBlock bucketKeyIsHeapBigInt = m_out.newBlock();
 
             m_out.branch(m_out.equal(key, bucketKey),
                 unsure(continuation), unsure(notBitEqual));
@@ -11481,11 +11547,19 @@
 
             m_out.appendTo(bothAreCells, bucketKeyIsString);
             m_out.branch(isString(bucketKey),
-                unsure(bucketKeyIsString), unsure(loopAround));
+                unsure(bucketKeyIsString), unsure(bucketKeyIsNotString));
 
-            m_out.appendTo(bucketKeyIsString, loopAround);
-            m_out.branch(isString(key),
+            m_out.appendTo(bucketKeyIsString, bucketKeyIsNotString);
+            m_out.branch(isString(key, provenType(m_node->child2())),
                 unsure(slowPath), unsure(loopAround));
+
+            m_out.appendTo(bucketKeyIsNotString, bucketKeyIsHeapBigInt);
+            m_out.branch(isHeapBigInt(bucketKey),
+                unsure(bucketKeyIsHeapBigInt), unsure(loopAround));
+
+            m_out.appendTo(bucketKeyIsHeapBigInt, loopAround);
+            m_out.branch(isHeapBigInt(key, provenType(m_node->child2())),
+                unsure(slowPath), unsure(loopAround));
             break;
         }
         default:

Modified: trunk/Source/_javascript_Core/runtime/HashMapImpl.h (267372 => 267373)


--- trunk/Source/_javascript_Core/runtime/HashMapImpl.h	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/runtime/HashMapImpl.h	2020-09-21 22:10:24 UTC (rev 267373)
@@ -243,8 +243,11 @@
 // Keep in sync with the implementation of DFG and FTL normalization.
 ALWAYS_INLINE JSValue normalizeMapKey(JSValue key)
 {
-    if (!key.isNumber())
+    if (!key.isNumber()) {
+        if (key.isHeapBigInt())
+            return tryConvertToBigInt32(key.asHeapBigInt());
         return key;
+    }
 
     if (key.isInt32())
         return key;
@@ -287,6 +290,9 @@
         return wtfString.impl()->hash();
     }
 
+    if (value.isHeapBigInt())
+        return value.asHeapBigInt()->hash();
+
     return wangsInt64Hash(JSValue::encode(value));
 }
 
@@ -303,6 +309,9 @@
         return impl->concurrentHash();
     }
 
+    if (key.isHeapBigInt())
+        return key.asHeapBigInt()->concurrentHash();
+
     uint64_t rawValue = JSValue::encode(key);
     return wangsInt64Hash(rawValue);
 }

Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.cpp (267372 => 267373)


--- trunk/Source/_javascript_Core/runtime/JSBigInt.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -54,6 +54,7 @@
 #include "ParseInt.h"
 #include "StructureInlines.h"
 #include <algorithm>
+#include <wtf/Hasher.h>
 #include <wtf/MathExtras.h>
 
 namespace JSC {
@@ -430,31 +431,6 @@
     : payload(value)
 { }
 
-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);
-        JSBigInt::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;
-}
-
 static ALWAYS_INLINE JSValue tryConvertToBigInt32(JSBigInt::ImplResult implResult)
 {
     if (!implResult.payload)
@@ -3073,4 +3049,27 @@
 }
 #endif
 
+static ALWAYS_INLINE unsigned computeHash(JSBigInt::Digit* digits, unsigned length, bool sign)
+{
+    Hasher hasher;
+    WTF::add(hasher, sign);
+    for (unsigned index = 0; index < length; ++index)
+        WTF::add(hasher, digits[index]);
+    return hasher.hash();
+}
+
+Optional<unsigned> JSBigInt::concurrentHash()
+{
+    // FIXME: Implement JSBigInt::concurrentHash by inserting right store barriers.
+    // https://bugs.webkit.org/show_bug.cgi?id=216801
+    return WTF::nullopt;
+}
+
+unsigned JSBigInt::hashSlow()
+{
+    ASSERT(!m_hash);
+    m_hash = computeHash(dataStorage(), length(), m_sign);
+    return m_hash;
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.h (267372 => 267373)


--- trunk/Source/_javascript_Core/runtime/JSBigInt.h	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.h	2020-09-21 22:10:24 UTC (rev 267373)
@@ -427,11 +427,21 @@
     JS_EXPORT_PRIVATE JSBigInt* rightTrim(JSGlobalObject*);
     JS_EXPORT_PRIVATE JSBigInt* tryRightTrim(VM&);
 
+    JS_EXPORT_PRIVATE Optional<unsigned> concurrentHash();
+    unsigned hash()
+    {
+        if (m_hash)
+            return m_hash;
+        return hashSlow();
+    }
+
 private:
     JSBigInt(VM&, Structure*, Digit*, unsigned length);
 
     JSBigInt* rightTrim(JSGlobalObject*, VM&);
 
+    JS_EXPORT_PRIVATE unsigned hashSlow();
+
     static JSBigInt* createFromImpl(JSGlobalObject*, uint64_t value, bool sign);
 
     static constexpr unsigned bitsPerByte = 8;
@@ -572,8 +582,10 @@
     }
 
     inline Digit* dataStorage() { return m_data.get(m_length); }
+    inline Digit* dataStorageUnsafe() { return m_data.getUnsafe(); }
 
     const unsigned m_length;
+    unsigned m_hash { 0 };
     bool m_sign { false };
     CagedBarrierPtr<Gigacage::Primitive, Digit, tagCagedPtr> m_data;
 };
@@ -608,4 +620,29 @@
     }
 }
 
+ALWAYS_INLINE JSValue tryConvertToBigInt32(JSBigInt* bigInt)
+{
+#if USE(BIGINT32)
+    if (UNLIKELY(!bigInt))
+        return JSValue();
+
+    if (bigInt->length() <= 1) {
+        if (!bigInt->length())
+            return jsBigInt32(0);
+        JSBigInt::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;
+}
+
 } // namespace JSC

Modified: trunk/Source/WTF/ChangeLog (267372 => 267373)


--- trunk/Source/WTF/ChangeLog	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/WTF/ChangeLog	2020-09-21 22:10:24 UTC (rev 267373)
@@ -1,3 +1,14 @@
+2020-09-21  Yusuke Suzuki  <[email protected]>
+
+        [JSC] BigInt should work with Map / Set
+        https://bugs.webkit.org/show_bug.cgi?id=216667
+
+        Reviewed by Robin Morisset.
+
+        * wtf/Hasher.h:
+        (WTF::Hasher::hash const):
+        (WTF::add):
+
 2020-09-21  Mark Lam  <[email protected]>
 
         Move some LLInt globals into JSC::Config.

Modified: trunk/Source/WTF/wtf/Hasher.h (267372 => 267373)


--- trunk/Source/WTF/wtf/Hasher.h	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/WTF/wtf/Hasher.h	2020-09-21 22:10:24 UTC (rev 267373)
@@ -47,6 +47,7 @@
 
 template<typename... Types> uint32_t computeHash(const Types&...);
 template<typename T, typename... OtherTypes> uint32_t computeHash(std::initializer_list<T>, std::initializer_list<OtherTypes>...);
+template<typename UnsignedInteger> std::enable_if_t<std::is_unsigned<UnsignedInteger>::value && sizeof(UnsignedInteger) <= sizeof(uint32_t), void> add(Hasher&, UnsignedInteger);
 
 class Hasher {
     WTF_MAKE_FAST_ALLOCATED;
@@ -75,6 +76,11 @@
         hasher.m_underlyingHasher.addCharactersAssumingAligned(sizedInteger, sizedInteger >> 16);
     }
 
+    unsigned hash() const
+    {
+        return m_underlyingHasher.hash();
+    }
+
 private:
     StringHasher m_underlyingHasher;
 };
@@ -91,6 +97,11 @@
     add(hasher, static_cast<std::make_unsigned_t<SignedArithmetic>>(number));
 }
 
+inline void add(Hasher& hasher, bool boolean)
+{
+    add(hasher, static_cast<uint8_t>(boolean));
+}
+
 inline void add(Hasher& hasher, double number)
 {
     add(hasher, bitwise_cast<uint64_t>(number));

Modified: trunk/Source/WebCore/ChangeLog (267372 => 267373)


--- trunk/Source/WebCore/ChangeLog	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/WebCore/ChangeLog	2020-09-21 22:10:24 UTC (rev 267373)
@@ -1,3 +1,16 @@
+2020-09-21  Yusuke Suzuki  <[email protected]>
+
+        [JSC] BigInt should work with Map / Set
+        https://bugs.webkit.org/show_bug.cgi?id=216667
+        <rdar://problem/69107221>
+
+        Reviewed by Robin Morisset.
+
+        Strongly ensure that BigInt32 is always selected since Map / Set could use it as a key.
+
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneDeserializer::readBigInt):
+
 2020-09-21  Peng Liu  <[email protected]>
 
         Tapping to zoom in and out causes video to become very small on some iPhone models

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (267372 => 267373)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-09-21 22:03:44 UTC (rev 267372)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-09-21 22:10:24 UTC (rev 267373)
@@ -3054,7 +3054,7 @@
                 return JSValue();
             }
             m_gcBuffer.appendWithCrashOnOverflow(bigInt);
-            return bigInt;
+            return tryConvertToBigInt32(bigInt);
         }
 #endif
         JSBigInt* bigInt = nullptr;
@@ -3094,7 +3094,7 @@
             return JSValue();
         }
         m_gcBuffer.appendWithCrashOnOverflow(bigInt);
-        return bigInt;
+        return tryConvertToBigInt32(bigInt);
     }
 
     JSValue readTerminal()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to