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 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); }
static inline void c32arr_init() {

View File

@ -24,11 +24,11 @@ typedef struct Atop {
B g, h;
} Atop;
void md1D_free(B x) { dec(c(Md1D,x)->m1); dec(c(Md1D,x)->f); }
void md2D_free(B x) { dec(c(Md2D,x)->m2); dec(c(Md2D,x)->f); dec(c(Md2D,x)->g); }
void md2H_free(B x) { dec(c(Md2H,x)->m2); dec(c(Md2H,x)->g); }
void fork_free(B x) { dec(c(Fork,x)->f ); dec(c(Fork,x)->g); dec(c(Fork,x)->h); }
void atop_free(B x) { dec(c(Atop,x)->g); dec(c(Atop,x)->h); }
void md1D_free(Value* x) { dec(((Md1D*)x)->m1); dec(((Md1D*)x)->f); }
void md2D_free(Value* x) { dec(((Md2D*)x)->m2); dec(((Md2D*)x)->f); dec(((Md2D*)x)->g); }
void md2H_free(Value* x) { dec(((Md2H*)x)->m2); dec(((Md2H*)x)->g); }
void fork_free(Value* x) { dec(((Fork*)x)->f ); dec(((Fork*)x)->g); dec(((Fork*)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 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 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); }
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 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] ; }
void fillarr_free(B x) {
void fillarr_free(Value* x) {
decSh(x);
B* p = c(FillArr, x)->a;
dec(c(FillArr, x)->fill);
usz ia = a(x)->ia;
B* p = ((FillArr*)x)->a;
dec(((FillArr*)x)->fill);
usz ia = ((Arr*)x)->ia;
for (usz i = 0; i < ia; i++) dec(p[i]);
}
void fillarr_visit(B x) {

View File

@ -71,7 +71,7 @@ void gc_tryFree(Value* v) {
gc_freedBytes+= mm_size(v); gc_freedCount++;
#endif
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.
// 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;
usz a[];
} ShArr;
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* shObj (B x) { return (ShArr*)((u64)a(x)->sh-offsetof(ShArr,a)); }
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) {
a(x)->ia = ia;
@ -391,7 +392,7 @@ typedef struct Slice {
struct Arr;
B p;
} 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_print(B x) { arr_print(x); }
@ -409,7 +410,7 @@ typedef B (*BBBBB2B)(B, B, B, B, B);
typedef bool (*B2b)(B);
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 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)
@ -437,23 +438,22 @@ bool isNothing(B b) { return b.u==bi_N.u; }
// refcount
bool reusable(B x) { return v(x)->refc==1; }
static inline void value_free(B x, Value* vx) {
ti[vx->type].free(x);
mm_free(vx);
static inline void value_free(Value* x) {
ti[x->type].free(x);
mm_free(x);
}
static NOINLINE void value_freeR1(Value* x) { value_free(tag(x, OBJ_TAG), x); }
static NOINLINE void value_freeR2(Value* vx, B x) { value_free(x, vx); }
static NOINLINE void value_freeR(Value* x) { value_free(x); }
void dec(B x) {
if (!isVal(VALIDATE(x))) return;
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_decR(void* x) { if(!--VALIDATEP((Value*)x)->refc) value_freeR1(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_freeR(x); }
void decR(B x) {
if (!isVal(VALIDATE(x))) return;
Value* vx = v(x);
if(!--vx->refc) value_freeR2(vx, x);
if(!--vx->refc) value_freeR(vx);
}
B inc(B x) {
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 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] ; }
void harr_free(B x) {
void harr_free(Value* x) {
decSh(x);
B* p = c(HArr,x)->a; // don't use harr_ptr so type isn't checked
usz ia = a(x)->ia;
B* p = ((HArr*)x)->a; // don't use harr_ptr so type isn't checked
usz ia = ((Arr*)x)->ia;
for (usz i = 0; i < ia; i++) dec(p[i]);
}
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]);
mm_free(v(x));
}
void harrP_free(B x) { assert(v(x)->type==t_harrPartial|v(x)->type==t_freed);
assert(rnk(x)>1? true : a(x)->sh!=&a(x)->ia);
B* p = c(HArr,x)->a;
usz am = *c(HArr,x)->sh;
void harrP_free(Value* x) { assert(x->type==t_harrPartial|x->type==t_freed);
assert(prnk(x)>1? true : ((Arr*)x)->sh!=&((Arr*)x)->ia);
B* p = ((HArr*)x)->a;
usz am = *((HArr*)x)->sh;
// printf("partfree %d/%d %p\n", am, a(x)->ia, (void*)x.u);
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) {
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));
}
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)));
if (ti[v->type].isArr && prnk(v)>1) heapVerify_visitP(shObjP(v));
ti[v->type].visit(tag(v,OBJ_TAG));
}
#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 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); }
static inline void i32arr_init() {

View File

@ -63,8 +63,8 @@ B ns_nameList(NSDesc* d) {
void ns_free(B x) {
NS* c = c(NS, x);
void ns_free(Value* x) {
NS* c = (NS*)x;
ptr_decR(c->desc);
ptr_decR(c->sc);
}
@ -93,8 +93,8 @@ void ns_print(B x) {
putchar('}');
}
void nsDesc_free(B x) {
decR(c(NSDesc,x)->nameList);
void nsDesc_free(Value* x) {
decR(((NSDesc*)x)->nameList);
}
void nsDesc_visit(B x) {
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");
usz ia = a(x)->ia;
if (reusable(x)) {
decSh(x);
decSh(v(x));
arr_shVec(x, ia);
return x;
}
@ -165,7 +165,7 @@ B shape_c2(B t, B w, B x) {
ur nr = (ur)wia;
usz nia = a(x)->ia;
B r;
if (reusable(x)) { r = x; decSh(x); }
if (reusable(x)) { r = x; decSh(v(x)); }
else r = TI(x).slice(x, 0);
usz* sh = arr_shAllocI(r, nia, nr);
if (sh) for (u32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i));

View File

@ -10,8 +10,9 @@
#endif
void empty_free(B x) { err("FREEING EMPTY\n"); }
void builtin_free(B x) { err("FREEING BUILTIN\n"); }
void empty_free(Value* x) { err("FREEING EMPTY\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 freed_visit(B x) {
#ifndef CATCH_ERRORS
@ -218,8 +219,8 @@ u8 fillElType(B x) {
}
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));
if (prnk(x)<=1) assert(a->sh == &a->ia);
else VALIDATE(tag(shObjP(x),OBJ_TAG));
}
return x;
}
@ -245,7 +246,7 @@ u8 fillElType(B x) {
static inline void hdr_init() {
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].get = def_get;
ti[i].getU = def_getU;
@ -261,7 +262,7 @@ static inline void hdr_init() {
ti[i].canStore = def_canStore;
}
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_shape].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;
}
void comp_free(B x) {
Comp* c = c(Comp, x);
void comp_free(Value* x) {
Comp* c = (Comp*)x;
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]);
}
void scope_free(B x) {
Scope* c = c(Scope,x);
void scope_free(Value* x) {
Scope* c = (Scope*)x;
if (c->psc) ptr_decR(c->psc);
ptr_decR(c->body);
u16 am = c->varAm;
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 block_free(B x) { Block* c = 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 md1Bl_free(B x) { Md1Block* c = 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 alias_free(B x) { dec(c(FldAlias,x)->obj); }
void body_free(Value* x) { Body* c = (Body*)x; ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); }
void block_free(Value* x) { Block* c = (Block*)x; ptr_decR(c->body); }
void funBl_free(Value* x) { FunBlock* c = (FunBlock*)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(Value* x) { Md2Block* c = (Md2Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
void alias_free(Value* x) { dec(((FldAlias*)x)->obj); }
void comp_visit(B x) {
Comp* c = c(Comp,x);