Note [Update remembered set]

rts/sm/NonMovingMark.c:129 rts

The concurrent non-moving collector uses a remembered set to ensure
that its marking is consistent with the snapshot invariant defined in
the design. This remembered set, known as the update remembered set,
records all pointers that have been overwritten since the beginning
of the concurrent mark. This ensures that concurrent mutation cannot hide
pointers to live objects from the nonmoving garbage collector.

The update remembered set is maintained via a write barrier that
is enabled whenever a concurrent mark is active. This write barrier
can be found in a number of places:

 - In rts/Primops.cmm in primops responsible for modifying mutable closures
   (e.g. MVARs, MUT_VARs, etc.)

 - In rts/STM.c, where

 - In the dirty_* functions found in rts/Storage.c where we dirty MVARs,
   MUT_VARs, TSOs and STACKs. STACK is a somewhat special case, as described
   in Note [StgStack dirtiness flags and concurrent marking] in TSO.h.

 - In the code generated by the STG code generator for pointer array writes

 - In thunk updates (e.g. updateWithIndirection) to ensure that the free
   variables of the original thunk remain reachable.

There is also a read barrier to handle weak references, as described in
Note [Concurrent read barrier on deRefWeak#].

The representation of the update remembered set is the same as that of
the mark queue. For efficiency, each capability maintains its own local
accumulator of remembered set entries. When a capability fills its
accumulator it is linked in to the global remembered set
(upd_rem_set_block_list), where it is consumed by the mark phase.

The mark phase is responsible for freeing update remembered set block
allocations.

Note that we eagerly flush update remembered sets during minor GCs as
described in Note [Eager update remembered set flushing].