diff --git a/src/builtins/slash.c b/src/builtins/slash.c index 10dad7d5..fc689137 100644 --- a/src/builtins/slash.c +++ b/src/builtins/slash.c @@ -215,7 +215,7 @@ static void bsp_block_u32(u64* src, u32* dst, usz len, usz sum, usz off) { static void bsp_u16(u64* src, u16* dst, usz len, usz sum) { usz b = bsp_max; usz bufsize = b len-i) b = len-i; diff --git a/src/builtins/sortTemplate.h b/src/builtins/sortTemplate.h index 1d435385..16ff4072 100644 --- a/src/builtins/sortTemplate.h +++ b/src/builtins/sortTemplate.h @@ -259,13 +259,14 @@ typedef struct { SORT_TYPE *storage; } TEMP_STORAGE_T; -static void TIM_SORT_RESIZE(TEMP_STORAGE_T *store, const size_t new_size) { +static void TIM_SORT_RESIZE(TEMP_STORAGE_T *store, size_t new_size) { + new_size*= 2; if (store->storage == NULL) { store->storage = TALLOCP(SORT_TYPE, new_size); } else if (store->alloc < new_size) { store->storage = (SORT_TYPE *)TREALLOC(store->storage, new_size * sizeof(SORT_TYPE)); } else return; - store->alloc = TSIZE(store->storage)/sizeof(SORT_TYPE); + store->alloc = new_size; } static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const int stack_curr, diff --git a/src/core/stuff.c b/src/core/stuff.c index 05145d05..778aeb32 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -83,7 +83,7 @@ B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec, bi_emptySVec; NOINLINE TStack* ts_e(TStack* o, u32 elsz, u64 am) { u64 size = o->size; u64 alsz = mm_round(fsizeof(TStack, data, u8, (size+am)*elsz)); TStack* n; - if (alsz==mm_size((Value*)o)) { + if (alsz==mm_sizeUsable((Value*)o)) { n = o; } else { n = (TStack*)mm_alloc(alsz, t_temp); @@ -91,7 +91,7 @@ NOINLINE TStack* ts_e(TStack* o, u32 elsz, u64 am) { u64 size = o->size; mm_free((Value*)o); n->size = size; } - n->cap = (mm_size((Value*)n)-offsetof(TStack,data))/elsz; + n->cap = (mm_sizeUsable((Value*)n)-offsetof(TStack,data))/elsz; return n; } diff --git a/src/h.h b/src/h.h index 2d21ffa8..6f5aa9c8 100644 --- a/src/h.h +++ b/src/h.h @@ -255,10 +255,10 @@ typedef union B { /*31*/ F(bitarr) \ \ /*32*/ F(comp) F(block) F(body) F(scope) F(scopeExt) F(blBlocks) F(arbObj) F(ffiType) \ - /*40*/ F(ns) F(nsDesc) F(fldAlias) F(arrMerge) F(vfyObj) F(hashmap) F(temp) F(nfn) F(nfnDesc) \ - /*49*/ F(freed) F(harrPartial) F(customObj) F(mmapH) \ + /*40*/ F(ns) F(nsDesc) F(fldAlias) F(arrMerge) F(vfyObj) F(hashmap) F(temp) F(talloc) F(nfn) F(nfnDesc) \ + /*50*/ F(freed) F(harrPartial) F(customObj) F(mmapH) \ \ - /*52*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap)) + /*53*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap)) enum Type { #define F(X) t_##X, @@ -354,9 +354,12 @@ extern B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec, bi_emptySVec; #define emptySVec() incG(bi_emptySVec) ALLOC_FN void* mm_alloc(u64 sz, u8 type); ALLOC_FN void mm_free(Value* x); -static u64 mm_size(Value* x); static void mm_visit(B x); static void mm_visitP(void* x); +static u64 mm_size(Value* x); +#if !VERIFY_TAIL +#define mm_sizeUsable mm_size +#endif static void dec(B x); static B inc(B x); static void ptr_dec(void* x); diff --git a/src/load.c b/src/load.c index d9a9881e..33787045 100644 --- a/src/load.c +++ b/src/load.c @@ -706,6 +706,7 @@ void base_init() { // very first init function #endif TIi(t_shape,visit) = noop_visit; TIi(t_temp,visit) = noop_visit; + TIi(t_talloc,visit) = noop_visit; TIi(t_funBI,visit) = TIi(t_md1BI,visit) = TIi(t_md2BI,visit) = noop_visit; TIi(t_funBI,freeO) = TIi(t_md1BI,freeO) = TIi(t_md2BI,freeO) = builtin_free; TIi(t_funBI,freeF) = TIi(t_md1BI,freeF) = TIi(t_md2BI,freeF) = builtin_free; diff --git a/src/opt/gc.c b/src/opt/gc.c index 6dda6768..42b14980 100644 --- a/src/opt/gc.c +++ b/src/opt/gc.c @@ -39,7 +39,7 @@ static void gc_tryFree(Value* v) { if (t==t_freed) err("GC found t_freed\n"); #endif if (t!=t_empty && !(v->mmInfo&0x80)) { - if (t==t_shape || t==t_temp) return; + if (t==t_shape || t==t_temp || t==t_talloc) return; #ifdef DONT_FREE v->flags = t; #else diff --git a/src/opt/mm_buddy.c b/src/opt/mm_buddy.c index eacc8165..c0e3e0e2 100644 --- a/src/opt/mm_buddy.c +++ b/src/opt/mm_buddy.c @@ -25,6 +25,7 @@ u64 mm_heapUsed() { #undef BSZ #if VERIFY_TAIL +#include "../utils/talloc.h" FORCE_INLINE u64 ptrHash(void* ptr, usz off) { u64 pv = ptr2u64(ptr) ^ off; pv*= 0xa0761d6478bd642full; @@ -57,8 +58,8 @@ static void tailVerifyInit(void* ptr, u64 filled, u64 end, u64 allocEnd) { } void tailVerifyAlloc(void* ptr, u64 filled, i64 logAlloc, u8 type) { u64 end = 1ULL<sz) { printf("Bad used range: "N64u".."N64u", allocation size "N64u"\n", start, end, sz); exit(1); } @@ -100,6 +101,7 @@ NOINLINE NORETURN void tailFail(u64 got, u64 exp, void* ptr, u64 off, int len, u } void tailVerifyFree(void* ptr) { u64 filled; u64 ia; Arr* xa = ptr; + u64 end = mm_size(ptr); switch(PTY(xa)) { default: return; case t_bitarr: filled = BITARR_SZ(ia=PIA(xa)); break; case t_i8arr: filled = TYARR_SZ(I8, ia=PIA(xa)); break; @@ -108,8 +110,8 @@ void tailVerifyFree(void* ptr) { case t_f64arr: filled = TYARR_SZ(F64, ia=PIA(xa)); break; case t_harr: filled = fsizeof(HArr,a,B,ia=PIA(xa)); break; case t_fillarr: filled = fsizeof(FillArr,a,B,ia=PIA(xa)); break; + case t_talloc: filled = ia = *(u64*)((u8*)ptr + end - 8); end-= 8; break; } - u64 end = mm_size(ptr); verifyEnd(ptr, end, 8, filled); #define F(G, X, O, L) if ((G) != (X)) tailFail(G, X, ptr, O, L, filled, end, ia) ITER_TAIL(F) diff --git a/src/opt/mm_buddy.h b/src/opt/mm_buddy.h index 15453b8b..6ae248eb 100644 --- a/src/opt/mm_buddy.h +++ b/src/opt/mm_buddy.h @@ -43,6 +43,11 @@ static u64 mm_round(usz sz) { static u64 mm_size(Value* x) { return BSZ(x->mmInfo&63); } +#if VERIFY_TAIL +static u64 mm_sizeUsable(Value* x) { + return mm_size(x) - VERIFY_TAIL; +} +#endif void mm_forHeap(V2v f); void mm_dumpHeap(FILE* f); diff --git a/src/utils/mut.h b/src/utils/mut.h index b963efe7..a826432e 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -166,10 +166,7 @@ FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) { usz xia = IA(x); u64 ria = wia+xia; if (!reusable(w)) goto no; - u64 wsz = mm_size(v(w)); - #if VERIFY_TAIL - wsz-= VERIFY_TAIL; - #endif + u64 wsz = mm_sizeUsable(v(w)); u8 wt = TY(w); u8 we = TI(w, elType); // TODO f64∾i32, i32∾i8, c32∾c8 etc @@ -206,10 +203,7 @@ static inline bool inplace_add(B w, B x) { // consumes x if returns true; fails usz wia = IA(w); usz ria = wia+1; if (reusable(w)) { - u64 wsz = mm_size(v(w)); - #if VERIFY_TAIL - wsz-= VERIFY_TAIL; - #endif + u64 wsz = mm_sizeUsable(v(w)); u8 wt = TY(w); switch (wt) { case t_bitarr: if (BITARR_SZ( ria)data) // +8 so mm is happy +#define TALLOCP(T,AM) ((T*) ((TAlloc*)mm_alloc(TOFF + (AM)*sizeof(T) + 8, t_talloc))->data) // +8 so mm is happy #define TALLOC(T,N,AM) T* N = TALLOCP(T,AM); #define TOBJ(N) (void*)((u8*)(N) - TOFF) #define TFREE(N) mm_free((Value*)TOBJ(N)); #define TREALLOC(N, AM) talloc_realloc(TOBJ(N), AM) -#define TSIZE(N) (mm_size(TOBJ(N))-TOFF) +#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_size((Value*)t)-TOFF; + u64 stored = mm_sizeUsable((Value*)t)-TOFF; if (stored > am) return t->data; TALLOC(u8,r,am); memcpy(r, t->data, stored);