# Simple Garbage Collector Consistency

21 February 2019

In a previous log entry, I discussed setting up a set() function to help with keeping reference-counted objects in a garbage collection system in line. While I did play around with that for a while, I determined that what I needed to do to fix my reference-counting problems first was probably to write some form of consistency check. To that end, I wrote the following function. For reference, gc_list points to the head of a singly-linked list (of cons cells) pointing to all allocated atoms in the system.

void __debug_gc_consistency(void)
{
    assert(gc_list);
    atom_t *outer = gc_list;
    while (outer != nil) {
        if (ATOM_REFS(outer->car) == 0
            && !(ATOM_FLAGS(outer->car) & FPROT)
            && outer->car != nil) {
            while (inner != nil) {
                if (inner->car != outer->car &&
                    (AS_ATOM(inner->car)->car == outer->car || AS_ATOM(inner->car)->cdr == outer->car)) {
                    char *irep = atom_repr(inner->car);
                    char *orep = atom_repr(outer->car);
                    printf("\n%s still refers to %s\n", irep, orep);
                    free(irep);
                    free(orep);
                }
                inner = inner->cdr;
            }
        }
        outer = outer->cdr;
    }
}

Ignoring the presence of the nasty ATOM_x and AS_ATOM macros (which I intend to change soon), the code amounts to a loop within a loop, such that all pairs of two atoms are checked to see if one is due to be garbage collected with another still pointing at it. Using this function, I have already eliminated a few bugs from the language's reader code, and I intend to apply it to the evaluation and macro systems as well. It will probably get cleaned up some in the process, as it is a bit rough-looking right now (and, for instance, still prints to stdout instead of something more sane like stderr).