diff options
Diffstat (limited to 'js/src/vm/ArrayBufferObject.cpp')
-rw-r--r-- | js/src/vm/ArrayBufferObject.cpp | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 2fe4f01f8d..14039af574 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -2830,7 +2830,7 @@ bool InnerViewTable::addView(JSContext* cx, ArrayBufferObject* buffer, if (isNurseryView && !hadNurseryViews && nurseryKeysValid) { #ifdef DEBUG if (nurseryKeys.length() < 100) { - for (auto* key : nurseryKeys) { + for (const auto& key : nurseryKeys) { MOZ_ASSERT(key != buffer); } } @@ -2859,31 +2859,53 @@ void InnerViewTable::removeViews(ArrayBufferObject* buffer) { map.remove(ptr); } -bool InnerViewTable::traceWeak(JSTracer* trc) { return map.traceWeak(trc); } +bool InnerViewTable::traceWeak(JSTracer* trc) { + nurseryKeys.traceWeak(trc); + map.traceWeak(trc); + return true; +} void InnerViewTable::sweepAfterMinorGC(JSTracer* trc) { MOZ_ASSERT(needsSweepAfterMinorGC()); - if (nurseryKeysValid) { - for (size_t i = 0; i < nurseryKeys.length(); i++) { - ArrayBufferObject* buffer = nurseryKeys[i]; + NurseryKeysVector keys; + bool valid = true; + std::swap(nurseryKeys, keys); + std::swap(nurseryKeysValid, valid); + + // Use nursery keys vector if possible. + if (valid) { + for (ArrayBufferObject* buffer : keys) { MOZ_ASSERT(!gc::IsInsideNursery(buffer)); auto ptr = map.lookup(buffer); - if (ptr && !ptr->value().sweepAfterMinorGC(trc)) { + if (ptr && !sweepViewsAfterMinorGC(trc, buffer, ptr->value())) { map.remove(ptr); } } - } else { - for (ArrayBufferViewMap::Enum e(map); !e.empty(); e.popFront()) { - MOZ_ASSERT(!gc::IsInsideNursery(e.front().key())); - if (!e.front().value().sweepAfterMinorGC(trc)) { - e.removeFront(); - } + return; + } + + // Otherwise look at every map entry. + for (ArrayBufferViewMap::Enum e(map); !e.empty(); e.popFront()) { + MOZ_ASSERT(!gc::IsInsideNursery(e.front().key())); + if (!sweepViewsAfterMinorGC(trc, e.front().key(), e.front().value())) { + e.removeFront(); } } +} + +bool InnerViewTable::sweepViewsAfterMinorGC(JSTracer* trc, + ArrayBufferObject* buffer, + Views& views) { + if (!views.sweepAfterMinorGC(trc)) { + return false; // No more views. + } - nurseryKeys.clear(); - nurseryKeysValid = true; + if (views.hasNurseryViews() && !nurseryKeys.append(buffer)) { + nurseryKeysValid = false; + } + + return true; } size_t InnerViewTable::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { |