diff --git a/src/core/stuff.h b/src/core/stuff.h index 4c46c076..1efd859a 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -417,6 +417,7 @@ FORCE_INLINE void preAlloc(usz sz, u8 type) { #if VERIFY_TAIL void tailVerifyAlloc(void* ptr, u64 origSz, ux logAlloc, u8 type); void tailVerifyFree(void* ptr); +void tailVerifySetMinTallocSize(void* ptr, u64 bytes); void tailVerifyReinit(void* ptr, u64 s, u64 e); #define FINISH_OVERALLOC(P, S, E) tailVerifyReinit(P, S, E) NOINLINE void reinit_portion(Arr* a, usz s, usz e); diff --git a/src/opt/mm_buddy.c b/src/opt/mm_buddy.c index 4c218142..cf43fb53 100644 --- a/src/opt/mm_buddy.c +++ b/src/opt/mm_buddy.c @@ -47,6 +47,19 @@ FORCE_INLINE u64 limitLen(u64 l) { } \ } +static u64* tallocSizePtr(void* ptr, u64 end) { + return (u64*)((u8*)ptr + end - 8); +} +void tailVerifySetMinTallocSize(void* ptr, u64 bytes) { + u64 end = mm_size(ptr); + if (bytes >= mm_sizeUsable(ptr)) { + printf("Bad tailVerifySetMinTallocSize: setting to "N64u" bytes, "N64u" available\n", bytes, mm_sizeUsable(ptr)); + __builtin_trap(); + } + u64 prev = *tallocSizePtr(ptr, end); + if (prev > bytes) return; + *tallocSizePtr(ptr, end) = bytes; +} static void tailVerifyInit(void* ptr, u64 filled, u64 end, u64 allocEnd) { #define F(W, X, O, L) W = X ITER_TAIL(F) @@ -55,7 +68,7 @@ static void tailVerifyInit(void* ptr, u64 filled, u64 end, u64 allocEnd) { void tailVerifyAlloc(void* ptr, u64 filled, ux logAlloc, u8 type) { u64 end = 1ULL< sz) { diff --git a/src/utils/talloc.h b/src/utils/talloc.h index 17478b92..f6815ec8 100644 --- a/src/utils/talloc.h +++ b/src/utils/talloc.h @@ -13,7 +13,12 @@ typedef struct TAlloc { #define TSIZE(N) (mm_sizeUsable(TOBJ(N))-TOFF) static inline void* talloc_realloc(TAlloc* t, u64 am) { // TODO maybe shouldn't be inline? u64 stored = mm_sizeUsable((Value*)t)-TOFF; - if (stored > am) return t->data; + if (stored > am) { + #if VERIFY_TAIL + tailVerifySetMinTallocSize(t, am); + #endif + return t->data; + } TALLOC(u8,r,am); memcpy(r, t->data, stored); mm_free((Value*)t);