diff --git a/clox/src/memory.c b/clox/src/memory.c index 7d403d1..c639b65 100644 --- a/clox/src/memory.c +++ b/clox/src/memory.c @@ -150,6 +150,28 @@ static void traceReferences() { } } +static void sweep() { + Obj *previous = NULL; + Obj *object = vm.objects; + while (object != NULL) { + if (object->isMarked) { + object->isMarked = false; + previous = object; + object = object->next; + } else { + Obj *unreached = object; + object = object->next; + if (previous != NULL) { + previous->next = object; + } else { + vm.objects = object; + } + + freeObject(unreached); + } + } +} + void collectGarbage() { #ifdef DEBUG_LOG_GC printf("-- gc begin\n"); @@ -157,6 +179,8 @@ void collectGarbage() { markRoots(); traceReferences(); + tableRemoveWhite(&vm.strings); + sweep(); #ifdef DEBUG_LOG_GC printf("-- gd end\n"); diff --git a/clox/src/table.c b/clox/src/table.c index ae34ab0..134f455 100644 --- a/clox/src/table.c +++ b/clox/src/table.c @@ -141,6 +141,15 @@ ObjString *tableFindString(Table *table, const char *chars, int length, } } +void tableRemoveWhite(Table *table) { + for (int i = 0; i < table->capacity; i++) { + Entry *entry = &table->entries[i]; + if (entry->key != NULL && !entry->key->obj.isMarked) { + tableDelete(table, entry->key); + } + } +} + void markTable(Table *table) { for (int i = 0; i < table->capacity; i++) { Entry *entry = &table->entries[i]; diff --git a/clox/src/table.h b/clox/src/table.h index b2bf7a3..8c5aa07 100644 --- a/clox/src/table.h +++ b/clox/src/table.h @@ -23,6 +23,7 @@ bool tableDelete(Table *table, ObjString *key); void tableAddAll(Table *from, Table *to); ObjString *tableFindString(Table *talbe, const char *chars, int length, uint32_t hash); +void tableRemoveWhite(Table *table); void markTable(Table *table); #endif