move to meson for build system

This commit is contained in:
Lobo 2026-01-19 10:25:56 -03:00
parent fdd1ee61b5
commit 9616fb616e
28 changed files with 123 additions and 24 deletions

126
gc.c
View file

@ -1,126 +0,0 @@
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include "gc.h"
#include "vendor/yar.h"
#define ALIGN(n) (((n) + 7) & ~7)
static inline int infrom(Gc *gc, V *ptr) {
const U8 *x = (const U8 *)ptr;
return (x >= gc->from.start && x < gc->from.end);
}
V gc_addroot(Gc *gc, O *ptr) { *yar_append(&gc->roots) = ptr; }
I gc_mark(Gc *gc) { return gc->roots.count; }
V gc_reset(Gc *gc, I mark) { gc->roots.count = mark; }
static O copy(Gc *gc, Hd *hdr) {
assert(infrom(gc, hdr));
assert(hdr->type != TYPE_FWD);
Z sz = ALIGN(hdr->size);
Hd *new = (Hd *)gc->to.free;
gc->to.free += sz;
memcpy(new, hdr, sz);
hdr->type = TYPE_FWD;
O *obj = (O *)(hdr + 1);
*obj = BOX(new);
return *obj;
}
static O forward(Gc *gc, O obj) {
if (obj == 0)
return 0;
if (IMM(obj))
return obj;
if (!infrom(gc, (V *)obj))
return obj;
Hd *hdr = UNBOX(obj);
if (hdr->type == TYPE_FWD) {
O *o = (O *)(hdr + 1);
return *o;
} else {
return copy(gc, hdr);
}
}
#if GC_DEBUG
static V printstats(Gc *gc, const char *label) {
Z used = (Z)(gc->from.free - gc->from.start);
fprintf(stderr, "[%s] used=%zu/%zu bytes (%.1f%%)\n", label, used,
(Z)HEAP_BYTES, (F)used / (F)HEAP_BYTES * 100.0);
}
#endif
V gc_collect(Gc *gc) {
uint8_t *scan = gc->to.free;
#if GC_DEBUG
printstats(gc, "before GC");
#endif
for (Z i = 0; i < gc->roots.count; i++) {
O *o = gc->roots.items[i];
*o = forward(gc, *o);
}
while (scan < gc->to.free) {
if (scan >= gc->to.end) {
fprintf(stderr, "fatal GC error: out of memory\n");
abort();
}
Hd *hdr = (Hd *)scan;
switch (hdr->type) {
// TODO: the rest of the owl
case TYPE_FWD:
fprintf(stderr, "fatal GC error: forwarding pointer in to-space\n");
abort();
default:
fprintf(stderr, "GC warning: junk object type %" PRId32 "\n", hdr->type);
}
scan += ALIGN(hdr->size);
}
Gs tmp = gc->from;
gc->from = gc->to;
gc->to = tmp;
gc->to.free = gc->to.start;
#if GC_DEBUG
printstats(gc, "after GC");
#endif
}
void gc_init(Gc *gc) {
gc->from.start = malloc(HEAP_BYTES);
if (!gc->from.start)
goto fatal;
gc->from.end = gc->from.start + HEAP_BYTES;
gc->from.free = gc->from.start;
gc->to.start = malloc(HEAP_BYTES);
if (!gc->to.start)
goto fatal;
gc->to.end = gc->to.start + HEAP_BYTES;
gc->to.free = gc->to.start;
gc->roots.capacity = 0;
gc->roots.count = 0;
gc->roots.items = NULL;
return;
fatal:
fprintf(stderr, "failed to allocate heap space\n");
abort();
}
void gc_deinit(Gc *gc) {
gc_collect(gc);
free(gc->from.start);
free(gc->to.start);
yar_free(&gc->roots);
}