From a6fd0ed320f13516dfb0b7065d58216a99760b17 Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Thu, 13 Feb 2025 08:22:28 +0000 Subject: [PATCH] DBtiles.c: DBFreePaintPlane() remove the TiFree() deferred assumption The comment indicates the expectation that TiFree() is deferred-by-one, which would be true if freeMalloc() was used but since the custom mmap() allocator technically this is not true. The TiFree() allocator is single-threaded and separate from libc so the assumption is still kind of true but for different reasons (single-threaded). But since it doesn't really cost anything (other than a few lines of code a human needs to read) the compiler would be expected to perform a load (which it was going to do anyway) into a caller-saves register over the function call. Most of the other function state is invalidated anyway due to the heavy linked-list navigation and low number of local variables, I would not think there is much register allocation pressure. TODO this code can be tested by confirming zero allocations are active and by invalidating (poison) all fields inside TiFree(). --- database/DBtiles.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/database/DBtiles.c b/database/DBtiles.c index c68610a1..52782410 100644 --- a/database/DBtiles.c +++ b/database/DBtiles.c @@ -723,9 +723,7 @@ enumerate: * * This procedure uses a carfully constructed non-recursive area * enumeration algorithm. Care is taken to not access a tile that has - * been deallocated. The only exception is for a tile that has just been - * passed to free(), but no more calls to free() or malloc() have been made. - * Magic's malloc allows this. + * been deallocated. * * -------------------------------------------------------------------- */ @@ -740,6 +738,7 @@ DBFreePaintPlane(plane) /* Start with the bottom-right non-infinity tile in the plane */ tp = BL(plane->pl_right); + Tile *delayed = NULL; /* Each iteration visits another tile on the RHS of the search area */ while (BOTTOM(tp) < rect->r_ytop) { @@ -762,9 +761,9 @@ enumerate: /* Each iteration returns one tile further to the right */ while (RIGHT(tp) < rect->r_xtop) { - TiFree(tp); - tpnew = RT(tp); - tp = TR(tp); + TiFree1(&delayed, tp); + tpnew = RT(tp); /* deref of delayed */ + tp = TR(tp); /* deref of delayed */ if (CLIP_TOP(tpnew) <= CLIP_TOP(tp) && BOTTOM(tpnew) < rect->r_ytop) { tp = tpnew; @@ -772,13 +771,14 @@ enumerate: } } - TiFree(tp); + TiFree1(&delayed, tp); /* At right edge -- walk up to next tile along the right edge */ - tp = RT(tp); + tp = RT(tp); /* deref of delayed */ if (BOTTOM(tp) < rect->r_ytop) { while(LEFT(tp) >= rect->r_xtop) tp = BL(tp); } } + TiFreeIf(delayed); } /*