2024-08-20 10:56:54 -04:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "gc.h"
|
|
|
|
#include "vm.h"
|
|
|
|
|
|
|
|
void mark(struct garbageObject *obj) {
|
2024-08-20 13:16:27 -04:00
|
|
|
if (obj->mark)
|
|
|
|
return;
|
2024-08-20 10:56:54 -04:00
|
|
|
|
|
|
|
++obj->mark;
|
|
|
|
|
|
|
|
if (obj->type == GARBAGE_PAIR) {
|
|
|
|
mark(obj->head);
|
|
|
|
mark(obj->tail);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void markAll(struct virtualMachine *vm) {
|
|
|
|
for (int i = 0; i < vm->stackSize; ++i) {
|
|
|
|
mark(vm->stack[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sweep(struct virtualMachine *vm) {
|
|
|
|
struct garbageObject **obj = &vm->head;
|
|
|
|
|
|
|
|
while (*obj) {
|
|
|
|
if (!(*obj)->mark) {
|
|
|
|
struct garbageObject *unreachable = *obj;
|
|
|
|
*obj = unreachable->next;
|
|
|
|
free(unreachable);
|
|
|
|
vm->refCount--;
|
|
|
|
} else {
|
|
|
|
(*obj)->mark = 0;
|
|
|
|
obj = &(*obj)->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-20 13:16:27 -04:00
|
|
|
void collect(struct virtualMachine *vm) {
|
2024-08-20 10:56:54 -04:00
|
|
|
markAll(vm);
|
|
|
|
sweep(vm);
|
2024-08-20 13:16:27 -04:00
|
|
|
vm->refMax = vm->refCount * 2 <= STACK_MAX ? vm->refCount * 2 : STACK_MAX;
|
2024-08-20 10:56:54 -04:00
|
|
|
}
|