Fix some memory leaks

This commit is contained in:
2026-01-28 14:54:15 -08:00
parent de43dfcda2
commit 76b28c1dc0
8 changed files with 51 additions and 2 deletions

View File

@ -1,5 +1,5 @@
DEBUG=1
LLVM_SAN=0
LLVM_SAN=1
ifeq ($(DEBUG),1)
DEBUG_CFLAGS=-g

View File

@ -307,3 +307,26 @@ void lisp_gc_now(struct timespec *restrict time_took) {
++total_gc_count;
lisp_doing_gc = false;
}
void lisp_gc_teardown(void) {
assert(the_stack.depth == 0);
while (white_objects) {
free_object(white_objects->obj);
}
while (grey_objects) {
free_object(grey_objects->obj);
}
while (black_objects) {
free_object(black_objects->obj);
}
while (static_objects) {
struct GCObjectList *next = static_objects->next;
free(static_objects);
static_objects = next;
}
while (free_objects_list) {
struct GCObjectList *next = free_objects_list->next;
free(free_objects_list);
free_objects_list = next;
}
}

View File

@ -33,4 +33,8 @@ void gc_move_to_set(void *val, ObjectGCSet new_set);
void lisp_gc_now(struct timespec *restrict time_took);
// Unregister all static objects and prepare for shutdown
// The stack MUST be empty when this is called
void lisp_gc_teardown(void);
#endif

View File

@ -92,6 +92,7 @@ static void rehash(LispHashTable *ht, size_t new_size) {
nb->value = cob->value;
}
}
lisp_free(old_data);
}
static void maybe_rehash(LispHashTable *ht) {

View File

@ -52,7 +52,10 @@ void lisp_init(void) {
lisp_init_stack();
}
void lisp_shutdown(void) {}
void lisp_shutdown(void) {
lisp_gc_teardown();
lisp_teardown_stack();
}
DEFUN(eval, "eval", (LispVal * form), "(form)", "") {
if (!OBJECTP(form)) {

View File

@ -31,6 +31,7 @@ DEFUN(cons, "cons", (LispVal * car, LispVal *cdr), "(car cdr)",
DEFUN(length, "length", (LispVal * list), "(list)", "") {
// TODO type check
// TODO list may be circular
return MAKE_FIXNUM(list_length(list));
}

View File

@ -26,6 +26,21 @@ void lisp_init_stack(void) {
the_stack.nogc_retval = Qnil;
}
static void teardown_stack_frame(struct StackFrame *restrict frame) {
for (size_t i = 0; i < frame->local_refs.num_blocks; ++i) {
lisp_free(frame->local_refs.blocks[i]);
}
lisp_free(frame->local_refs.blocks);
}
void lisp_teardown_stack(void) {
assert(the_stack.depth == 0);
for (size_t i = 0; i < the_stack.max_depth; ++i) {
teardown_stack_frame(&the_stack.frames[i]);
}
lisp_free(the_stack.frames);
}
void push_stack_frame(LispVal *name, LispVal *fobj, LispVal *args) {
assert(the_stack.depth < the_stack.max_depth);
struct StackFrame *frame = &the_stack.frames[the_stack.depth++];
@ -164,6 +179,7 @@ void add_local_reference(LispVal *obj) {
while ((cur = next_local_reference(&i))) {
add_local_refs_for_object_sub_vals(seen_objs, cur);
}
release_hash_table_no_gc(seen_objs);
}
void compact_stack_frame(struct StackFrame *restrict frame) {

View File

@ -41,6 +41,7 @@ static ALWAYS_INLINE struct StackFrame *LISP_STACK_TOP(void) {
}
void lisp_init_stack(void);
void lisp_teardown_stack(void);
void push_stack_frame(LispVal *name, LispVal *fobj, LispVal *args);
void pop_stack_frame(void);
void add_local_reference_no_recurse(LispVal *obj);