Ignore:
Timestamp:
Sep 21, 2020, 3:10:24 PM (5 years ago)
Author:
[email protected]
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/JavaScriptCore:

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.

  1. In MapHash, for BigInt32, we directly has the JSValue bits. For HeapBigInt, we calculate hash via Hasher.
  2. 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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp

    r266250 r267373  
    5555#include "StructureInlines.h"
    5656#include <algorithm>
     57#include <wtf/Hasher.h>
    5758#include <wtf/MathExtras.h>
    5859
     
    430431    : payload(value)
    431432{ }
    432 
    433 static ALWAYS_INLINE JSValue tryConvertToBigInt32(JSBigInt* bigInt)
    434 {
    435 #if USE(BIGINT32)
    436     if (UNLIKELY(!bigInt))
    437         return JSValue();
    438 
    439     if (bigInt->length() <= 1) {
    440         if (!bigInt->length())
    441             return jsBigInt32(0);
    442         JSBigInt::Digit digit = bigInt->digit(0);
    443         if (bigInt->sign()) {
    444             static constexpr uint64_t maxValue = -static_cast<int64_t>(std::numeric_limits<int32_t>::min());
    445             if (digit <= maxValue)
    446                 return jsBigInt32(static_cast<int32_t>(-static_cast<int64_t>(digit)));
    447         } else {
    448             static constexpr uint64_t maxValue = static_cast<uint64_t>(std::numeric_limits<int32_t>::max());
    449             if (digit <= maxValue)
    450                 return jsBigInt32(static_cast<int32_t>(digit));
    451         }
    452     }
    453 #endif
    454 
    455     return bigInt;
    456 }
    457433
    458434static ALWAYS_INLINE JSValue tryConvertToBigInt32(JSBigInt::ImplResult implResult)
     
    30743050#endif
    30753051
     3052static ALWAYS_INLINE unsigned computeHash(JSBigInt::Digit* digits, unsigned length, bool sign)
     3053{
     3054    Hasher hasher;
     3055    WTF::add(hasher, sign);
     3056    for (unsigned index = 0; index < length; ++index)
     3057        WTF::add(hasher, digits[index]);
     3058    return hasher.hash();
     3059}
     3060
     3061Optional<unsigned> JSBigInt::concurrentHash()
     3062{
     3063    // FIXME: Implement JSBigInt::concurrentHash by inserting right store barriers.
     3064    // https://bugs.webkit.org/show_bug.cgi?id=216801
     3065    return WTF::nullopt;
     3066}
     3067
     3068unsigned JSBigInt::hashSlow()
     3069{
     3070    ASSERT(!m_hash);
     3071    m_hash = computeHash(dataStorage(), length(), m_sign);
     3072    return m_hash;
     3073}
     3074
    30763075} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.