Skip to content

Commit 31fcfb3

Browse files
committed
Cleans up linkblock implementation to increase clarity
Procedure can be static as it is only used within this file Uses consistent naming (_np) for native pointer equivalents of Lisp addresses, and better matches Lisp implementation naming of variables. Improve readability by reducing if/else nesting with early outs in exceptional cases. Still equivalent to the original Lisp version. Adds comments with a little explanation of what the code is doing.
1 parent 1f18779 commit 31fcfb3

File tree

2 files changed

+45
-27
lines changed

2 files changed

+45
-27
lines changed

inc/gcfinaldefs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
void printarrayblock(LispPTR base);
55
LispPTR releasingvmempage(LispPTR ptr);
66
LispPTR checkarrayblock(LispPTR base, LispPTR free, LispPTR onfreelist);
7-
LispPTR linkblock(LispPTR base);
87
LispPTR makefreearrayblock(LispPTR block, DLword length);
98
LispPTR arrayblockmerger(LispPTR base, LispPTR nbase);
109
LispPTR mergebackward(LispPTR base);

src/gcfinal.c

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -284,34 +284,53 @@ static void deleteblock(LispPTR base) {
284284
/* */
285285
/* */
286286
/************************************************************************/
287+
/*
288+
* Links a block onto the free list for a particular size range.
289+
* The free list is maintained as a doubly linked circular list accessed
290+
* from the block pointed to by the free list bucket for the size.
291+
* If there are no blocks in the free list bucket then the forward and
292+
* backward pointers of the newly added block point to the block itself.
293+
*/
294+
static LispPTR linkblock(LispPTR base) {
295+
struct arrayblock *base_np, *freeblock_np, *tail_np;
296+
LispPTR fbl, freeblock;
297+
LispPTR *fbl_np;
287298

288-
LispPTR linkblock(LispPTR base) {
289-
struct arrayblock *bbase, *fbbase, *tmpbase;
290-
LispPTR fbl, freeblocklsp;
291-
LispPTR *freeblock;
292-
if (*FreeBlockBuckets_word != NIL) {
293-
bbase = (struct arrayblock *)NativeAligned4FromLAddr(base);
294-
if (bbase->arlen < MINARRAYBLOCKSIZE)
295-
checkarrayblock(base, T, NIL);
296-
else {
297-
fbl = FreeBlockChainN(bbase->arlen);
298-
freeblock = (LispPTR *)NativeAligned4FromLAddr(POINTERMASK & fbl);
299-
freeblocklsp = POINTERMASK & (*freeblock);
300-
if (freeblocklsp == NIL) {
301-
bbase->fwd = base;
302-
bbase->bkwd = base;
303-
} else {
304-
fbbase = (struct arrayblock *)NativeAligned4FromLAddr(freeblocklsp);
305-
bbase->fwd = freeblocklsp;
306-
bbase->bkwd = fbbase->bkwd;
307-
tmpbase = (struct arrayblock *)NativeAligned4FromLAddr(fbbase->bkwd);
308-
tmpbase->fwd = base;
309-
fbbase->bkwd = base;
310-
}
311-
*freeblock = base;
312-
checkarrayblock(base, T, T);
313-
}
299+
if (*FreeBlockBuckets_word == NIL)
300+
return (base);
301+
302+
base_np = (struct arrayblock *)NativeAligned4FromLAddr(base);
303+
if (base_np->arlen < MINARRAYBLOCKSIZE) {
304+
checkarrayblock(base, T, NIL);
305+
return (base);
306+
}
307+
308+
/* lisp pointer to bucket for size */
309+
fbl = FreeBlockChainN(base_np->arlen);
310+
/* native pointer to bucket */
311+
fbl_np = (LispPTR *)NativeAligned4FromLAddr(POINTERMASK & fbl);
312+
/* lisp pointer to first free block on chain */
313+
freeblock = POINTERMASK & (*fbl_np);
314+
if (freeblock == NIL) { /* no blocks already in chain */
315+
base_np->fwd = base;
316+
base_np->bkwd = base;
317+
} else {
318+
/* set up new block to be first free block on the chain */
319+
freeblock_np = (struct arrayblock *)NativeAligned4FromLAddr(freeblock);
320+
/* link new block forward to free block */
321+
base_np->fwd = freeblock;
322+
/* new block's backward link becomes free block's backward link */
323+
base_np->bkwd = freeblock_np->bkwd;
324+
/* get the tail location (backward pointer of freelist head) */
325+
tail_np = (struct arrayblock *)NativeAligned4FromLAddr(freeblock_np->bkwd);
326+
/* set its forward pointer to new block */
327+
tail_np->fwd = base;
328+
/* and the update the free block's backward link to new block */
329+
freeblock_np->bkwd = base;
314330
}
331+
/* new block becomes the head of the free list */
332+
*fbl_np = base;
333+
checkarrayblock(base, T, T); /* free, and on free list */
315334
return (base);
316335
}
317336

0 commit comments

Comments
 (0)