next: *
This commit is contained in:
parent
2ac2f85512
commit
90175b7e26
12 changed files with 300 additions and 77 deletions
|
|
@ -67,38 +67,40 @@ GrowlObjectHeader *growl_gc_alloc_tenured(GrowlVM *vm, size_t size) {
|
|||
|
||||
static void scan(GrowlVM *vm, GrowlObjectHeader *hdr) {
|
||||
switch (hdr->type) {
|
||||
case GROWL_STRING:
|
||||
case GROWL_TYPE_STRING:
|
||||
break;
|
||||
case GROWL_LIST: {
|
||||
case GROWL_TYPE_LIST: {
|
||||
GrowlList *list = (GrowlList *)(hdr + 1);
|
||||
list->head = forward(vm, list->head);
|
||||
list->tail = forward(vm, list->tail);
|
||||
break;
|
||||
}
|
||||
case GROWL_TUPLE: {
|
||||
case GROWL_TYPE_TUPLE: {
|
||||
GrowlTuple *tuple = (GrowlTuple *)(hdr + 1);
|
||||
for (size_t i = 0; i < tuple->count; ++i) {
|
||||
tuple->data[i] = forward(vm, tuple->data[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GROWL_QUOTATION: {
|
||||
case GROWL_TYPE_QUOTATION: {
|
||||
GrowlQuotation *quot = (GrowlQuotation *)(hdr + 1);
|
||||
quot->constants = forward(vm, quot->constants);
|
||||
break;
|
||||
}
|
||||
case GROWL_COMPOSE: {
|
||||
case GROWL_TYPE_COMPOSE: {
|
||||
GrowlCompose *comp = (GrowlCompose *)(hdr + 1);
|
||||
comp->first = forward(vm, comp->first);
|
||||
comp->second = forward(vm, comp->second);
|
||||
break;
|
||||
}
|
||||
case GROWL_CURRY: {
|
||||
case GROWL_TYPE_CURRY: {
|
||||
GrowlCurry *comp = (GrowlCurry *)(hdr + 1);
|
||||
comp->value = forward(vm, comp->value);
|
||||
comp->callable = forward(vm, comp->callable);
|
||||
break;
|
||||
}
|
||||
case GROWL_TYPE_ALIEN:
|
||||
break;
|
||||
case UINT32_MAX:
|
||||
fprintf(stderr, "gc: fwd pointer during scan\n");
|
||||
abort();
|
||||
|
|
@ -109,15 +111,22 @@ static void scan(GrowlVM *vm, GrowlObjectHeader *hdr) {
|
|||
}
|
||||
|
||||
static void gc_print_stats(GrowlVM *vm, const char *label) {
|
||||
size_t used = vm->from.free - vm->from.start;
|
||||
size_t total = vm->from.end - vm->from.start;
|
||||
fprintf(stderr, "[%s] used=%zu/%zu bytes (%.1f%%)\n", label, used, total,
|
||||
(double)used / (double)total * 100.0);
|
||||
size_t nursery_used = vm->from.free - vm->from.start;
|
||||
size_t nursery_total = vm->from.end - vm->from.start;
|
||||
size_t tenured_used = vm->arena.free - vm->arena.start;
|
||||
size_t tenured_total = vm->arena.end - vm->arena.start;
|
||||
|
||||
fprintf(stderr, "%s:\n", label);
|
||||
fprintf(stderr, " tenured: %zu/%zu bytes (%.1f%%)\n", tenured_used,
|
||||
nursery_total, (double)tenured_used / (double)tenured_total * 100.0);
|
||||
fprintf(stderr, " nursery: %zu/%zu bytes (%.1f%%)\n", nursery_used,
|
||||
nursery_total, (double)nursery_used / (double)nursery_total * 100.0);
|
||||
}
|
||||
|
||||
void growl_gc_collect(GrowlVM *vm) {
|
||||
uint8_t *gc_scan = vm->to.free;
|
||||
|
||||
fprintf(stderr, ">>> starting garbage collection\n");
|
||||
gc_print_stats(vm, "before GC");
|
||||
|
||||
for (size_t i = 0; i < GROWL_STACK_SIZE; ++i) {
|
||||
|
|
@ -141,6 +150,26 @@ void growl_gc_collect(GrowlVM *vm) {
|
|||
gc_scan += ALIGN(hdr->size);
|
||||
}
|
||||
|
||||
gc_scan = vm->from.start;
|
||||
while (gc_scan < vm->from.free) {
|
||||
GrowlObjectHeader *hdr = (GrowlObjectHeader *)gc_scan;
|
||||
if (hdr->type != UINT32_MAX) {
|
||||
switch (hdr->type) {
|
||||
case GROWL_TYPE_ALIEN: {
|
||||
GrowlAlien *alien = (GrowlAlien *)(hdr + 1);
|
||||
if (alien->type->finalizer != NULL) {
|
||||
alien->type->finalizer(alien->data);
|
||||
alien->data = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
gc_scan += ALIGN(hdr->size);
|
||||
}
|
||||
|
||||
GrowlGCArena tmp = vm->from;
|
||||
vm->from = vm->to;
|
||||
vm->to = tmp;
|
||||
|
|
@ -148,6 +177,7 @@ void growl_gc_collect(GrowlVM *vm) {
|
|||
vm->scratch.free = vm->scratch.start;
|
||||
|
||||
gc_print_stats(vm, "after GC");
|
||||
fprintf(stderr, ">>> garbage collection finished\n");
|
||||
}
|
||||
|
||||
void growl_gc_root(GrowlVM *vm, Growl *ptr) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue