From 5ac4b3113364c8d9da6e688fceaeed45dc7851d1 Mon Sep 17 00:00:00 2001 From: Jeff Laughlin Date: Mon, 17 Mar 2025 20:39:40 -0400 Subject: [PATCH 1/3] Fix race between GC and case object construction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Does a partial GC before constructing new case objects to ensure there are enough free nodes to finish construction and add it to a root node before the GC runs again. Case objects must be marked twice so if the GC runs after a new case is allocated but before it is added to the hash table AND a root AND the pointer isn't found on the stack, eg because it was optimized out, then the GC may free the cases. I was concerned this would have a negative performance impact... It actually improved unit test performance by 10-20%. ¯\_(ツ)_/¯ --- globals.h | 2 ++ intern.c | 1 + 2 files changed, 3 insertions(+) diff --git a/globals.h b/globals.h index fe1ddef..4dbbcf2 100644 --- a/globals.h +++ b/globals.h @@ -674,3 +674,5 @@ extern NODE *parent_list(NODE *); extern void dbUsual(const char*); #endif + +void do_gc(BOOLEAN full); diff --git a/intern.c b/intern.c index a0dd55e..76651a2 100644 --- a/intern.c +++ b/intern.c @@ -57,6 +57,7 @@ FIXNUM hash(char *s, int len) { NODE *make_case(NODE *casestrnd, NODE *obj) { NODE *new_caseobj, *clistptr; + do_gc(FALSE); clistptr = caselistptr__object(obj); new_caseobj = make_caseobj(casestrnd, obj); setcdr(clistptr, cons(new_caseobj, cdr(clistptr))); From 027f7d91158b36a7ad1367f2ce12cdb5f2f40611 Mon Sep 17 00:00:00 2001 From: Jeff Laughlin Date: Mon, 17 Mar 2025 22:26:03 -0400 Subject: [PATCH 2/3] Change slow GC to fast preallocation --- intern.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/intern.c b/intern.c index 76651a2..215dbcb 100644 --- a/intern.c +++ b/intern.c @@ -55,12 +55,14 @@ FIXNUM hash(char *s, int len) { } NODE *make_case(NODE *casestrnd, NODE *obj) { - NODE *new_caseobj, *clistptr; + NODE *new_caseobj, *clistptr, *tmp; - do_gc(FALSE); + tmp = cons(NIL, NIL); clistptr = caselistptr__object(obj); new_caseobj = make_caseobj(casestrnd, obj); - setcdr(clistptr, cons(new_caseobj, cdr(clistptr))); + setcar(tmp, new_caseobj); + setcdr(tmp, cdr(clistptr)); + setcdr(clistptr, tmp); return(new_caseobj); } From 8a1dea52dae888b49befe149104675eb5f0862be Mon Sep 17 00:00:00 2001 From: "Joshua J. Cogliati" Date: Mon, 31 Mar 2025 06:15:01 -0600 Subject: [PATCH 3/3] Revert adding to globals.h --- globals.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/globals.h b/globals.h index 4dbbcf2..fe1ddef 100644 --- a/globals.h +++ b/globals.h @@ -674,5 +674,3 @@ extern NODE *parent_list(NODE *); extern void dbUsual(const char*); #endif - -void do_gc(BOOLEAN full);