Module mark_nursery_bits_states

Module mark_nursery_bits_states 

Source
Expand description

The states of the ObjectModel::LOCAL_LOS_MARK_NURSERY_SPEC metadata in tracing-based GC.

§The states

LOS objects can be in one of the three states at any time:

StateNURSERY_BITMARK_BIT
Nursery1disregarded
MatureUnmarked0!= mark_state
MatureMarked0== mark_state

Note that there is no “nursery marked” state. Nursery objects are promoted when marked.

When encoded as the two-bit metadata, both 0b10 and 0b11 represents the Nursery state. When the NURSERY_BIT is 0, it is mature, and the MARK_BIT represents “marked” if it is equal to LargeObjectSpace::mark_state.

When flipping the meaning of the mark bit, MatureUnmarked becomes MatureMarked, and MatureMarked becomes MatureUnmarked. However, the Nursery state remains the Nursery state because the mark bit is ignored.

§In tracing collectors

In tracing collectors, allowed state transitions are:

 allocate (normal)          allocate (as live)
 │                          |
 │   ┌──┐flip mark state    |
 │   │  │                   |
┌▼───▼──┴─┐         ┌───────▼──────┐ flip mark state ┌────────────────┐
│         │ mark    │              ├────────────────►│                │
│ Nursery │────────►│ MatureMarked │                 │ MatureUnmarked │
│         │         │              │◄────────────────┤                │
└─────────┘         └──────────────┘ mark            └────────────────┘

Newly allocated objects can be either in the Nursery state (for normal allocations) or the MatureMarked state (when allocating as live for concurrent GC). Note that right before flipping mark state (at the beginning of a full-heap GC), all objects must be either in the Nursery state or the MatureMarked state. There must not be unmarked mature objects, otherwise it is an error. After flipping, all objects become unmarked (Nursery remains Nursery, and MatureMarked becomes MatureUnmarked).

§In RC collectors

In RC collectors (currently just LXR), the NURSERY_BIT is unused, and the Nursery state is unused.

        allocate
        |
┌───────▼──────┐ flip mark state ┌────────────────┐
│              ├────────────────►│                │
│ MatureMarked │                 │ MatureUnmarked │
│              │◄────────────────┤                │
└──────────────┘ mark            └────────────────┘

Newly allocated objects are always in the MatureMarked state. There are two reasons:

  1. When backup tracing is not in progress, all (surviving) objects are in the MatureMarked state. Allocating new objects in the MatureMarked state just makes them look like any other objects. During RC collections, only the reference counts are used, and the MatureMarked state is disregared.
  2. When backup tracing starts (the InitialMark pause or the Full pause), the meaning of the mark bit is flipped, and all MatureMarked objects become MatureUnmarked. Objects allocated during concurrent marking are in the MatureMarked state, too. They will be conservatively considered as “marked”, just like SATB-based concurrent tracing collectors. At the end of tracing, objects that are in the MatureUnmarked state have been dead since tracing started, i.e. they have been dead in the snapshot in the beginning (SATB).

Functions§

is_marked
Return true if the mark-nursery state represents a marked state (i.e. the MatureMarked state). All other states are considered unmarked.
is_nursery
Return true if the mark-nursery state represents the Nursery state.