Day Fifty Eight
I spent over an hour stuck because I didn't realize br 0 in a loop doesn't break out of the loop. Anyways I've decided to go with the heap being 100% GC'd. To start I've settled on making every allocation typed, this includes the internal buffers of tables. This'll apply to the callstack too. There's an oroot global now I haven't gotten to: it'll be a vec of roots. The GC will be compacting. Right now I'm thinking 2-state mark-and-sweep Lisp2 because I understand how to implement it off reading the description

Mark/Sweep bits will be stored in lower bits of relocation pointers. Going with all allocations being 8-byte aligned so that the GC's copying can assume it's safe to memcpy with 64bit instructions. No 'next' pointers because given an object one can deduce its size, so next is self+sizeof(self)

Had to jiggle with table code since I'm no longer storing capacity inside the table struct, as that's stored in the vec instance. vec initializes filled with nils, this way I don't have to store a len/cap pair in vecs. Code had to rethink a bit since various values were being stored as element count rather than byte count, but vec stores its size as byte code, even though it must be a multiple of 4, as vec represents a collection of objects, ended up mostly simplifying the code