GHC Commentary: Garbage Collecting CAFs

Constant Applicative Forms, or CAFs for short, are top-level values defined in a program.
Essentially, they are objects that are not allocated dynamically at run-time but, instead,
are part of the static data of the program. Sometimes, a CAF may refer to many values in the heap. To avoid memory leaks in such situations, we need to know when a CAF is never going to be used
again, and so we can deallocate the values that it refers to.

Evacuating Static Objects

While scavenging objects, we also process (aka "evacuate") any static objects that need to be kept alive. When a GC thread discovers a live static object, it places it on its static_objects
list. Later, this list is used to scavange the static objects, potentially finding more live objects.
Note that this process might find more static objects, and thus further extend the static_objects list.

When a static object is scavenged, it is removed from static_objects and placed on another list, called scavenged_static_objects. Later, we use this list to "clean up" the liveness markers from these static objects, so that we can repeat the process on the next garbage collection.
Note that we can't "clean up" the liveness markers as we go along because we use them to notice
cycles among the static objects.