shithub: sl

Download patch

ref: c3e7f845c40f501ea112d2aa3f1764c51d254922
parent: c214932b4ac9a978d255221bb01d8657c02f6d5a
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Apr 24 03:08:14 EDT 2025

exit: sweep *all* cvalues

This ensures there are no pointers to malloced memory left
dangling, which memory leaks analyzer was complaining about.

--- a/src/cvalues.c
+++ b/src/cvalues.c
@@ -15,6 +15,7 @@
 #define owned(cv) ((uintptr)(cv)->type & CV_OWNED)
 #define isinlined(cv) ((cv)->data == (cv)->_space)
 
+static sl_type notype = {0};
 sl_type *unboxedtypes[T_UNBOXED_NUM];
 sl_v unboxedtypesyms[T_UNBOXED_NUM];
 
@@ -31,9 +32,22 @@
 	slg.finalizers[slg.nfinalizers++] = cv;
 }
 
+static void
+sweep_cv(sl_cv *cv)
+{
+	sl_type *t = cv_class(cv);
+	if(t->vtable != nil && t->vtable->finalize != nil)
+		t->vtable->finalize(tagptr(cv, TAG_CVALUE));
+	if(!isinlined(cv) && owned(cv)){
+		MEM_FREE(cv_data(cv));
+		cv_data(cv) = nil;
+	}
+	cv->type = &notype;
+}
+
 // remove dead objects from finalization list in-place
 void
-sweep_finalizers(void)
+sweep_finalizers(bool all)
 {
 	sl_cv **lst = slg.finalizers;
 	usize n = 0, ndel = 0, l = slg.nfinalizers;
@@ -43,17 +57,18 @@
 		return;
 	do{
 		tmp = lst[n];
+		bool live = false;
 		if(isforwarded((sl_v)tmp)){
 			// object is alive
-			lst[n] = ptr(forwardloc((sl_v)tmp));
-			n++;
-		}else{
-			sl_type *t = cv_class(tmp);
-			if(t->vtable != nil && t->vtable->finalize != nil)
-				t->vtable->finalize(tagptr(tmp, TAG_CVALUE));
-			if(!isinlined(tmp) && owned(tmp))
-				MEM_FREE(cv_data(tmp));
+			tmp = ptr(forwardloc((sl_v)tmp));
+			live = true;
+		}
+		if(!live || all){
+			sweep_cv(tmp);
 			ndel++;
+		}else{
+			lst[n] = tmp;
+			n++;
 		}
 	}while((n < l-ndel) && SWAP_sf(lst[n], lst[n+ndel]));
 
--- a/src/cvalues.h
+++ b/src/cvalues.h
@@ -1,7 +1,7 @@
 #pragma once
 
 void add_finalizer(sl_cv *cv);
-void sweep_finalizers(void);
+void sweep_finalizers(bool all);
 void cv_autorelease(sl_cv *cv);
 sl_v cvalue_(sl_type *type, usize sz, bool nofinalizer);
 #define cvalue(type, sz) cvalue_(type, sz, false)
--- a/src/htable.c
+++ b/src/htable.c
@@ -48,6 +48,7 @@
 {
 	if(h->table != &h->_space[0])
 		MEM_FREE(h->table);
+	h->table = nil;
 }
 
 // empty and reduce size
--- a/src/sl.c
+++ b/src/sl.c
@@ -556,7 +556,7 @@
 	sl_emptyvec = sl_relocate(sl_emptyvec);
 	sl_emptystr = sl_relocate(sl_emptystr);
 
-	sweep_finalizers();
+	sweep_finalizers(slg.exiting);
 
 	void *temp = slg.tospace;
 	slg.tospace = slg.fromspace;