Note [Large objects in the non-moving collector]
The nonmoving collector keeps a separate list of its large objects, apart from
oldest_gen->large_objects. There are two reasons for this:
1. oldest_gen is mutated by minor collections, which happen concurrently with
marking
2. the non-moving collector needs a consistent picture
At the beginning of a major collection, nonmovingCollect takes the objects in
oldest_gen->large_objects (which includes all large objects evacuated by the
moving collector) and adds them to nonmoving_large_objects. This is the set
of large objects that will being collected in the current major GC cycle.
As the concurrent mark phase proceeds, the large objects in
nonmoving_large_objects that are found to be live are moved to
nonmoving_marked_large_objects. During sweep we discard all objects that remain
in nonmoving_large_objects and move everything in nonmoving_marked_larged_objects
back to nonmoving_large_objects.
During minor collections large objects will accumulate on
oldest_gen->large_objects, where they will be picked up by the nonmoving
collector and moved to nonmoving_large_objects during the next major GC.
When this happens the block gets its BF_NONMOVING_SWEEPING flag set to
indicate that it is part of the snapshot and consequently should be marked by
the nonmoving mark phase.
Note that pinned object blocks are treated as large objects containing only
a single object. That is, the block has a single mark flag (BF_MARKED) and we
consequently will trace the pointers of only one object per block. However,
this is okay since the only type of pinned object supported by GHC is the
pinned ByteArray#, which has no pointers.
We need to take care that the stats department is made aware of the amount of
live large (and compact) objects, since they no longer live on gen[i]->large_objects.
Failing to do so caused #17574. References 0
This Note does not link to any other.