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
This commit is contained in:
dzaima 2022-11-06 02:01:08 +02:00
parent 36111276c6
commit f87a1155f5
8 changed files with 39 additions and 51 deletions

View File

@ -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); }
}

View File

@ -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));

View File

@ -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)); }
}

View File

@ -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() {

View File

@ -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,

View File

@ -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);
}

View File

@ -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() {

View File

@ -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