free should take pointer as arg

This commit is contained in:
dzaima 2021-05-15 12:09:15 +03:00
parent 5dfa9e0e31
commit fb7bfcf188
13 changed files with 58 additions and 57 deletions

View File

@ -79,7 +79,7 @@ B c32slice_slice(B x, usz s) { B r = m_c32slice(inc(c(Slice,x)->p), c(C32Slice,x
B c32arr_get (B x, usz n) { VT(x,t_c32arr ); return m_c32(c(C32Arr ,x)->a[n]); } B c32arr_get (B x, usz n) { VT(x,t_c32arr ); return m_c32(c(C32Arr ,x)->a[n]); }
B c32slice_get(B x, usz n) { VT(x,t_c32slice); return m_c32(c(C32Slice,x)->a[n]); } B c32slice_get(B x, usz n) { VT(x,t_c32slice); return m_c32(c(C32Slice,x)->a[n]); }
void c32arr_free(B x) { decSh(x); } void c32arr_free(Value* x) { decSh(x); }
bool c32arr_canStore(B x) { return isC32(x); } bool c32arr_canStore(B x) { return isC32(x); }
static inline void c32arr_init() { static inline void c32arr_init() {

View File

@ -24,11 +24,11 @@ typedef struct Atop {
B g, h; B g, h;
} Atop; } Atop;
void md1D_free(B x) { dec(c(Md1D,x)->m1); dec(c(Md1D,x)->f); } void md1D_free(Value* x) { dec(((Md1D*)x)->m1); dec(((Md1D*)x)->f); }
void md2D_free(B x) { dec(c(Md2D,x)->m2); dec(c(Md2D,x)->f); dec(c(Md2D,x)->g); } void md2D_free(Value* x) { dec(((Md2D*)x)->m2); dec(((Md2D*)x)->f); dec(((Md2D*)x)->g); }
void md2H_free(B x) { dec(c(Md2H,x)->m2); dec(c(Md2H,x)->g); } void md2H_free(Value* x) { dec(((Md2H*)x)->m2); dec(((Md2H*)x)->g); }
void fork_free(B x) { dec(c(Fork,x)->f ); dec(c(Fork,x)->g); dec(c(Fork,x)->h); } void fork_free(Value* x) { dec(((Fork*)x)->f ); dec(((Fork*)x)->g); dec(((Fork*)x)->h); }
void atop_free(B x) { dec(c(Atop,x)->g); dec(c(Atop,x)->h); } void atop_free(Value* x) { dec(((Atop*)x)->g); dec(((Atop*)x)->h); }
void md1D_visit(B x) { mm_visit(c(Md1D,x)->m1); mm_visit(c(Md1D,x)->f); } void md1D_visit(B x) { mm_visit(c(Md1D,x)->m1); mm_visit(c(Md1D,x)->f); }
void md2D_visit(B x) { mm_visit(c(Md2D,x)->m2); mm_visit(c(Md2D,x)->f); mm_visit(c(Md2D,x)->g); } void md2D_visit(B x) { mm_visit(c(Md2D,x)->m2); mm_visit(c(Md2D,x)->f); mm_visit(c(Md2D,x)->g); }

View File

@ -63,7 +63,7 @@ B f64slice_slice(B x, usz s) { B r = m_f64slice(inc(c(Slice,x)->p), c(F64Slice,x
B f64arr_get (B x, usz n) { VT(x,t_f64arr ); return m_f64(c(F64Arr ,x)->a[n]); } B f64arr_get (B x, usz n) { VT(x,t_f64arr ); return m_f64(c(F64Arr ,x)->a[n]); }
B f64slice_get(B x, usz n) { VT(x,t_f64slice); return m_f64(c(F64Slice,x)->a[n]); } B f64slice_get(B x, usz n) { VT(x,t_f64slice); return m_f64(c(F64Slice,x)->a[n]); }
void f64arr_free(B x) { decSh(x); } void f64arr_free(Value* x) { decSh(x); }
bool f64arr_canStore(B x) { return q_f64(x); } bool f64arr_canStore(B x) { return q_f64(x); }
static inline void f64arr_init() { static inline void f64arr_init() {

View File

@ -80,11 +80,11 @@ B fillarr_get (B x, usz n) { VT(x,t_fillarr ); return inc(c(FillArr ,x)->a[n
B fillslice_get (B x, usz n) { VT(x,t_fillslice); return inc(c(FillSlice,x)->a[n]); } B fillslice_get (B x, usz n) { VT(x,t_fillslice); return inc(c(FillSlice,x)->a[n]); }
B fillarr_getU (B x, usz n) { VT(x,t_fillarr ); return c(FillArr ,x)->a[n] ; } B fillarr_getU (B x, usz n) { VT(x,t_fillarr ); return c(FillArr ,x)->a[n] ; }
B fillslice_getU(B x, usz n) { VT(x,t_fillslice); return c(FillSlice,x)->a[n] ; } B fillslice_getU(B x, usz n) { VT(x,t_fillslice); return c(FillSlice,x)->a[n] ; }
void fillarr_free(B x) { void fillarr_free(Value* x) {
decSh(x); decSh(x);
B* p = c(FillArr, x)->a; B* p = ((FillArr*)x)->a;
dec(c(FillArr, x)->fill); dec(((FillArr*)x)->fill);
usz ia = a(x)->ia; usz ia = ((Arr*)x)->ia;
for (usz i = 0; i < ia; i++) dec(p[i]); for (usz i = 0; i < ia; i++) dec(p[i]);
} }
void fillarr_visit(B x) { void fillarr_visit(B x) {

View File

@ -71,7 +71,7 @@ void gc_tryFree(Value* v) {
gc_freedBytes+= mm_size(v); gc_freedCount++; gc_freedBytes+= mm_size(v); gc_freedCount++;
#endif #endif
v->type = t_freed; v->type = t_freed;
ti[t].free(tag(v, OBJ_TAG)); ti[t].free(v);
// Object may not be immediately freed if it's not a part of a cycle, but instead a descendant of one. // Object may not be immediately freed if it's not a part of a cycle, but instead a descendant of one.
// It will be freed when the cycle is freed, and the t_freed type ensures it doesn't double-free itself // It will be freed when the cycle is freed, and the t_freed type ensures it doesn't double-free itself
} }

26
src/h.h
View File

@ -319,8 +319,9 @@ typedef struct ShArr {
struct Value; struct Value;
usz a[]; usz a[];
} ShArr; } ShArr;
ShArr* shObj(B x) { return (ShArr*)((u64)a(x)->sh-offsetof(ShArr,a)); } ShArr* shObj (B x) { return (ShArr*)((u64)a(x)->sh-offsetof(ShArr,a)); }
void decSh(B x) { if (rnk(x)>1) ptr_dec(shObj(x)); } ShArr* shObjP(Value* x) { return (ShArr*)((u64)((Arr*)x)->sh-offsetof(ShArr,a)); }
void decSh(Value* x) { if (prnk(x)>1) ptr_dec(shObjP(x)); }
void arr_shVec(B x, usz ia) { void arr_shVec(B x, usz ia) {
a(x)->ia = ia; a(x)->ia = ia;
@ -391,7 +392,7 @@ typedef struct Slice {
struct Arr; struct Arr;
B p; B p;
} Slice; } Slice;
void slice_free(B x) { dec(c(Slice,x)->p); decSh(x); } void slice_free(Value* x) { dec(((Slice*)x)->p); decSh(x); }
void slice_visit(B x) { mm_visit(c(Slice,x)->p); } void slice_visit(B x) { mm_visit(c(Slice,x)->p); }
void slice_print(B x) { arr_print(x); } void slice_print(B x) { arr_print(x); }
@ -409,7 +410,7 @@ typedef B (*BBBBB2B)(B, B, B, B, B);
typedef bool (*B2b)(B); typedef bool (*B2b)(B);
typedef struct TypeInfo { typedef struct TypeInfo {
B2v free; // expects refc==0, type may be cleared to t_empty for garbage collection V2v free; // expects refc==0, type may be cleared to t_empty for garbage collection
BS2B get; // increments result, doesn't consume arg; TODO figure out if this should never allocate, so GC wouldn't happen BS2B get; // increments result, doesn't consume arg; TODO figure out if this should never allocate, so GC wouldn't happen
BS2B getU; // like get, but doesn't increment result (mostly equivalent to `B t=get(…); dec(t); t`) BS2B getU; // like get, but doesn't increment result (mostly equivalent to `B t=get(…); dec(t); t`)
BB2B m1_d; // consume all args; (m, f) BB2B m1_d; // consume all args; (m, f)
@ -437,23 +438,22 @@ bool isNothing(B b) { return b.u==bi_N.u; }
// refcount // refcount
bool reusable(B x) { return v(x)->refc==1; } bool reusable(B x) { return v(x)->refc==1; }
static inline void value_free(B x, Value* vx) { static inline void value_free(Value* x) {
ti[vx->type].free(x); ti[x->type].free(x);
mm_free(vx); mm_free(x);
} }
static NOINLINE void value_freeR1(Value* x) { value_free(tag(x, OBJ_TAG), x); } static NOINLINE void value_freeR(Value* x) { value_free(x); }
static NOINLINE void value_freeR2(Value* vx, B x) { value_free(x, vx); }
void dec(B x) { void dec(B x) {
if (!isVal(VALIDATE(x))) return; if (!isVal(VALIDATE(x))) return;
Value* vx = v(x); Value* vx = v(x);
if(!--vx->refc) value_free(x, vx); if(!--vx->refc) value_free(vx);
} }
void ptr_dec(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_free(tag(x, OBJ_TAG), x); } void ptr_dec(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_free(x); }
void ptr_decR(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_freeR1(x); } void ptr_decR(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_freeR(x); }
void decR(B x) { void decR(B x) {
if (!isVal(VALIDATE(x))) return; if (!isVal(VALIDATE(x))) return;
Value* vx = v(x); Value* vx = v(x);
if(!--vx->refc) value_freeR2(vx, x); if(!--vx->refc) value_freeR(vx);
} }
B inc(B x) { B inc(B x) {
if (isVal(VALIDATE(x))) v(x)->refc++; if (isVal(VALIDATE(x))) v(x)->refc++;

View File

@ -164,10 +164,10 @@ B harr_get (B x, usz n) { VT(x,t_harr ); return inc(c(HArr ,x)->a[n]); }
B hslice_get (B x, usz n) { VT(x,t_hslice); return inc(c(HSlice,x)->a[n]); } B hslice_get (B x, usz n) { VT(x,t_hslice); return inc(c(HSlice,x)->a[n]); }
B harr_getU (B x, usz n) { VT(x,t_harr ); return c(HArr ,x)->a[n] ; } B harr_getU (B x, usz n) { VT(x,t_harr ); return c(HArr ,x)->a[n] ; }
B hslice_getU(B x, usz n) { VT(x,t_hslice); return c(HSlice,x)->a[n] ; } B hslice_getU(B x, usz n) { VT(x,t_hslice); return c(HSlice,x)->a[n] ; }
void harr_free(B x) { void harr_free(Value* x) {
decSh(x); decSh(x);
B* p = c(HArr,x)->a; // don't use harr_ptr so type isn't checked B* p = ((HArr*)x)->a; // don't use harr_ptr so type isn't checked
usz ia = a(x)->ia; usz ia = ((Arr*)x)->ia;
for (usz i = 0; i < ia; i++) dec(p[i]); for (usz i = 0; i < ia; i++) dec(p[i]);
} }
void harr_visit(B x) { void harr_visit(B x) {
@ -184,10 +184,10 @@ NOINLINE void harr_pfree(B x, usz am) { // am - item after last written
for (usz i = 0; i < am; i++) dec(p[i]); for (usz i = 0; i < am; i++) dec(p[i]);
mm_free(v(x)); mm_free(v(x));
} }
void harrP_free(B x) { assert(v(x)->type==t_harrPartial|v(x)->type==t_freed); void harrP_free(Value* x) { assert(x->type==t_harrPartial|x->type==t_freed);
assert(rnk(x)>1? true : a(x)->sh!=&a(x)->ia); assert(prnk(x)>1? true : ((Arr*)x)->sh!=&((Arr*)x)->ia);
B* p = c(HArr,x)->a; B* p = ((HArr*)x)->a;
usz am = *c(HArr,x)->sh; usz am = *((HArr*)x)->sh;
// printf("partfree %d/%d %p\n", am, a(x)->ia, (void*)x.u); // printf("partfree %d/%d %p\n", am, a(x)->ia, (void*)x.u);
for (usz i = 0; i < am; i++) dec(p[i]); for (usz i = 0; i < am; i++) dec(p[i]);
} }

View File

@ -41,13 +41,13 @@ bool heapVerify_visitP(void* x) {
} }
void heapVerify_callVisit(Value* v) { void heapVerify_callVisit(Value* v) {
if (ti[v->type].isArr && rnk(tag(v,ARR_TAG))>1) heapVerify_visitP(shObj(tag(v,ARR_TAG))); if (ti[v->type].isArr && prnk(v)>1) heapVerify_visitP(shObjP(v));
ti[v->type].visit(tag(v,OBJ_TAG)); ti[v->type].visit(tag(v,OBJ_TAG));
} }
void heap_getReferents(Value* v) { void heap_getReferents(Value* v) {
heap_curr = v; heap_curr = v;
if (ti[v->type].isArr && rnk(tag(v,ARR_TAG))>1) heapVerify_visitP(shObj(tag(v,ARR_TAG))); if (ti[v->type].isArr && prnk(v)>1) heapVerify_visitP(shObjP(v));
ti[v->type].visit(tag(v,OBJ_TAG)); ti[v->type].visit(tag(v,OBJ_TAG));
} }
#ifdef CATCH_ERRORS #ifdef CATCH_ERRORS

View File

@ -63,7 +63,7 @@ B i32slice_slice(B x, usz s) { B r = m_i32slice(inc(c(Slice,x)->p), c(I32Slice,x
B i32arr_get (B x, usz n) { VT(x,t_i32arr ); return m_i32(c(I32Arr ,x)->a[n]); } B i32arr_get (B x, usz n) { VT(x,t_i32arr ); return m_i32(c(I32Arr ,x)->a[n]); }
B i32slice_get(B x, usz n) { VT(x,t_i32slice); return m_i32(c(I32Slice,x)->a[n]); } B i32slice_get(B x, usz n) { VT(x,t_i32slice); return m_i32(c(I32Slice,x)->a[n]); }
void i32arr_free(B x) { decSh(x); } void i32arr_free(Value* x) { decSh(x); }
bool i32arr_canStore(B x) { return q_i32(x); } bool i32arr_canStore(B x) { return q_i32(x); }
static inline void i32arr_init() { static inline void i32arr_init() {

View File

@ -63,8 +63,8 @@ B ns_nameList(NSDesc* d) {
void ns_free(B x) { void ns_free(Value* x) {
NS* c = c(NS, x); NS* c = (NS*)x;
ptr_decR(c->desc); ptr_decR(c->desc);
ptr_decR(c->sc); ptr_decR(c->sc);
} }
@ -93,8 +93,8 @@ void ns_print(B x) {
putchar('}'); putchar('}');
} }
void nsDesc_free(B x) { void nsDesc_free(Value* x) {
decR(c(NSDesc,x)->nameList); decR(((NSDesc*)x)->nameList);
} }
void nsDesc_visit(B x) { void nsDesc_visit(B x) {
mm_visit(c(NSDesc,x)->nameList); mm_visit(c(NSDesc,x)->nameList);

View File

@ -148,7 +148,7 @@ B shape_c1(B t, B x) {
if (isAtm(x)) thrM("⥊: deshaping non-array"); if (isAtm(x)) thrM("⥊: deshaping non-array");
usz ia = a(x)->ia; usz ia = a(x)->ia;
if (reusable(x)) { if (reusable(x)) {
decSh(x); decSh(v(x));
arr_shVec(x, ia); arr_shVec(x, ia);
return x; return x;
} }
@ -165,7 +165,7 @@ B shape_c2(B t, B w, B x) {
ur nr = (ur)wia; ur nr = (ur)wia;
usz nia = a(x)->ia; usz nia = a(x)->ia;
B r; B r;
if (reusable(x)) { r = x; decSh(x); } if (reusable(x)) { r = x; decSh(v(x)); }
else r = TI(x).slice(x, 0); else r = TI(x).slice(x, 0);
usz* sh = arr_shAllocI(r, nia, nr); usz* sh = arr_shAllocI(r, nia, nr);
if (sh) for (u32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i)); if (sh) for (u32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i));

View File

@ -10,8 +10,9 @@
#endif #endif
void empty_free(B x) { err("FREEING EMPTY\n"); } void empty_free(Value* x) { err("FREEING EMPTY\n"); }
void builtin_free(B x) { err("FREEING BUILTIN\n"); } void builtin_free(Value* x) { err("FREEING BUILTIN\n"); }
void def_free(Value* x) { }
void def_visit(B x) { printf("(no visit for %d=%s)\n", v(x)->type, format_type(v(x)->type)); } void def_visit(B x) { printf("(no visit for %d=%s)\n", v(x)->type, format_type(v(x)->type)); }
void freed_visit(B x) { void freed_visit(B x) {
#ifndef CATCH_ERRORS #ifndef CATCH_ERRORS
@ -218,8 +219,8 @@ u8 fillElType(B x) {
} }
if (ti[x->type].isArr) { if (ti[x->type].isArr) {
Arr* a = (Arr*)x; Arr* a = (Arr*)x;
if (rnk(tag(x,ARR_TAG))<=1) assert(a->sh == &a->ia); if (prnk(x)<=1) assert(a->sh == &a->ia);
else VALIDATE(tag(shObj(tag(x,ARR_TAG)),OBJ_TAG)); else VALIDATE(tag(shObjP(x),OBJ_TAG));
} }
return x; return x;
} }
@ -245,7 +246,7 @@ u8 fillElType(B x) {
static inline void hdr_init() { static inline void hdr_init() {
for (i32 i = 0; i < t_COUNT; i++) { for (i32 i = 0; i < t_COUNT; i++) {
ti[i].free = do_nothing; ti[i].free = def_free;
ti[i].visit = def_visit; ti[i].visit = def_visit;
ti[i].get = def_get; ti[i].get = def_get;
ti[i].getU = def_getU; ti[i].getU = def_getU;
@ -261,7 +262,7 @@ static inline void hdr_init() {
ti[i].canStore = def_canStore; ti[i].canStore = def_canStore;
} }
ti[t_empty].free = empty_free; ti[t_empty].free = empty_free;
ti[t_freed].free = do_nothing; ti[t_freed].free = def_free;
ti[t_freed].visit = freed_visit; ti[t_freed].visit = freed_visit;
ti[t_shape].visit = do_nothing; ti[t_shape].visit = do_nothing;
ti[t_funBI].visit = ti[t_md1BI].visit = ti[t_md2BI].visit = do_nothing; ti[t_funBI].visit = ti[t_md1BI].visit = ti[t_md2BI].visit = do_nothing;

View File

@ -561,24 +561,24 @@ B m_md2Block(Block* bl, Scope* psc) {
return r; return r;
} }
void comp_free(B x) { void comp_free(Value* x) {
Comp* c = c(Comp, x); Comp* c = (Comp*)x;
ptr_decR(c->objs); decR(c->bc); decR(c->src); decR(c->indices); ptr_decR(c->objs); decR(c->bc); decR(c->src); decR(c->indices);
u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]); u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]);
} }
void scope_free(B x) { void scope_free(Value* x) {
Scope* c = c(Scope,x); Scope* c = (Scope*)x;
if (c->psc) ptr_decR(c->psc); if (c->psc) ptr_decR(c->psc);
ptr_decR(c->body); ptr_decR(c->body);
u16 am = c->varAm; u16 am = c->varAm;
for (u32 i = 0; i < am; i++) dec(c->vars[i]); for (u32 i = 0; i < am; i++) dec(c->vars[i]);
} }
void body_free(B x) { Body* c = c(Body ,x); ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); } void body_free(Value* x) { Body* c = (Body*)x; ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); }
void block_free(B x) { Block* c = c(Block,x); ptr_decR(c->body); } void block_free(Value* x) { Block* c = (Block*)x; ptr_decR(c->body); }
void funBl_free(B x) { FunBlock* c = c(FunBlock,x); ptr_decR(c->sc); ptr_decR(c->bl); } void funBl_free(Value* x) { FunBlock* c = (FunBlock*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
void md1Bl_free(B x) { Md1Block* c = c(Md1Block,x); ptr_decR(c->sc); ptr_decR(c->bl); } void md1Bl_free(Value* x) { Md1Block* c = (Md1Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
void md2Bl_free(B x) { Md2Block* c = c(Md2Block,x); ptr_decR(c->sc); ptr_decR(c->bl); } void md2Bl_free(Value* x) { Md2Block* c = (Md2Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
void alias_free(B x) { dec(c(FldAlias,x)->obj); } void alias_free(Value* x) { dec(((FldAlias*)x)->obj); }
void comp_visit(B x) { void comp_visit(B x) {
Comp* c = c(Comp,x); Comp* c = c(Comp,x);