From f87a1155f5b37a63d84fad23362c4defcbc9ba99 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 6 Nov 2022 02:01:08 +0200 Subject: [PATCH] store references instead of GC root functions to handle mutable roots -0.21% binary size; mm_visit & mm_visitP got inlined in the gcFn-s, even though that's very pointless --- src/builtins/fns.c | 16 ++++++---------- src/builtins/internal.c | 16 +++++++--------- src/builtins/search.c | 10 ++-------- src/builtins/sysfn.c | 16 +++++++--------- src/load.c | 15 ++++++--------- src/nfns.c | 5 +---- src/opt/gc.c | 11 +++++++++-- src/opt/gc.h | 1 + 8 files changed, 39 insertions(+), 51 deletions(-) diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 4bb02939..0acd2e0c 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -272,13 +272,7 @@ void profiler_freeMap(void* mapRaw) { void fun_gcFn() { if (prevImports!=NULL) mm_visitP(prevImports); if (globalNames!=NULL) mm_visitP(globalNames); - mm_visit(globalNameList); - for (i32 i = 0; i < 3; i++) mm_visitP(bitUD[i]); - mm_visit(bit2x[1]); // bit2x[0] visited by ↑ } - - - static void print_funBI(FILE* f, B x) { fprintf(f, "%s", pfn_repr(c(Fun,x)->extra)); } static B funBI_uc1(B t, B o, B x) { return c(BFn,t)->uc1(t, o, x); } static B funBI_ucw(B t, B o, B w, B x) { return c(BFn,t)->ucw(t, o, w, x); } @@ -286,13 +280,15 @@ static B funBI_im(B t, B x) { return c(BFn,t)->im(t, x); } static B funBI_identity(B x) { return inc(c(BFn,x)->ident); } void fns_init() { gc_addFn(fun_gcFn); + gc_add_ref(&globalNameList); + TIi(t_funBI,print) = print_funBI; TIi(t_funBI,identity) = funBI_identity; TIi(t_funBI,fn_uc1) = funBI_uc1; TIi(t_funBI,fn_ucw) = funBI_ucw; TIi(t_funBI,fn_im) = funBI_im; - bitUD[0] = a(emptyIVec()); - { u64* p; B a=m_bitarrv(&p, 1); *p=0; bitUD[1] = a(a); } - { u64* p; B a=m_bitarrv(&p, 2); *p=0; bitp_set(p,1,1); bitUD[2] = a(a); bit2x[0] = a; } - { u64* p; B a=m_bitarrv(&p, 2); *p=0; bitp_set(p,0,1); bit2x[1] = a; } + bitUD[0] = a(bi_emptyIVec); // don't increment as it's already gc_add-ed + { u64* p; B a=m_bitarrv(&p, 1); *p=0; bitUD[1] = a(a); gc_add(a); } + { u64* p; B a=m_bitarrv(&p, 2); *p=0; bitp_set(p,1,1); bitUD[2] = a(a); bit2x[0] = a; gc_add(a); } + { u64* p; B a=m_bitarrv(&p, 2); *p=0; bitp_set(p,0,1); bit2x[1] = a; gc_add(a); } } diff --git a/src/builtins/internal.c b/src/builtins/internal.c index d6a48300..4e86cd2d 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -162,14 +162,6 @@ static bool u8_get(u8** cv, u8* cE, const char* x) { } static B variation_refs; -static void variation_gcRoot() { - mm_visit(variation_refs); - mm_visit(listVariations_def); - #define F(X) mm_visit(v_##X); - FOR_VARIATION(F) - #undef F -} - B variation_c2(B t, B w, B x) { if (!isArr(w)) thrM("•internal.Variation: Non-array 𝕨"); if (!isArr(x)) thrM("•internal.Variation: Non-array 𝕩"); @@ -316,7 +308,13 @@ B getInternalNS() { FOR_VARIATION(F) #undef F listVariations_def = m_c8vec_0("if"); - gc_addFn(variation_gcRoot); + + gc_add(listVariations_def); + gc_add_ref(&variation_refs); + #define F(X) gc_add_ref(&v_##X); // 38 refs + FOR_VARIATION(F) + #undef F + #define F(X) incG(bi_##X), Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info","listvariations","variation","clearrefs","unshare","deepsqueeze","heapdump","eequal","temp"); internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)F(heapDump)F(eequal)F(internalTemp)); diff --git a/src/builtins/search.c b/src/builtins/search.c index cfcc34d6..330f9285 100644 --- a/src/builtins/search.c +++ b/src/builtins/search.c @@ -232,13 +232,7 @@ B count_c2(B t, B w, B x) { } -void search_gcFn() { - mm_visit(enclosed_0); - mm_visit(enclosed_1); -} - void search_init() { - gc_addFn(search_gcFn); - { u64* p; Arr* a=m_bitarrp(&p, 1); arr_shAlloc(a,0); *p= 0; enclosed_0=taga(a); } - { u64* p; Arr* a=m_bitarrp(&p, 1); arr_shAlloc(a,0); *p=~0ULL; enclosed_1=taga(a); } + { u64* p; Arr* a=m_bitarrp(&p, 1); arr_shAlloc(a,0); *p= 0; gc_add(enclosed_0=taga(a)); } + { u64* p; Arr* a=m_bitarrp(&p, 1); arr_shAlloc(a,0); *p=~0ULL; gc_add(enclosed_1=taga(a)); } } diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 8e7b2ffc..e5f692da 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -709,14 +709,6 @@ B import_c1(B d, B x) { return r; } -static void sys_gcFn() { - mm_visit(importKeyList); - mm_visit(importValList); - mm_visit(thrownMsg); - #if CATCH_ERRORS - mm_visit(lastErrMsg); - #endif -} void clearImportCache() { if (importKeyList.u!=0) { dec(importKeyList); importKeyList = m_f64(0); @@ -1552,8 +1544,14 @@ void sysfn_init() { #if CATCH_ERRORS lastErrMsg = bi_N; + gc_add_ref(&lastErrMsg); #endif - cdPath = m_c8vec(".", 1); gc_add(cdPath); gc_addFn(sys_gcFn); + cdPath = m_c8vec(".", 1); gc_add(cdPath); + + gc_add_ref(&importKeyList); + gc_add_ref(&importValList); + gc_add_ref(&thrownMsg); + reBQNDesc = registerNFn(m_c8vec_0("(REPL)"), repl_c1, repl_c2); } void sysfnPost_init() { diff --git a/src/load.c b/src/load.c index 873dae8c..d6cad43a 100644 --- a/src/load.c +++ b/src/load.c @@ -149,14 +149,6 @@ B bqn_repr(B x) { } #endif -void load_gcFn() { - mm_visit(comp_currPath); - mm_visit(comp_currArgs); - mm_visit(comp_currSrc); - mm_visit(comp_currRe); - mm_visit(rt_invFnReg); - mm_visit(rt_invFnSwap); -} #define POP_COMP ({ \ comp_currPath = prevPath; \ comp_currArgs = prevArgs; \ @@ -353,7 +345,12 @@ void load_init() { // very last init function comp_currArgs = bi_N; comp_currSrc = bi_N; comp_currRe = bi_N; - gc_addFn(load_gcFn); + gc_add_ref(&comp_currPath); + gc_add_ref(&comp_currArgs); + gc_add_ref(&comp_currSrc); + gc_add_ref(&comp_currRe); + gc_add_ref(&rt_invFnReg); + gc_add_ref(&rt_invFnSwap); B fruntime[] = { /* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_root , bi_floor , bi_ceil , bi_stile , bi_not, /* ∧∨<>≠=≤≥≡≢ */ bi_and , bi_or , bi_lt , bi_gt , bi_ne , bi_eq , bi_le , bi_ge , bi_feq , bi_fne, diff --git a/src/nfns.c b/src/nfns.c index d49dbe02..402a4fa7 100644 --- a/src/nfns.c +++ b/src/nfns.c @@ -34,14 +34,11 @@ DEF_FREE(nfnDesc) { err("nfnDesc shouldn't be freed!"); } void nfnDesc_visit(Value* x) { mm_visit(((NFnDesc*)x)->name); } void nfnDesc_print(FILE* f, B x) { fprintf(f, "(native function description)"); } -void nfn_gcRoot() { - mm_visit(nfn_list); -} void nfn_init() { nfn_list = emptyHVec(); TIi(t_nfn,freeO) = nfn_freeO; TIi(t_nfnDesc,freeO) = nfnDesc_freeO; TIi(t_nfn,freeF) = nfn_freeF; TIi(t_nfnDesc,freeF) = nfnDesc_freeF; TIi(t_nfn,visit) = nfn_visit; TIi(t_nfnDesc,visit) = nfnDesc_visit; TIi(t_nfn,print) = nfn_print; TIi(t_nfnDesc,print) = nfnDesc_print; - gc_addFn(nfn_gcRoot); + gc_add_ref(&nfn_list); } diff --git a/src/opt/gc.c b/src/opt/gc.c index 98a2417c..0b9c2cda 100644 --- a/src/opt/gc.c +++ b/src/opt/gc.c @@ -7,10 +7,10 @@ u64 gc_depth = 1; -vfn gc_roots[32]; +vfn gc_roots[8]; u32 gc_rootSz; void gc_addFn(vfn f) { - if (gc_rootSz>=32) err("Too many GC root functions"); + if (gc_rootSz>=8) err("Too many GC root functions"); gc_roots[gc_rootSz++] = f; } @@ -22,6 +22,12 @@ void gc_add(B x) { gc_rootObjs[gc_rootObjSz++] = v(x); } +B* gc_rootBRefs[64]; u32 gc_rootBRefsSz; +void gc_add_ref(B* x) { + if (gc_rootBRefsSz>=64) err("Too many GC root B refs"); + gc_rootBRefs[gc_rootBRefsSz++] = x; +} + #ifdef LOG_GC u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount; @@ -64,6 +70,7 @@ static void gc_resetTag(Value* x) { void gc_visitRoots() { for (u32 i = 0; i < gc_rootSz; i++) gc_roots[i](); for (u32 i = 0; i < gc_rootObjSz; i++) mm_visitP(gc_rootObjs[i]); + for (u32 i = 0; i < gc_rootBRefsSz; i++) mm_visit(*gc_rootBRefs[i]); } u64 gc_lastAlloc; void gc_forceGC() { diff --git a/src/opt/gc.h b/src/opt/gc.h index 91f29dd3..535a49f0 100644 --- a/src/opt/gc.h +++ b/src/opt/gc.h @@ -5,6 +5,7 @@ static void gc_disable() { gc_depth++; } static void gc_enable() { gc_depth--; } void gc_addFn(vfn f); void gc_add(B x); +void gc_add_ref(B* x); #ifdef LOG_GC