make heapverify run on GC_VISIT_V2

also make it able to track shape object leaks
This commit is contained in:
dzaima 2023-02-25 00:20:51 +02:00
parent c6c0b8925e
commit a928277e8c
7 changed files with 35 additions and 7 deletions

View File

@ -93,6 +93,7 @@ DEF_FREE(harr) {
for (usz i = 0; i < ia; i++) dec(p[i]);
}
static void harr_visit(Value* x) {
VISIT_SHAPE(x);
usz ia = PIA((Arr*)x); B* p = ((HArr*)x)->a;
for (usz i = 0; i < ia; i++) mm_visit(p[i]);
}

View File

@ -30,11 +30,18 @@ void heap_getReferents(Value* v) {
TIv(v,visit)(v);
}
void gc_visitRoots(void);
void gcv2_runHeapverify(i32);
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 GC_VISIT_V2
gcv2_runHeapverify(0);
mm_forHeap(heapVerify_checkFn);
gcv2_runHeapverify(1);
#else
heapVerify_mode=0; mm_forHeap(heapVerify_callVisit); gc_visitRoots();
mm_forHeap(heapVerify_checkFn);
heapVerify_mode=1; mm_forHeap(heapVerify_callVisit); gc_visitRoots();
#endif
if (heap_observed) {
printf("refc of last: %d\n", heap_observed->refc);
// heapVerify_mode=2; mm_forHeap(heap_getReferents);

View File

@ -44,6 +44,9 @@ NOINLINE B c2F(B f, B w, B x) { dec(w); dec(x);
NOINLINE void value_freeF(Value* x) { value_free(x); }
NOINLINE void decA_F(B x) { dec(x); }
void noop_visit(Value* x) { }
#if HEAP_VERIFY && GC_VISIT_V2
void arr_visit(Value* x) { VISIT_SHAPE(x); }
#endif
NOINLINE B c1_bad(B f, B x) { thrM("This function can't be called monadically"); }
NOINLINE B c2_bad(B f, B w, B x) { thrM("This function can't be called dyadically"); }
NOINLINE B m1c1_bad(Md1D* d, B x) { thrM("This 1-modifier can't be called monadically"); }
@ -583,7 +586,7 @@ void tyarr_freeO(Value* x) { decSh(x); }
void slice_freeO(Value* x) { ptr_dec(((Slice*)x)->p); decSh(x); }
void tyarr_freeF(Value* x) { tyarr_freeO(x); mm_free(x); }
void slice_freeF(Value* x) { slice_freeO(x); mm_free(x); }
void slice_visit(Value* x) { mm_visitP(((Slice*)x)->p); }
void slice_visit(Value* x) { mm_visitP(((Slice*)x)->p); VISIT_SHAPE(x); }
void slice_print(B x) { arr_print(x); }
char* type_repr(u8 u) {

View File

@ -222,6 +222,13 @@ B def_fn_ix(B t, B w, B x);
B def_decompose(B x);
void noop_visit(Value* x);
#if HEAP_VERIFY && GC_VISIT_V2
void arr_visit(Value* x);
#define VISIT_SHAPE(X) ({ if (PRNK(X)>1) mm_visitP(shObjP(X)); })
#else
#define arr_visit noop_visit
#define VISIT_SHAPE(X)
#endif
#define CMP(W,X) ({ AUTO wt = (W); AUTO xt = (X); (wt>xt?1:0)-(wt<xt?1:0); })
NOINLINE i32 compareF(B w, B x);

View File

@ -86,7 +86,7 @@ static void bitarr_init(void) {
TIi(t_bitarr,slice) = bitarr_slice;
TIi(t_bitarr,freeO) = tyarr_freeO;
TIi(t_bitarr,freeF) = tyarr_freeF;
TIi(t_bitarr,visit) = noop_visit;
TIi(t_bitarr,visit) = arr_visit;
TIi(t_bitarr,print) = farr_print;
TIi(t_bitarr,isArr) = true;
TIi(t_bitarr,arrD1) = true;

View File

@ -21,7 +21,7 @@ static void TP(,arr_init)() {
TIi(T_ARR,slice) = TP(,arr_slice); TIi(T_SLICE,slice) = TP(,slice_slice);
TIi(T_ARR,freeO) = tyarr_freeO; TIi(T_SLICE,freeO) = slice_freeO; // typed array slice frees calling the generic function is relied on by mmap & •bit._cast
TIi(T_ARR,freeF) = tyarr_freeF; TIi(T_SLICE,freeF) = slice_freeF;
TIi(T_ARR,visit) = noop_visit; TIi(T_SLICE,visit) = slice_visit;
TIi(T_ARR,visit) = arr_visit; TIi(T_SLICE,visit) = slice_visit;
TIi(T_ARR,print) = farr_print; TIi(T_SLICE,print) = farr_print;
TIi(T_ARR,isArr) = true; TIi(T_SLICE,isArr) = true;
TIi(T_ARR,arrD1) = true; TIi(T_SLICE,arrD1) = true;

View File

@ -82,6 +82,7 @@ static void gc_tryFree(Value* v) {
GC_DEC_REFC, // decrement refcount
GC_INC_REFC, // increment refcount
GC_MARK, // if unmarked, mark & visit
GC_LISTBAD, //
};
void gc_onVisit(Value* x) {
@ -100,6 +101,16 @@ static void gc_tryFree(Value* v) {
}
}
static void gcv2_visit(Value* x) { TIv(x,visit)(x); }
#if HEAP_VERIFY
void gcv2_runHeapverify(i32 mode) {
visit_mode = mode==0? GC_DEC_REFC : GC_INC_REFC;
mm_forHeap(gcv2_visit);
gc_visitRoots();
}
#endif
static Value** gcv2_bufS;
static Value** gcv2_bufC;
static Value** gcv2_bufE;
@ -124,7 +135,6 @@ static void gc_tryFree(Value* v) {
if (gcv2_bufC == gcv2_bufE) return gcv2_storeRemainingR(x);
gcv2_storeRemainingEnd(x);
}
static void gcv2_visit(Value* x) { TIv(x,visit)(x); }
static void gc_run() {
visit_mode = GC_DEC_REFC;