From f375519dbc9ced7d4e702d9e1872d372b34ee434 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Sat, 19 Jul 2025 12:35:02 -0700 Subject: [PATCH] Cleans up mergebackward implementation Uses consistent naming (_np) for native pointer equivalents of Lisp addresses Adds comments with a little explanation of what the code is doing --- src/gcfinal.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/gcfinal.c b/src/gcfinal.c index 763a777..2f52fdd 100644 --- a/src/gcfinal.c +++ b/src/gcfinal.c @@ -418,18 +418,34 @@ static LispPTR arrayblockmerger(LispPTR base, LispPTR nbase) { /* */ /************************************************************************/ +/* + * merges this block into the block behind it, unless there are + * disqualifying conditions: + * merging is turned off or + * this is the first block in array space or + * this is the first block in the 2nd array space or + * the block behind it is in use + * in which case it is linked onto the freelist (fwd and backward pointers) + * and added to the free block chain by size. + * If it can be merged, + */ LispPTR mergebackward(LispPTR base) { LispPTR pbase; - struct arrayblock *ptrailer; + struct arrayblock *ptrailer_np; if (base == NIL) return (NIL); - ptrailer = (struct arrayblock *)NativeAligned4FromLAddr(base - ARRAYBLOCKTRAILERWORDS); + /* back up to get the trailer of the previous block */ + ptrailer_np = (struct arrayblock *)NativeAligned4FromLAddr(base - ARRAYBLOCKTRAILERWORDS); + /* check that there are no disqualifying conditions for merging with previous block */ if ((*ArrayMerging_word == NIL) || - ((base == *ArraySpace_word) || ((base == *ArraySpace2_word) || (ptrailer->inuse == T)))) + ((base == *ArraySpace_word) || ((base == *ArraySpace2_word) || (ptrailer_np->inuse == T)))) return (linkblock(base)); - pbase = base - DLWORDSPER_CELL * ptrailer->arlen; + /* back up to the header of the previous block */ + pbase = base - DLWORDSPER_CELL * ptrailer_np->arlen; + /* check that it is free, but skip free list checks */ checkarrayblock(pbase, T, NIL); + /* remove it from the free list */ deleteblock(pbase); return (arrayblockmerger(pbase, base)); }