diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
commit | def92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch) | |
tree | 2ef34b9ad8bb9a9220e05d60352558b15f513894 /js/src/ds | |
parent | Adding debian version 125.0.3-1. (diff) | |
download | firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.tar.xz firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/ds')
-rw-r--r-- | js/src/ds/BitArray.h | 6 | ||||
-rw-r--r-- | js/src/ds/Bitmap.h | 22 | ||||
-rw-r--r-- | js/src/ds/OrderedHashTable.h | 71 |
3 files changed, 80 insertions, 19 deletions
diff --git a/js/src/ds/BitArray.h b/js/src/ds/BitArray.h index bdd78873fd..f8a6aad455 100644 --- a/js/src/ds/BitArray.h +++ b/js/src/ds/BitArray.h @@ -99,6 +99,12 @@ class BitArray { return map[elementIndex]; } + // Update a word at a time. + void setWord(size_t elementIndex, WordT value) { + MOZ_ASSERT(elementIndex < nbits); + map[elementIndex] = value; + } + static void getIndexAndMask(size_t offset, size_t* indexp, WordT* maskp) { MOZ_ASSERT(offset < nbits); static_assert(bitsPerElement == 32, "unexpected bitsPerElement value"); diff --git a/js/src/ds/Bitmap.h b/js/src/ds/Bitmap.h index 6770585a61..f564e2a328 100644 --- a/js/src/ds/Bitmap.h +++ b/js/src/ds/Bitmap.h @@ -162,8 +162,26 @@ class SparseBitmap { void bitwiseOrWith(const SparseBitmap& other); void bitwiseOrInto(DenseBitmap& other) const; - // Currently, this API only supports a range of words that is in a single bit - // block. + // Currently, the following APIs only supports a range of words that is in a + // single bit block. + + template <typename T> + typename std::enable_if_t<std::is_convertible_v<T, uintptr_t>, void> + bitwiseAndRangeWith(size_t wordStart, size_t numWords, T* source) { + size_t blockWord = blockStartWord(wordStart); + + // We only support using a single bit block in this API. + MOZ_ASSERT(numWords && + (blockWord == blockStartWord(wordStart + numWords - 1))); + + BitBlock* block = getBlock(blockWord / WordsInBlock); + if (block) { + for (size_t i = 0; i < numWords; i++) { + (*block)[wordStart - blockWord + i] &= source[i]; + } + } + } + template <typename T> typename std::enable_if_t<std::is_convertible_v<T, uintptr_t>, void> bitwiseOrRangeInto(size_t wordStart, size_t numWords, T* target) const { diff --git a/js/src/ds/OrderedHashTable.h b/js/src/ds/OrderedHashTable.h index 3ef366abc3..75c22bd123 100644 --- a/js/src/ds/OrderedHashTable.h +++ b/js/src/ds/OrderedHashTable.h @@ -39,6 +39,7 @@ #include "mozilla/HashFunctions.h" #include "mozilla/Likely.h" +#include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" #include "mozilla/TemplateLib.h" @@ -85,9 +86,16 @@ class OrderedHashTable { uint32_t dataCapacity; // size of data, in elements uint32_t liveCount; // dataLength less empty (removed) entries uint32_t hashShift; // multiplicative hash shift - Range* ranges; // list of all live Ranges on this table in malloc memory - Range* - nurseryRanges; // list of all live Ranges on this table in the GC nursery + + // List of all live Ranges on this table in malloc memory. Populated when + // ranges are created. + Range* ranges; + + // List of all live Ranges on this table in the GC nursery. Populated when + // ranges are created. This is cleared at the start of minor GC and rebuilt + // when ranges are moved. + Range* nurseryRanges; + AllocPolicy alloc; mozilla::HashCodeScrambler hcs; // don't reveal pointer hash codes @@ -382,22 +390,28 @@ class OrderedHashTable { next->prevp = &next; } seek(); + MOZ_ASSERT(valid()); } public: - Range(const Range& other) + Range(const Range& other, bool inNursery) : ht(other.ht), i(other.i), count(other.count), - prevp(&ht->ranges), - next(ht->ranges) { + prevp(inNursery ? &ht->nurseryRanges : &ht->ranges), + next(*prevp) { *prevp = this; if (next) { next->prevp = &next; } + MOZ_ASSERT(valid()); } ~Range() { + if (!prevp) { + // Head of removed nursery ranges. + return; + } *prevp = next; if (next) { next->prevp = prevp; @@ -446,12 +460,15 @@ class OrderedHashTable { i = count = 0; } - bool valid() const { return next != this; } +#ifdef DEBUG + bool valid() const { return /* *prevp == this && */ next != this; } +#endif void onTableDestroyed() { MOZ_ASSERT(valid()); prevp = &next; next = this; + MOZ_ASSERT(!valid()); } public: @@ -559,9 +576,6 @@ class OrderedHashTable { /* * Allocate a new Range, possibly in nursery memory. The buffer must be * large enough to hold a Range object. - * - * All nursery-allocated ranges can be freed in one go by calling - * destroyNurseryRanges(). */ Range* createRange(void* buffer, bool inNursery) const { auto* self = const_cast<OrderedHashTable*>(this); @@ -570,7 +584,16 @@ class OrderedHashTable { return static_cast<Range*>(buffer); } - void destroyNurseryRanges() { nurseryRanges = nullptr; } + void destroyNurseryRanges() { + if (nurseryRanges) { + nurseryRanges->prevp = nullptr; + } + nurseryRanges = nullptr; + } + +#ifdef DEBUG + bool hasNurseryRanges() const { return nurseryRanges; } +#endif /* * Change the value of the given key. @@ -959,13 +982,17 @@ class OrderedHashMap { HashNumber hash(const Lookup& key) const { return impl.prepareHash(key); } template <typename GetNewKey> - void rekeyOneEntry(const Lookup& current, const GetNewKey& getNewKey) { + mozilla::Maybe<Key> rekeyOneEntry(Lookup& current, GetNewKey&& getNewKey) { + // TODO: This is inefficient because we also look up the entry in + // impl.rekeyOneEntry below. const Entry* e = get(current); if (!e) { - return; + return mozilla::Nothing(); } + Key newKey = getNewKey(current); - return impl.rekeyOneEntry(current, newKey, Entry(newKey, e->value)); + impl.rekeyOneEntry(current, newKey, Entry(newKey, e->value)); + return mozilla::Some(newKey); } Range* createRange(void* buffer, bool inNursery) const { @@ -973,6 +1000,9 @@ class OrderedHashMap { } void destroyNurseryRanges() { impl.destroyNurseryRanges(); } +#ifdef DEBUG + bool hasNurseryRanges() const { return impl.hasNurseryRanges(); } +#endif void trace(JSTracer* trc) { impl.trace(trc); } @@ -1048,12 +1078,16 @@ class OrderedHashSet { HashNumber hash(const Lookup& value) const { return impl.prepareHash(value); } template <typename GetNewKey> - void rekeyOneEntry(const Lookup& current, const GetNewKey& getNewKey) { + mozilla::Maybe<T> rekeyOneEntry(Lookup& current, GetNewKey&& getNewKey) { + // TODO: This is inefficient because we also look up the entry in + // impl.rekeyOneEntry below. if (!has(current)) { - return; + return mozilla::Nothing(); } + T newKey = getNewKey(current); - return impl.rekeyOneEntry(current, newKey, newKey); + impl.rekeyOneEntry(current, newKey, newKey); + return mozilla::Some(newKey); } Range* createRange(void* buffer, bool inNursery) const { @@ -1061,6 +1095,9 @@ class OrderedHashSet { } void destroyNurseryRanges() { impl.destroyNurseryRanges(); } +#ifdef DEBUG + bool hasNurseryRanges() const { return impl.hasNurseryRanges(); } +#endif void trace(JSTracer* trc) { impl.trace(trc); } |