fix gc/refc issues, set memory to invalid objects on free in debug

This commit is contained in:
dzaima 2021-05-30 01:55:59 +03:00
parent 74fe1f1243
commit 16f379b6c7
4 changed files with 12 additions and 1 deletions

View File

@ -41,7 +41,9 @@ void gc_tryFree(Value* v) {
gc_freedBytes+= mm_size(v); gc_freedCount++;
#endif
v->type = t_freed;
ptr_inc(v); // required as otherwise the object may free itself while not done reading its own fields
ti[t].free(v);
ptr_dec(v);
// Object may not be immediately freed if it's not a part of a cycle, but instead a descendant of one.
// It will be freed when the cycle is freed, and the t_freed type ensures it doesn't double-free itself
}

View File

@ -25,6 +25,9 @@ NOINLINE EmptyValue* BN(makeEmpty)(u8 bucket) { // result->next is garbage
mm_heapAlloc+= sz;
// gc_maybeGC();
c = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0);
#ifdef USE_VALGRIND
VALGRIND_MAKE_MEM_UNDEFINED(c, sz);
#endif
if (alSize+1>=alCap) {
alCap = alCap? alCap*2 : 1024;
al = realloc(al, sizeof(AllocInfo)*alCap);

View File

@ -45,6 +45,12 @@ static void* BN(allocL)(u8 bucket, u8 type) {
x->flags = x->extra = x->type = 0;
x->refc = 1;
x->type = type;
#ifdef DEBUG
u64* p = (u64*)x;
u64* s = p + sizeof(Value)/8;
u64* e = p + BSZ(bucket)/8;
while(s<e) *s++ = tag(NULL, OBJ_TAG).u;
#endif
return x;
}

View File

@ -321,7 +321,7 @@ static NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd) {
if (upd) {
if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable");
dec(prev);
}
} else dec(prev);
sc->ext->vars[(u32)s.u] = inc(x);
} else {
VTY(s, t_harr);