Cell memory (quads) are subject to machine-level garbage collection.
The garbage-collected heap ranges from START
up to (not including) cell_top
.
The floor (currently START
) may be moved upward to include additional "reserved" cells.
The ceiling (held in the variable cell_top
) is extended upward
to expand the pool of available memory,
up to a limit of CELL_MAX
.
The bootstrap image initially occupies cells up to CELL_BASE
,
which determines the initial value of cell_top
.
The garbage-collector maintains a mark for each cell in the heap. The mark can have one of four possible values:
GC_GENX
: This cell is in use as of Generation XGC_GENY
: This cell is in use as of Generation YGC_SCAN
: This cell is in use, but has not been scannedGC_FREE
: This cell is in the free-cell chain {t:Free_T}
The current generation alternates between GC_GENX
and GC_GENY
.
Cells in the range [START
, CELL_BASE
) are initially marked GC_GENX
.
Garbage collection is concurrent with allocation and mutation. An increment of the garbage collector algorithm runs between each instruction execution cycle. The overall algorithm is roughly the following:
- Swap generations (
GC_GENX
<-->GC_GENY
) - Mark each cell in the root-set with
GC_SCAN
- If a new cell is added to the root-set, mark it with
GC_SCAN
- If a new cell is added to the root-set, mark it with
- Mark each newly-allocated cell with
GC_SCAN
- While there are cells marked
GC_SCAN
:- Scan a cell, for each field of the cell:
- If it points to the heap, and is marked with the previous generation, mark it
GC_SCAN
- If it points to the heap, and is marked with the previous generation, mark it
- Mark the cell with the current generation
- Scan a cell, for each field of the cell:
- For each cell marked with the previous generation,
- Mark the cell
GC_FREE
and add it to the free-cell chain
- Mark the cell