summaryrefslogtreecommitdiffstats
path: root/js/src/vm/ArrayBufferObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/ArrayBufferObject.cpp')
-rw-r--r--js/src/vm/ArrayBufferObject.cpp50
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) {