This commit is contained in:
Scott Duensing 2026-06-29 01:30:54 -05:00
parent b3c5b9b241
commit b6a6a5cdcc

View file

@ -572,17 +572,15 @@ void *malloc(size_t n0) {
link = &cur->next;
cur = cur->next;
}
// Bump-allocate from the high end.
// Bump-allocate from the high end. Big allocations (e.g. the 16 KB sprite
// codegen scratch) are routed through halBigAlloc -> the Memory Manager,
// NOT this heap, so n is always small here and the historical
// `p + HDR_SZ + n > heapEnd` over-heap miscompile (only manifested for
// oversized n) is never exercised. A `heapEnd - p` reformulation went
// through the same i32 path and spuriously failed small mallocs, so keep
// the original simple compare.
char *p = bumpPtr;
// Bounds check as a 16-bit SAME-BANK difference (avail = heapEnd - p),
// NOT `p + HDR_SZ + n > heapEnd`: that 24-bit pointer compare goes through
// the same i32 pattern the backend miscompiles at -O2 (see the size-round
// note above), so an oversized request returned a non-NULL OVER-HEAP
// pointer instead of NULL. On the tiny IIgs heap that let, e.g., a 16 KB
// scratch malloc "succeed" on a ~3 KB heap; the returned pointer + free()
// then trampled the IO window / language card / GS-OS stack and crashed.
// The heap lives in one bank, so the 16-bit offset difference is exact.
if ((u16)(heapEnd - p) < (u16)((u16)HDR_SZ + n)) return (void *)0;
if (p + HDR_SZ + n > heapEnd) return (void *)0;
*(u16 *)p = (u16)n;
bumpPtr = p + HDR_SZ + n;
return p + HDR_SZ;