move GC tag resetting from alloc to another pass
This commit is contained in:
parent
a62a41249e
commit
b7f60ffb1c
14
src/opt/gc.c
14
src/opt/gc.c
@ -21,14 +21,12 @@ void gc_add(B x) {
|
||||
u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount;
|
||||
#endif
|
||||
|
||||
u8 gc_tagCurr = 0x80; // if no gc is running, this is what all objects will have
|
||||
u8 gc_tagNew = 0x00;
|
||||
void gc_tryFree(Value* v) {
|
||||
static void gc_tryFree(Value* v) {
|
||||
u8 t = v->type;
|
||||
#if defined(DEBUG) && !defined(CATCH_ERRORS)
|
||||
if (t==t_freed) err("GC found t_freed\n");
|
||||
#endif
|
||||
if (t!=t_empty & (v->mmInfo&0x80)==gc_tagCurr) {
|
||||
if (t!=t_empty && !(v->mmInfo&0x80)) {
|
||||
if (t==t_shape) return;
|
||||
#ifdef DONT_FREE
|
||||
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_rootObjSz; i++) mm_visit(gc_rootObjs[i]);
|
||||
}
|
||||
@ -63,10 +64,9 @@ void gc_forceGC() {
|
||||
gc_visitCount = 0; gc_freedCount = 0;
|
||||
u64 startSize = mm_heapUsed();
|
||||
#endif
|
||||
mm_forHeap(gc_resetTag);
|
||||
gc_visitRoots();
|
||||
mm_forHeap(gc_tryFree);
|
||||
gc_tagNew = gc_tagCurr;
|
||||
gc_tagCurr^= 0x80;
|
||||
u64 endSize = mm_heapUsed();
|
||||
#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);
|
||||
|
||||
12
src/opt/gc.h
12
src/opt/gc.h
@ -7,8 +7,6 @@ void gc_addFn(vfn f);
|
||||
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
|
||||
extern u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount;
|
||||
#endif
|
||||
@ -20,9 +18,8 @@ static void mm_visit(B x) {
|
||||
|
||||
if (!isVal(x)) return;
|
||||
Value* vx = v(x);
|
||||
u8 p = vx->mmInfo;
|
||||
if ((p&0x80)==gc_tagNew) return;
|
||||
vx->mmInfo = p^0x80;
|
||||
if (vx->mmInfo&0x80) return;
|
||||
vx->mmInfo|= 0x80;
|
||||
#ifdef LOG_GC
|
||||
gc_visitBytes+= mm_size(vx); gc_visitCount++;
|
||||
#endif
|
||||
@ -34,9 +31,8 @@ static void mm_visitP(void* xp) {
|
||||
#endif
|
||||
|
||||
Value* x = (Value*)xp;
|
||||
u8 p = x->mmInfo;
|
||||
if ((p&0x80)==gc_tagNew) return;
|
||||
x->mmInfo = p^0x80;
|
||||
if (x->mmInfo&0x80) return;
|
||||
x->mmInfo|= 0x80;
|
||||
#ifdef LOG_GC
|
||||
gc_visitBytes+= mm_size(x); gc_visitCount++;
|
||||
#endif
|
||||
|
||||
@ -30,7 +30,7 @@ static void* BN(allocL)(i64 bucket, u8 type) {
|
||||
x->flags = x->extra = x->type = x->mmInfo = 0;
|
||||
x->refc = 1;
|
||||
x->type = type;
|
||||
x->mmInfo = bucket | gc_tagCurr;
|
||||
x->mmInfo = bucket;
|
||||
#if defined(DEBUG) && !defined(DONT_FREE)
|
||||
u64* p = (u64*)x;
|
||||
u64* s = p + sizeof(Value)/8;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user