move GC tag resetting from alloc to another pass

This commit is contained in:
dzaima 2021-10-10 23:11:49 +03:00
parent a62a41249e
commit b7f60ffb1c
3 changed files with 12 additions and 16 deletions

View File

@ -21,14 +21,12 @@ void gc_add(B x) {
u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount; u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount;
#endif #endif
u8 gc_tagCurr = 0x80; // if no gc is running, this is what all objects will have static void gc_tryFree(Value* v) {
u8 gc_tagNew = 0x00;
void gc_tryFree(Value* v) {
u8 t = v->type; u8 t = v->type;
#if defined(DEBUG) && !defined(CATCH_ERRORS) #if defined(DEBUG) && !defined(CATCH_ERRORS)
if (t==t_freed) err("GC found t_freed\n"); if (t==t_freed) err("GC found t_freed\n");
#endif #endif
if (t!=t_empty & (v->mmInfo&0x80)==gc_tagCurr) { if (t!=t_empty && !(v->mmInfo&0x80)) {
if (t==t_shape) return; if (t==t_shape) return;
#ifdef DONT_FREE #ifdef DONT_FREE
v->flags = t; v->flags = t;
@ -49,8 +47,11 @@ void gc_tryFree(Value* v) {
} }
} }
static void gc_resetTag(Value* x) {
x->mmInfo&= 0x7F;
}
void gc_visitRoots() { static void gc_visitRoots() {
for (u32 i = 0; i < gc_rootSz; i++) gc_roots[i](); for (u32 i = 0; i < gc_rootSz; i++) gc_roots[i]();
for (u32 i = 0; i < gc_rootObjSz; i++) mm_visit(gc_rootObjs[i]); for (u32 i = 0; i < gc_rootObjSz; i++) mm_visit(gc_rootObjs[i]);
} }
@ -63,10 +64,9 @@ void gc_forceGC() {
gc_visitCount = 0; gc_freedCount = 0; gc_visitCount = 0; gc_freedCount = 0;
u64 startSize = mm_heapUsed(); u64 startSize = mm_heapUsed();
#endif #endif
mm_forHeap(gc_resetTag);
gc_visitRoots(); gc_visitRoots();
mm_forHeap(gc_tryFree); mm_forHeap(gc_tryFree);
gc_tagNew = gc_tagCurr;
gc_tagCurr^= 0x80;
u64 endSize = mm_heapUsed(); u64 endSize = mm_heapUsed();
#ifdef LOG_GC #ifdef LOG_GC
fprintf(stderr, "GC kept "N64d"B from "N64d" objects, freed "N64d"B, including directly "N64d"B from "N64d" objects; took %.3fms\n", gc_visitBytes, gc_visitCount, startSize-endSize, gc_freedBytes, gc_freedCount, (nsTime()-start)/1e6); fprintf(stderr, "GC kept "N64d"B from "N64d" objects, freed "N64d"B, including directly "N64d"B from "N64d" objects; took %.3fms\n", gc_visitBytes, gc_visitCount, startSize-endSize, gc_freedBytes, gc_freedCount, (nsTime()-start)/1e6);

View File

@ -7,8 +7,6 @@ void gc_addFn(vfn f);
void gc_add(B x); void gc_add(B x);
extern u8 gc_tagCurr; // if no gc is running, this is what all objects will have
extern u8 gc_tagNew;
#ifdef LOG_GC #ifdef LOG_GC
extern u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount; extern u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount;
#endif #endif
@ -20,9 +18,8 @@ static void mm_visit(B x) {
if (!isVal(x)) return; if (!isVal(x)) return;
Value* vx = v(x); Value* vx = v(x);
u8 p = vx->mmInfo; if (vx->mmInfo&0x80) return;
if ((p&0x80)==gc_tagNew) return; vx->mmInfo|= 0x80;
vx->mmInfo = p^0x80;
#ifdef LOG_GC #ifdef LOG_GC
gc_visitBytes+= mm_size(vx); gc_visitCount++; gc_visitBytes+= mm_size(vx); gc_visitCount++;
#endif #endif
@ -34,9 +31,8 @@ static void mm_visitP(void* xp) {
#endif #endif
Value* x = (Value*)xp; Value* x = (Value*)xp;
u8 p = x->mmInfo; if (x->mmInfo&0x80) return;
if ((p&0x80)==gc_tagNew) return; x->mmInfo|= 0x80;
x->mmInfo = p^0x80;
#ifdef LOG_GC #ifdef LOG_GC
gc_visitBytes+= mm_size(x); gc_visitCount++; gc_visitBytes+= mm_size(x); gc_visitCount++;
#endif #endif

View File

@ -30,7 +30,7 @@ static void* BN(allocL)(i64 bucket, u8 type) {
x->flags = x->extra = x->type = x->mmInfo = 0; x->flags = x->extra = x->type = x->mmInfo = 0;
x->refc = 1; x->refc = 1;
x->type = type; x->type = type;
x->mmInfo = bucket | gc_tagCurr; x->mmInfo = bucket;
#if defined(DEBUG) && !defined(DONT_FREE) #if defined(DEBUG) && !defined(DONT_FREE)
u64* p = (u64*)x; u64* p = (u64*)x;
u64* s = p + sizeof(Value)/8; u64* s = p + sizeof(Value)/8;