From 2d43489cd260d79ddea5fef7923eb7d055b0909f Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 14 Apr 2021 23:12:59 +0300 Subject: [PATCH] more refcount fixes --- src/c32arr.c | 4 +-- src/fillarr.c | 4 +-- src/h.h | 74 +++++++++++++++++++++++++-------------------------- src/harr.c | 4 +-- src/heap.c | 54 ++++++++++++++++++++++++------------- src/i32arr.c | 4 +-- src/main.c | 12 ++++----- src/sfns.c | 2 +- src/sysfn.c | 6 ++--- 9 files changed, 89 insertions(+), 75 deletions(-) diff --git a/src/c32arr.c b/src/c32arr.c index 2092993f..a056fc8b 100644 --- a/src/c32arr.c +++ b/src/c32arr.c @@ -46,8 +46,8 @@ B m_c32slice(B p, u32* ptr) { return tag(r, ARR_TAG); } -B c32arr_slice (B x, usz s) {return m_c32slice(x , c(C32Arr ,x)->a+s); } -B c32slice_slice(B x, usz s) { B r = m_c32slice(inc(c(C32Slice,x)->p), c(C32Slice,x)->a+s); dec(x); return r; } +B c32arr_slice (B x, usz s) {return m_c32slice(x , c(C32Arr ,x)->a+s); } +B c32slice_slice(B x, usz s) { B r = m_c32slice(inc(c(Slice,x)->p), c(C32Slice,x)->a+s); dec(x); return r; } B c32arr_get (B x, usz n) { VT(x,t_c32arr ); return m_c32(c(C32Arr ,x)->a[n]); } diff --git a/src/fillarr.c b/src/fillarr.c index ed9248c7..7e4e5732 100644 --- a/src/fillarr.c +++ b/src/fillarr.c @@ -50,8 +50,8 @@ B m_fillslice(B p, B* ptr) { } B* fillarr_ptr(B x) { VT(x,t_fillarr); return c(FillArr,x)->a; } -B fillarr_slice (B x, usz s) {return m_fillslice(x , c(FillArr ,x)->a+s); } -B fillslice_slice(B x, usz s) { B r = m_fillslice(inc(c(FillSlice,x)->p), c(FillSlice,x)->a+s); dec(x); return r; } +B fillarr_slice (B x, usz s) {return m_fillslice(x , c(FillArr ,x)->a+s); } +B fillslice_slice(B x, usz s) { B r = m_fillslice(inc(c(Slice,x)->p), c(FillSlice,x)->a+s); dec(x); return r; } B fillarr_get (B x, usz n) { VT(x,t_fillarr ); return inc(c(FillArr ,x)->a[n]); } diff --git a/src/h.h b/src/h.h index f5c44bb6..0921dbd4 100644 --- a/src/h.h +++ b/src/h.h @@ -31,10 +31,12 @@ CTR_FOR(CTR_DEF) #ifdef DEBUG #include - #define VALIDATE(x) validate(x) // preferred validating level + #define VALIDATE(x) validate(x) + #define VALIDATEP(x) validateP(x) #else #define assert(x) {if (!(x)) __builtin_unreachable();} #define VALIDATE(x) (x) + #define VALIDATEP(x) (x) #endif #define fsizeof(T,F,E,n) (offsetof(T, F) + sizeof(E)*(n)) // type; FAM name; FAM type; amount @@ -71,7 +73,7 @@ enum Type { /*21*/ t_comp, t_block, t_body, t_scope, /*25*/ t_freed, - Type_MAX + t_COUNT }; char* format_type(u8 u) { switch(u) { default: return"(unknown type)"; @@ -207,10 +209,7 @@ B m_v4(B a, B b, B c, B d); void print_vmStack(); #ifdef DEBUG B validate(B x); - B recvalidate(B x); -#else - #define validate(x) (x) - #define recvalidate(x) (x) + Value* validateP(Value* x); #endif B err(char* s) { puts(s); fflush(stdout); @@ -254,10 +253,11 @@ void arr_shVec(B x, usz ia) { srnk(x, 1); a(x)->sh = &a(x)->ia; } +bool gotShape[t_COUNT]; usz* arr_shAlloc(B x, usz ia, usz r) { a(x)->ia = ia; srnk(x,r); - if (r>1) return a(x)->sh = c(ShArr,mm_alloc(fsizeof(ShArr, a, usz, r), t_shape, ftag(OBJ_TAG)))->a; + if (r>1) return a(x)->sh = ((ShArr*)mm_allocN(fsizeof(ShArr, a, usz, r), t_shape))->a; a(x)->sh = &a(x)->ia; return 0; } @@ -268,8 +268,8 @@ void arr_shCopy(B n, B o) { // copy shape from o to n if (r<=1) { a(n)->sh = &a(n)->ia; } else { - a(n)->sh = a(o)->sh; ptr_inc(shObj(o)); + a(n)->sh = a(o)->sh; } } bool shEq(B w, B x) { assert(isArr(w)); assert(isArr(x)); @@ -341,7 +341,7 @@ typedef struct TypeInfo { B2B decompose; // consumes; must return a HArr bool isArr; } TypeInfo; -TypeInfo ti[Type_MAX]; +TypeInfo ti[t_COUNT]; #define TI(x) (ti[v(x)->type]) @@ -349,6 +349,7 @@ void do_nothing(B x) { } void empty_free(B x) { err("FREEING EMPTY\n"); } void builtin_free(B x) { err("FREEING BUILTIN\n"); } void def_visit(B x) { printf("(no visit for %d=%s)\n", v(x)->type, format_type(v(x)->type)); } +void freeed_visit(B x) { err("visiting t_freed\n"); } void def_print(B x) { printf("(%d=%s)", v(x)->type, format_type(v(x)->type)); } B def_get (B x, usz n) { return inc(x); } B def_getU(B x, usz n) { return x; } @@ -359,7 +360,7 @@ B def_decompose(B x) { return m_v2(m_i32((isFun(x)|isMd(x))? 0 : -1),x); } bool def_canStore(B x) { return false; } B bi_nothing, bi_noVar, bi_badHdr, bi_optOut, bi_noFill; void hdr_init() { - for (i32 i = 0; i < Type_MAX; i++) { + for (i32 i = 0; i < t_COUNT; i++) { ti[i].free = do_nothing; ti[i].visit = def_visit; ti[i].get = def_get; @@ -374,6 +375,7 @@ void hdr_init() { } ti[t_empty].free = empty_free; ti[t_freed].free = do_nothing; + ti[t_freed].visit = freeed_visit; ti[t_shape].visit = do_nothing; ti[t_fun_def].visit = ti[t_md1_def].visit = ti[t_md2_def].visit = do_nothing; ti[t_fun_def].free = ti[t_md1_def].free = ti[t_md2_def].free = builtin_free; @@ -404,11 +406,11 @@ B inc(B x) { if (isVal(VALIDATE(x))) v(x)->refc++; return x; } -void ptr_dec(void* x) { if(!--((Value*)x)->refc) value_free(tag(x, OBJ_TAG), x); } -void ptr_inc(void* x) { ((Value*)x)->refc++; } -void ptr_decR(void* x) { if(!--((Value*)x)->refc) value_freeR1(x); } +void ptr_dec(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_free(tag(x, OBJ_TAG), x); } +void ptr_inc(void* x) { VALIDATEP((Value*)x)->refc++; } +void ptr_decR(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_freeR1(x); } void decR(B x) { - if (!isVal(x)) return; + if (!isVal(VALIDATE(x))) return; Value* vx = v(x); if(!--vx->refc) value_freeR2(vx, x); } @@ -572,31 +574,26 @@ u64 nsTime() { } #ifdef DEBUG - B validate(B x) { - if (!isVal(x)) return x; - if (v(x)->refc<=0 || (v(x)->refc>>28) == 'a') { - printf("bad refcount for type %d: %d; val=%p\nattempting to print: ", v(x)->type, v(x)->refc, (void*)x.u); fflush(stdout); - print(x); puts(""); fflush(stdout); + Value* validateP(Value* x) { + if (x->refc<=0 || (x->refc>>28) == 'a' || x->type==t_empty) { + printf("bad refcount for type %d: %d\nattempting to print: ", x->type, x->refc); fflush(stdout); + print(tag(x,OBJ_TAG)); puts(""); fflush(stdout); err(""); } - if (isArr(x) && v(x)->type!=t_freed) { - ur r = rnk(x); - if (r<=1) assert(a(x)->sh == &a(x)->ia); - else validate(tag(shObj(x),OBJ_TAG)); + if (ti[x->type].isArr) { + Arr* a = (Arr*)x; + if (rnk(tag(x,ARR_TAG))<=1) assert(a->sh == &a->ia); + else validate(tag(shObj(tag(x,ARR_TAG)),OBJ_TAG)); } return x; } - B recvalidate(B x) { - validate(x); - if (isArr(x)) { - BS2B xget = TI(x).get; - usz ia = a(x)->ia; - for (usz i = 0; i < ia; i++) { - B c = xget(x,i); - assert(c.u!=x.u); - recvalidate(c); - dec(c); - } + B validate(B x) { + if (!isVal(x)) return x; + validateP(v(x)); + if(isArr(x)!=TI(x).isArr && v(x)->type!=t_freed) { + printf("wat %d %p\n", v(x)->type, (void*)x.u); + print(x); + err("\nk"); } return x; } @@ -617,12 +614,12 @@ static inline void onAlloc(usz sz, u8 type) { if (!ctr_a) { #ifdef ALLOC_SIZES actrs = malloc(sizeof(u32*)*actrc); - for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(Type_MAX, sizeof(u32)); + for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(t_COUNT, sizeof(u32)); #endif - ctr_a = calloc(Type_MAX, sizeof(u64)); - ctr_f = calloc(Type_MAX, sizeof(u64)); + ctr_a = calloc(t_COUNT, sizeof(u64)); + ctr_f = calloc(t_COUNT, sizeof(u64)); } - assert(type=actrc? actrc-1 : (sz+3)/4][type]++; #endif @@ -635,6 +632,7 @@ static inline void onFree(Value* x) { ctr_f[x->type]++; #endif #ifdef DEBUG + if (x->type==t_empty) err("double-free"); // u32 undef; // x->refc = undef; x->refc = -1431655000; diff --git a/src/harr.c b/src/harr.c index b5af3db4..86b2875d 100644 --- a/src/harr.c +++ b/src/harr.c @@ -77,8 +77,8 @@ B m_hslice(B p, B* ptr) { return tag(r, ARR_TAG); } -B harr_slice (B x, usz s) {return m_hslice(x , c(HArr ,x)->a+s); } -B hslice_slice(B x, usz s) { B r = m_hslice(inc(c(HSlice,x)->p), c(HSlice,x)->a+s); dec(x); return r; } +B harr_slice (B x, usz s) {return m_hslice(x , c(HArr ,x)->a+s); } +B hslice_slice(B x, usz s) { B r = m_hslice(inc(c(Slice,x)->p), c(HSlice,x)->a+s); dec(x); return r; } B harr_get (B x, usz n) { VT(x,t_harr ); return inc(c(HArr ,x)->a[n]); } diff --git a/src/heap.c b/src/heap.c index 0d357f4f..966fe6db 100644 --- a/src/heap.c +++ b/src/heap.c @@ -1,6 +1,3 @@ -u32 heapVerify_mode = -1; - - u64 heapUsed_ctr; void heapUsedFn(Value* p) { heapUsed_ctr+= mm_size(p); } u64 mm_heapUsed() { @@ -10,30 +7,25 @@ u64 mm_heapUsed() { } -void heap_checkFn(Value* v) { + +#ifdef HEAP_VERIFY +u32 heapVerify_mode = -1; + +Value* heap_observed; +Value* heap_curr; +void heapVerify_checkFn(Value* v) { if (v->refc!=0) { #ifdef OBJ_COUNTER printf("delta %d for %s, uid %ld: ", v->refc, format_type(v->type), v->uid); #else printf("delta %d for %s: ", (i32)v->refc, format_type(v->type)); #endif + heap_observed = v; print(tag(v,OBJ_TAG)); puts(""); } } -void heap_callVisit(Value* v) { - ti[v->type].visit(tag(v,OBJ_TAG)); -} -void heapVerify() { - #ifndef HEAP_VERIFY - err("heapVerify() HEAP_VERIFY to be defined"); - #endif - heapVerify_mode=0; mm_forHeap(heap_callVisit); gc_visitRoots(); - mm_forHeap(heap_checkFn); - heapVerify_mode=1; mm_forHeap(heap_callVisit); gc_visitRoots(); - heapVerify_mode=-1; -} -#ifdef HEAP_VERIFY + bool heapVerify_visit(B x) { if (heapVerify_mode==-1) return false; if (isVal(x)) mm_visitP(v(x)); @@ -42,8 +34,32 @@ bool heapVerify_visit(B x) { bool heapVerify_visitP(void* x) { if(heapVerify_mode==-1) return false; Value* v = x; - if(heapVerify_mode==0) { v->refc--; if(ti[v->type].isArr && rnk(tag(v,OBJ_TAG))>1)heapVerify_visitP(shObj(tag(v,OBJ_TAG))); } - if(heapVerify_mode==1) { v->refc++; if(ti[v->type].isArr && rnk(tag(v,OBJ_TAG))>1)heapVerify_visitP(shObj(tag(v,OBJ_TAG))); } + if(heapVerify_mode==0) v->refc--; + else if(heapVerify_mode==1) v->refc++; + else if(heapVerify_mode==2) if (x==heap_observed) { printf("referee: %p ", heap_curr); print(tag(heap_curr,OBJ_TAG)); puts(""); } return true; } + +void heapVerify_callVisit(Value* v) { + if (ti[v->type].isArr && rnk(tag(v,ARR_TAG))>1) heapVerify_visitP(shObj(tag(v,ARR_TAG))); + ti[v->type].visit(tag(v,OBJ_TAG)); +} + +void heap_getReferents(Value* v) { + heap_curr = v; + if (ti[v->type].isArr && rnk(tag(v,ARR_TAG))>1) heapVerify_visitP(shObj(tag(v,ARR_TAG))); + ti[v->type].visit(tag(v,OBJ_TAG)); +} +void heapVerify() { + heap_observed = 0; + heapVerify_mode=0; mm_forHeap(heapVerify_callVisit); gc_visitRoots(); + mm_forHeap(heapVerify_checkFn); + heapVerify_mode=1; mm_forHeap(heapVerify_callVisit); gc_visitRoots(); + if (heap_observed) { + printf("refc of last: %d\n", heap_observed->refc); + heapVerify_mode=2; mm_forHeap(heap_getReferents); + } + heapVerify_mode=-1; +} + #endif \ No newline at end of file diff --git a/src/i32arr.c b/src/i32arr.c index 784d7992..ed229880 100644 --- a/src/i32arr.c +++ b/src/i32arr.c @@ -54,8 +54,8 @@ B m_i32slice(B p, i32* ptr) { return tag(r, ARR_TAG); } -B i32arr_slice (B x, usz s) {return m_i32slice(x , c(I32Arr ,x)->a+s); } -B i32slice_slice(B x, usz s) { B r = m_i32slice(inc(c(I32Slice,x)->p), c(I32Slice,x)->a+s); dec(x); return r; } +B i32arr_slice (B x, usz s) {return m_i32slice(x , c(I32Arr ,x)->a+s); } +B i32slice_slice(B x, usz s) { B r = m_i32slice(inc(c(Slice,x)->p), c(I32Slice,x)->a+s); dec(x); return r; } B i32arr_get (B x, usz n) { VT(x,t_i32arr ); return m_i32(c(I32Arr ,x)->a[n]); } diff --git a/src/main.c b/src/main.c index 2d9bd371..5ffff577 100644 --- a/src/main.c +++ b/src/main.c @@ -54,19 +54,19 @@ void printAllocStats() { printf("total ever allocated: %lu\n", talloc); printf("allocated heap size: %ld\n", mm_heapAllocated()); printf("used heap size: %ld\n", mm_heapUsed()); - printf("ctrA←"); for (i64 i = 0; i < Type_MAX; i++) { if(i)printf("‿"); printf("%lu", ctr_a[i]); } printf("\n"); - printf("ctrF←"); for (i64 i = 0; i < Type_MAX; i++) { if(i)printf("‿"); printf("%lu", ctr_f[i]); } printf("\n"); + printf("ctrA←"); for (i64 i = 0; i < t_COUNT; i++) { if(i)printf("‿"); printf("%lu", ctr_a[i]); } printf("\n"); + printf("ctrF←"); for (i64 i = 0; i < t_COUNT; i++) { if(i)printf("‿"); printf("%lu", ctr_f[i]); } printf("\n"); u64 leakedCount = 0; - for (i64 i = 0; i < Type_MAX; i++) leakedCount+= ctr_a[i]-ctr_f[i]; + for (i64 i = 0; i < t_COUNT; i++) leakedCount+= ctr_a[i]-ctr_f[i]; printf("leaked object count: %ld\n", leakedCount); #ifdef ALLOC_SIZES for(i64 i = 0; i < actrc; i++) { u32* c = actrs[i]; bool any = false; - for (i64 j = 0; j < Type_MAX; j++) if (c[j]) any=true; + for (i64 j = 0; j < t_COUNT; j++) if (c[j]) any=true; if (any) { printf("%ld", i*4); - for (i64 k = 0; k < Type_MAX; k++) printf("‿%u", c[k]); + for (i64 k = 0; k < t_COUNT; k++) printf("‿%u", c[k]); printf("\n"); } } @@ -117,7 +117,7 @@ int main() { dec(c1(rtFinish, m_v2(inc(bi_decp), inc(bi_primInd)))); dec(rtFinish); - B compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, inc(bi_sys)); dec(FAKE_RUNTIME? rtObj : frtObj); + B compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, inc(bi_sys)); gc_add(FAKE_RUNTIME? rtObj : frtObj); gc_add(compArg); diff --git a/src/sfns.c b/src/sfns.c index fe4e8b65..3201f3a7 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -23,7 +23,7 @@ B shape_c2(B t, B w, B x) { if (reusable(x)) { r = x; decSh(x); } else r = TI(x).slice(x, 0); usz* sh = arr_shAlloc(r, nia, nr); - if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2i(wget(w,i)); + if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i)); dec(w); return r; } else return err("reshaping non-array"); diff --git a/src/sysfn.c b/src/sysfn.c index 9519bc77..0d80ac06 100644 --- a/src/sysfn.c +++ b/src/sysfn.c @@ -86,7 +86,7 @@ B grOrd_c2(B t, B w, B x) { usz wia = a(w)->ia; usz xia = a(x)->ia; if (wia==0) { dec(w); dec(x); return c1(bi_ud, m_i32(0)); } - if (xia==0) { dec(w); dec(x); return x; } + if (xia==0) { dec(w); return x; } BS2B wget = TI(w).get; BS2B xget = TI(x).get; usz tmp[wia]; @@ -145,9 +145,9 @@ void sysfn_init() { bm(type) bm(decp) bm(primInd) bm(glyph) ba(fill) ba(grLen) b B sys_c1(B t, B x) { assert(isArr(x)); HArr_p r = m_harrc(x); - BS2B xget = TI(x).get; + BS2B xgetU = TI(x).getU; for (usz i = 0; i < a(x)->ia; i++) { - B c = xget(x,i); + B c = xgetU(x,i); if (eqStr(c, U"internal")) r.a[i] = inc(bi_internal); else if (eqStr(c, U"eq")) r.a[i] = inc(bi_feq); else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp);