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:
parent
36111276c6
commit
f87a1155f5
@ -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); }
|
||||
}
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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)); }
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
15
src/load.c
15
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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
11
src/opt/gc.c
11
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() {
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user