tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 76504589695a5c6d65d581795076a0cd4977e34c
parent 25de8c18648c6d6536b9b9379337560c78dffd30
Author: Iain Ireland <iireland@mozilla.com>
Date:   Thu, 27 Nov 2025 21:39:55 +0000

Bug 2000328: Add MacroAssembler implementations of hash1/hash2/applyDoubleHash r=jandem

Differential Revision: https://phabricator.services.mozilla.com/D273670

Diffstat:
Mjs/src/gc/WeakMap.h | 4++++
Mjs/src/jit/MacroAssembler.cpp | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Mjs/src/jit/MacroAssembler.h | 7+++++++
Mmfbt/HashTable.h | 21+++++++++++++++++++++
4 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/js/src/gc/WeakMap.h b/js/src/gc/WeakMap.h @@ -432,6 +432,10 @@ class WeakMap : public WeakMapBase { size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + static size_t offsetOfHashShift() { + return offsetof(WeakMap, map_) + UnbarrieredMap::offsetOfHashShift(); + } + protected: inline void assertMapIsSameZoneWithValue(const BarrieredValue& v); diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp @@ -10510,6 +10510,57 @@ void MacroAssembler::prepareHashMFBT(Register hashCode, bool alreadyScrambled) { and32(Imm32(~CollisionBit), hashCode); } +template <typename Table> +void MacroAssembler::computeHash1MFBT(Register hashTable, Register hashCode, + Register hash1, Register scratch) { + // Inline implementation of |mozilla::HashTable::hash1| + // return aHash0 >> hashShift(); + move32(hashCode, hash1); + load8ZeroExtend(Address(hashTable, Table::offsetOfHashShift()), scratch); + flexibleRshift32(scratch, hash1); +} + +template void MacroAssembler::computeHash1MFBT<WeakMapObject::Map>( + Register hashTable, Register hashCode, Register hash1, Register scratch); + +template <typename Table> +void MacroAssembler::computeHash2MFBT(Register hashTable, Register hashCode, + Register hash2, Register sizeMask, + Register scratch) { + // Inline implementation of |mozilla::detail::HashTable::hash2| + + // Load hashShift into sizeMask + load8ZeroExtend(Address(hashTable, Table::offsetOfHashShift()), sizeMask); + + // uint32_t sizeLog2 = kHashNumberBits - hashShift(); + move32(Imm32(kHashNumberBits), scratch); + sub32(sizeMask, scratch); + + // DoubleHash dh = {((aCurKeyHash << sizeLog2) >> hashShift()) | 1, + move32(hashCode, hash2); + flexibleLshift32(scratch, hash2); + flexibleRshift32(sizeMask, hash2); + or32(Imm32(1), hash2); + + // sizeMask = (HashNumber(1) << sizeLog2) - 1}; + move32(Imm32(1), sizeMask); + flexibleLshift32(scratch, sizeMask); + sub32(Imm32(1), sizeMask); +} + +template void MacroAssembler::computeHash2MFBT<WeakMapObject::Map>( + Register hashTable, Register hashCode, Register hash2, Register sizeMask, + Register scratch); + +void MacroAssembler::applyDoubleHashMFBT(Register hash1, Register hash2, + Register sizeMask) { + // Inline implementation of |mozilla::detail::HashTable::applyDoubleHash| + + // return WrappingSubtract(aHash1, aDoubleHash.mHash2) & aDoubleHash.mSizeMask + sub32(hash2, hash1); + and32(sizeMask, hash1); +} + // Can't push large frames blindly on windows, so we must touch frame memory // incrementally, with no more than 4096 - 1 bytes between touches. // diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h @@ -5447,6 +5447,13 @@ class MacroAssembler : public MacroAssemblerSpecific { // Helper functions used to implement mozilla::HashTable lookup inline // in jitcode. void prepareHashMFBT(Register hashCode, bool alreadyScrambled); + template <typename Table> + void computeHash1MFBT(Register hashTable, Register hashCode, Register hash1, + Register scratch); + template <typename Table> + void computeHash2MFBT(Register hashTable, Register hashCode, Register hash2, + Register sizeMask, Register scratch); + void applyDoubleHashMFBT(Register hash1, Register hash2, Register sizeMask); private: enum class IsBigInt { No, Yes, Maybe }; diff --git a/mfbt/HashTable.h b/mfbt/HashTable.h @@ -81,6 +81,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Casting.h" +#include "mozilla/EndianUtils.h" #include "mozilla/HashFunctions.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/Maybe.h" @@ -424,6 +425,10 @@ class MOZ_STANDALONE_DEBUG HashMap { using Range = typename Impl::Range; using Enum = typename Impl::Enum; Range all() const { return mImpl.all(); } + + static size_t offsetOfHashShift() { + return offsetof(HashMap, mImpl) + Impl::offsetOfHashShift(); + } }; //--------------------------------------------------------------------------- @@ -2331,6 +2336,22 @@ class MOZ_STANDALONE_DEBUG HashTable : private AllocPolicy { rekeyWithoutRehash(aPtr, aLookup, aKey); infallibleRehashIfOverloaded(); } + + static size_t offsetOfHashShift() { + static_assert(sHashShiftBits == 8, + "callers assume hash shift is stored in a byte"); + // The hash shift is stored in the least significant bits of + // mGenAndHashShift. On little-endian platforms, this is the + // same offset as mGenAndHashShift itself. On big-endian platforms, + // we have to add an additional offset to point to the last byte. + // (Or we would if we had JIT support for any big-endian platforms.) +#if MOZ_BIG_ENDIAN() + return offsetof(HashTable, mGenAndHashShift) + sizeof(mGenAndHashShift) - + sizeof(uint8_t); +#else + return offsetof(HashTable, mGenAndHashShift); +#endif + } }; } // namespace detail