commit 7b372211587fd5c7f90f369245de84b68eb6109a
parent 996938e0bc68f1eafeb22819beb9428c97df4388
Author: Jon Coppeard <jcoppeard@mozilla.com>
Date: Thu, 6 Nov 2025 08:15:06 +0000
Bug 1997896 - Fix some issues with atom marking bitmap state r=sfink
This fixes two problems:
1) Aborting GC while zones are in the prepare state needs to flag gray marking
state as invalid. We don't do gray unmarking in zones that are having their
mark bits cleared, so this also needs to be handled the same as for aborting
during incremental marking.
2) We shouldn't be doing gray unmarking during incrmental gray marking since
this will result in atoms being marked black in the arom marking bitmaps.
Differential Revision: https://phabricator.services.mozilla.com/D271383
Diffstat:
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp
@@ -3788,6 +3788,10 @@ GCRuntime::IncrementalResult GCRuntime::resetIncrementalGC(
zone->arenas.mergeArenasFromCollectingLists();
}
+ // The gray marking state may not be valid. We don't do gray unmarking
+ // when zones are in the Prepare state.
+ setGrayBitsInvalid();
+
incrementalState = State::NotActive;
checkGCStateNotInUse();
break;
diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp
@@ -1160,9 +1160,11 @@ template <uint32_t opts, typename S, typename T>
void js::GCMarker::markAndTraverseEdge(S* source, T* target) {
if constexpr (std::is_same_v<T, JS::Symbol>) {
// Unmark gray symbols in incremental GC.
- GCRuntime* gc = &runtime()->gc;
- MOZ_ASSERT(gc->atomMarking.atomIsMarked(source->zone(), target));
- gc->atomMarking.maybeUnmarkGrayAtomically(source->zone(), target);
+ if (markColor() == MarkColor::Black) {
+ GCRuntime* gc = &runtime()->gc;
+ MOZ_ASSERT(gc->atomMarking.atomIsMarked(source->zone(), target));
+ gc->atomMarking.maybeUnmarkGrayAtomically(source->zone(), target);
+ }
}
checkTraversedEdge(source, target);
markAndTraverse<opts>(target);
diff --git a/js/src/jit-test/tests/gc/gray-unmarking.js b/js/src/jit-test/tests/gc/gray-unmarking.js
@@ -87,3 +87,6 @@ assertEq(grayBitsValid(), true);
abortgc();
assertEq(grayBitsValid(), false);
checkMarks("black", "black", "gray");
+
+gc();
+checkMarks("gray", "gray", "gray");