switch to GCv2, various fixes/cleanup
includes: fixing some refcounts for FOR_BUILD build •FFI moving DEBUG_VM prints to stderr fixing heapverify reports of loose shape objects of fillarrs regular ol' adding-of-semicolon-after-label for old gcc move GC enable to after all initialization, not load_init
This commit is contained in:
parent
16274e5952
commit
c5aedaa414
@ -1326,7 +1326,7 @@ B transp_c1(B t, B x) {
|
|||||||
void* xp = tyany_ptr(x);
|
void* xp = tyany_ptr(x);
|
||||||
switch(xe) { default: UD;
|
switch(xe) { default: UD;
|
||||||
#if __BMI2__
|
#if __BMI2__
|
||||||
case el_bit:
|
case el_bit:;
|
||||||
u64* r0 = rp; TALLOC(u64, r1, BIT_N(h));
|
u64* r0 = rp; TALLOC(u64, r1, BIT_N(h));
|
||||||
for (usz i=0; i<BIT_N(ia); i++) {
|
for (usz i=0; i<BIT_N(ia); i++) {
|
||||||
u64 v = ((u64*)xp)[i];
|
u64 v = ((u64*)xp)[i];
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
#include "core/stuff.h"
|
#include "core/stuff.h"
|
||||||
#include "core/heap.h"
|
|
||||||
|
|
||||||
#if MM==0
|
#if MM==0
|
||||||
#include "opt/mm_malloc.h"
|
#include "opt/mm_malloc.h"
|
||||||
|
|||||||
@ -52,6 +52,7 @@ DEF_FREE(fillarr) {
|
|||||||
for (usz i = 0; i < ia; i++) dec(p[i]);
|
for (usz i = 0; i < ia; i++) dec(p[i]);
|
||||||
}
|
}
|
||||||
static void fillarr_visit(Value* x) { assert(PTY(x) == t_fillarr);
|
static void fillarr_visit(Value* x) { assert(PTY(x) == t_fillarr);
|
||||||
|
VISIT_SHAPE(x);
|
||||||
usz ia = PIA((Arr*)x); B* p = ((FillArr*)x)->a;
|
usz ia = PIA((Arr*)x); B* p = ((FillArr*)x)->a;
|
||||||
mm_visit(((FillArr*)x)->fill);
|
mm_visit(((FillArr*)x)->fill);
|
||||||
for (usz i = 0; i < ia; i++) mm_visit(p[i]);
|
for (usz i = 0; i < ia; i++) mm_visit(p[i]);
|
||||||
@ -60,7 +61,7 @@ static bool fillarr_canStore(B x) { return true; }
|
|||||||
|
|
||||||
static void fillarr_freeT(Value* x) { FillArr* s=(void*)x; dec(s->fill); decSh(x); mm_free(x); }
|
static void fillarr_freeT(Value* x) { FillArr* s=(void*)x; dec(s->fill); decSh(x); mm_free(x); }
|
||||||
|
|
||||||
static void fillslice_visit(Value* x) { FillSlice* s=(void*)x; mm_visitP(s->p); mm_visit(s->fill); }
|
static void fillslice_visit(Value* x) { FillSlice* s=(void*)x; mm_visitP(s->p); mm_visit(s->fill); VISIT_SHAPE(x); }
|
||||||
static void fillslice_freeO(Value* x) { FillSlice* s=(void*)x; ptr_dec(s->p); dec(s->fill); decSh(x); }
|
static void fillslice_freeO(Value* x) { FillSlice* s=(void*)x; ptr_dec(s->p); dec(s->fill); decSh(x); }
|
||||||
static void fillslice_freeF(Value* x) { fillslice_freeO(x); mm_free(x); }
|
static void fillslice_freeF(Value* x) { fillslice_freeO(x); mm_free(x); }
|
||||||
|
|
||||||
|
|||||||
@ -19,33 +19,14 @@ void heapVerify_checkFn(Value* v) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void heapVerify_callVisit(Value* v) {
|
|
||||||
if (TIv(v,isArr) && PRNK(v)>1) heapVerify_visitP(shObjP(v));
|
|
||||||
TIv(v,visit)(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void heap_getReferents(Value* v) {
|
|
||||||
heap_curr = v;
|
|
||||||
if (TIv(v,isArr) && PRNK(v)>1) heapVerify_visitP(shObjP(v));
|
|
||||||
TIv(v,visit)(v);
|
|
||||||
}
|
|
||||||
void gc_visitRoots(void);
|
void gc_visitRoots(void);
|
||||||
void gcv2_runHeapverify(i32);
|
void gcv2_runHeapverify(i32);
|
||||||
void heapVerify() {
|
void cbqn_heapVerify() {
|
||||||
heap_observed = 0;
|
heap_observed = 0;
|
||||||
#if GC_VISIT_V2
|
|
||||||
gcv2_runHeapverify(0);
|
gcv2_runHeapverify(0);
|
||||||
mm_forHeap(heapVerify_checkFn);
|
mm_forHeap(heapVerify_checkFn);
|
||||||
gcv2_runHeapverify(1);
|
gcv2_runHeapverify(1);
|
||||||
#else
|
if (heap_observed) printf("refc of last: %d\n", heap_observed->refc);
|
||||||
heapVerify_mode=0; mm_forHeap(heapVerify_callVisit); gc_visitRoots();
|
|
||||||
mm_forHeap(heapVerify_checkFn);
|
|
||||||
heapVerify_mode=1; mm_forHeap(heapVerify_callVisit); gc_visitRoots();
|
|
||||||
#endif
|
|
||||||
if (heap_observed) {
|
|
||||||
printf("refc of last: %d\n", heap_observed->refc);
|
|
||||||
// heapVerify_mode=2; mm_forHeap(heap_getReferents);
|
|
||||||
}
|
|
||||||
heapVerify_mode=-1;
|
heapVerify_mode=-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +78,7 @@ void heap_printInfo(bool sizes, bool types, bool freed, bool chain) {
|
|||||||
for (i32 i = 2; i < 64; i++) {
|
for (i32 i = 2; i < 64; i++) {
|
||||||
for (i32 j = 0; j < MM; j++) {
|
for (i32 j = 0; j < MM; j++) {
|
||||||
i32 o = i-j;
|
i32 o = i-j;
|
||||||
ux cf=0, cc=0;
|
u64 cf=0, cc=0;
|
||||||
if (freed) {
|
if (freed) {
|
||||||
cf = heap_PIFreed[o + j*64];
|
cf = heap_PIFreed[o + j*64];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
u64 mm_heapUsed(void);
|
|
||||||
|
|
||||||
#ifdef HEAP_VERIFY
|
|
||||||
|
|
||||||
extern u32 heapVerify_mode;
|
|
||||||
extern Value* heap_observed;
|
|
||||||
extern Value* heap_curr;
|
|
||||||
static bool heapVerify_visit(B x) {
|
|
||||||
if (heapVerify_mode==-1) return false;
|
|
||||||
if (isVal(x)) mm_visitP(v(x));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool heapVerify_visitP(void* x) {
|
|
||||||
if(heapVerify_mode==-1) return false;
|
|
||||||
Value* v = x;
|
|
||||||
if (heapVerify_mode==0) v->refc--;
|
|
||||||
else if(heapVerify_mode==1) v->refc++;
|
|
||||||
else if(heapVerify_mode==2) if (x==heap_observed) { printf("referee: %p ", heap_curr); printI(tag(heap_curr,OBJ_TAG)); putchar('\n'); }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void heapVerify(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -44,7 +44,7 @@ NOINLINE B c2F(B f, B w, B x) { dec(w); dec(x);
|
|||||||
NOINLINE void value_freeF(Value* x) { value_free(x); }
|
NOINLINE void value_freeF(Value* x) { value_free(x); }
|
||||||
NOINLINE void decA_F(B x) { dec(x); }
|
NOINLINE void decA_F(B x) { dec(x); }
|
||||||
void noop_visit(Value* x) { }
|
void noop_visit(Value* x) { }
|
||||||
#if HEAP_VERIFY && GC_VISIT_V2
|
#if HEAP_VERIFY
|
||||||
void arr_visit(Value* x) { VISIT_SHAPE(x); }
|
void arr_visit(Value* x) { VISIT_SHAPE(x); }
|
||||||
#endif
|
#endif
|
||||||
NOINLINE B c1_bad(B f, B x) { thrM("This function can't be called monadically"); }
|
NOINLINE B c1_bad(B f, B x) { thrM("This function can't be called monadically"); }
|
||||||
|
|||||||
@ -222,7 +222,7 @@ B def_fn_ix(B t, B w, B x);
|
|||||||
|
|
||||||
B def_decompose(B x);
|
B def_decompose(B x);
|
||||||
void noop_visit(Value* x);
|
void noop_visit(Value* x);
|
||||||
#if HEAP_VERIFY && GC_VISIT_V2
|
#if HEAP_VERIFY
|
||||||
void arr_visit(Value* x);
|
void arr_visit(Value* x);
|
||||||
#define VISIT_SHAPE(X) ({ if (PRNK(X)>1) mm_visitP(shObjP(X)); })
|
#define VISIT_SHAPE(X) ({ if (PRNK(X)>1) mm_visitP(shObjP(X)); })
|
||||||
#else
|
#else
|
||||||
|
|||||||
29
src/ffi.c
29
src/ffi.c
@ -939,6 +939,7 @@ void ffi_init(void) {
|
|||||||
switch (id) { default: err("bad id");
|
switch (id) { default: err("bad id");
|
||||||
case 0: {
|
case 0: {
|
||||||
char* s = toCStr(x);
|
char* s = toCStr(x);
|
||||||
|
decG(x);
|
||||||
i32 r = chdir(s);
|
i32 r = chdir(s);
|
||||||
freeCStr(s);
|
freeCStr(s);
|
||||||
return m_f64(r);
|
return m_f64(r);
|
||||||
@ -954,30 +955,34 @@ void ffi_init(void) {
|
|||||||
return m_vec2(m_f64(r), m_vec2(m_f64(vs[0]), m_f64(vs[1])));
|
return m_vec2(m_f64(r), m_vec2(m_f64(vs[0]), m_f64(vs[1])));
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
SGetU(x)
|
SGet(x)
|
||||||
int fd = o2i(GetU(x,0));
|
int fd = o2i(Get(x,0));
|
||||||
I8Arr* buf = cpyI8Arr(GetU(x,1));
|
I8Arr* buf = cpyI8Arr(Get(x,1));
|
||||||
usz maxlen = o2s(GetU(x,2));
|
usz maxlen = o2s(Get(x,2));
|
||||||
|
decG(x);
|
||||||
assert(PIA(buf)==maxlen);
|
assert(PIA(buf)==maxlen);
|
||||||
int res = read(fd, buf->a, maxlen);
|
int res = read(fd, buf->a, maxlen);
|
||||||
return m_vec2(m_f64(res), taga(buf));
|
return m_vec2(m_f64(res), taga(buf));
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
SGetU(x)
|
SGet(x)
|
||||||
int fd = o2i(GetU(x,0));
|
int fd = o2i(Get(x,0));
|
||||||
I8Arr* buf = cpyI8Arr(GetU(x,1));
|
I8Arr* buf = cpyI8Arr(Get(x,1));
|
||||||
usz maxlen = o2s(GetU(x,2));
|
usz maxlen = o2s(Get(x,2));
|
||||||
|
decG(x);
|
||||||
int res = write(fd, buf->a, maxlen);
|
int res = write(fd, buf->a, maxlen);
|
||||||
|
ptr_dec(buf);
|
||||||
return m_f64(res);
|
return m_f64(res);
|
||||||
}
|
}
|
||||||
case 5: {
|
case 5: {
|
||||||
return m_f64(close(o2i(x)));
|
return m_f64(close(o2i(x)));
|
||||||
}
|
}
|
||||||
case 6: {
|
case 6: {
|
||||||
SGetU(x)
|
SGet(x)
|
||||||
I16Arr* buf = cpyI16Arr(GetU(x,0)); i16* a = (i16*)buf->a;
|
I16Arr* buf = cpyI16Arr(Get(x,0)); i16* a = (i16*)buf->a;
|
||||||
int nfds = o2i(GetU(x,1));
|
int nfds = o2i(Get(x,1));
|
||||||
int timeout = o2s(GetU(x,2));
|
int timeout = o2s(Get(x,2));
|
||||||
|
decG(x);
|
||||||
|
|
||||||
TALLOC(pollfd, ps, nfds)
|
TALLOC(pollfd, ps, nfds)
|
||||||
for (i32 i = 0; i < nfds; i++) ps[i] = (pollfd){.fd = a[i*4+0]|a[i*4+1]<<16, .events=a[i*4+2]};
|
for (i32 i = 0; i < nfds; i++) ps[i] = (pollfd){.fd = a[i*4+0]|a[i*4+1]<<16, .events=a[i*4+2]};
|
||||||
|
|||||||
5
src/h.h
5
src/h.h
@ -46,7 +46,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #define HEAP_VERIFY // enable usage of heapVerify()
|
|
||||||
// #define ALLOC_STAT // store basic allocation statistics
|
// #define ALLOC_STAT // store basic allocation statistics
|
||||||
// #define ALLOC_SIZES // store per-type allocation size statistics
|
// #define ALLOC_SIZES // store per-type allocation size statistics
|
||||||
// #define USE_VALGRIND // whether to mark freed memory for valgrind
|
// #define USE_VALGRIND // whether to mark freed memory for valgrind
|
||||||
@ -357,6 +356,10 @@ void gc_addFn(vfn f); // add function that calls mm_visit/mm_visitP for dynamic
|
|||||||
void gc_add_ref(B* x); // add x as a root reference
|
void gc_add_ref(B* x); // add x as a root reference
|
||||||
bool gc_maybeGC(bool toplevel); // gc if that seems necessary; returns if did gc
|
bool gc_maybeGC(bool toplevel); // gc if that seems necessary; returns if did gc
|
||||||
void gc_forceGC(bool toplevel); // force a gc; who knows what happens if gc is disabled (probably should error)
|
void gc_forceGC(bool toplevel); // force a gc; who knows what happens if gc is disabled (probably should error)
|
||||||
|
u64 mm_heapUsed(void);
|
||||||
|
#if HEAP_VERIFY
|
||||||
|
void cbqn_heapVerify(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
// some primitive actions
|
// some primitive actions
|
||||||
static const B bi_N = b((u64)0x7FF2000000000000ull); // tag(0,TAG_TAG); // make gcc happy
|
static const B bi_N = b((u64)0x7FF2000000000000ull); // tag(0,TAG_TAG); // make gcc happy
|
||||||
|
|||||||
@ -512,8 +512,8 @@ void load_init() { // very last init function
|
|||||||
printI(interp);
|
printI(interp);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
dec(interp);
|
dec(interp);
|
||||||
#ifdef HEAP_VERIFY
|
#if HEAP_VERIFY
|
||||||
heapVerify();
|
cbqn_heapVerify();
|
||||||
#endif
|
#endif
|
||||||
rtWrap_print();
|
rtWrap_print();
|
||||||
CTR_FOR(CTR_PRINT)
|
CTR_FOR(CTR_PRINT)
|
||||||
@ -551,7 +551,6 @@ void load_init() { // very last init function
|
|||||||
decG(fmtR);
|
decG(fmtR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gc_enable();
|
|
||||||
#endif // PRECOMP
|
#endif // PRECOMP
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,5 +806,6 @@ void cbqn_init() {
|
|||||||
FOR_INIT(F)
|
FOR_INIT(F)
|
||||||
#undef F
|
#undef F
|
||||||
cbqn_initialized = true;
|
cbqn_initialized = true;
|
||||||
|
gc_enable();
|
||||||
}
|
}
|
||||||
#undef FOR_INIT
|
#undef FOR_INIT
|
||||||
|
|||||||
16
src/main.c
16
src/main.c
@ -825,16 +825,16 @@ void cbqn_runLine(char* ln, i64 len) {
|
|||||||
fprintf(stderr, "Error: "); printErrMsg(thrownMsg); fputc('\n', stderr);
|
fprintf(stderr, "Error: "); printErrMsg(thrownMsg); fputc('\n', stderr);
|
||||||
vm_pst(envCurr+1, envStart+envPrevHeight);
|
vm_pst(envCurr+1, envStart+envPrevHeight);
|
||||||
freeThrown();
|
freeThrown();
|
||||||
#ifdef HEAP_VERIFY
|
#if HEAP_VERIFY
|
||||||
heapVerify();
|
cbqn_heapVerify();
|
||||||
#endif
|
#endif
|
||||||
gc_maybeGC(true);
|
gc_maybeGC(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cbqn_takeInterrupts(true);
|
cbqn_takeInterrupts(true);
|
||||||
cbqn_runLine0(ln, len);
|
cbqn_runLine0(ln, len);
|
||||||
#ifdef HEAP_VERIFY
|
#if HEAP_VERIFY
|
||||||
heapVerify();
|
cbqn_heapVerify();
|
||||||
#endif
|
#endif
|
||||||
gc_maybeGC(true);
|
gc_maybeGC(true);
|
||||||
cbqn_takeInterrupts(false);
|
cbqn_takeInterrupts(false);
|
||||||
@ -983,8 +983,8 @@ int main(int argc, char* argv[]) {
|
|||||||
execRes = bqn_execFile(src, args);
|
execRes = bqn_execFile(src, args);
|
||||||
}
|
}
|
||||||
dec(execRes);
|
dec(execRes);
|
||||||
#ifdef HEAP_VERIFY
|
#if HEAP_VERIFY
|
||||||
heapVerify();
|
cbqn_heapVerify();
|
||||||
#endif
|
#endif
|
||||||
gc_forceGC(true);
|
gc_forceGC(true);
|
||||||
}
|
}
|
||||||
@ -1045,8 +1045,8 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef HEAP_VERIFY
|
#if HEAP_VERIFY
|
||||||
heapVerify();
|
cbqn_heapVerify();
|
||||||
#endif
|
#endif
|
||||||
bqn_exit(0);
|
bqn_exit(0);
|
||||||
#undef INIT
|
#undef INIT
|
||||||
|
|||||||
24
src/opt/gc.c
24
src/opt/gc.c
@ -1,6 +1,9 @@
|
|||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
|
|
||||||
void mm_freeFreedAndMerge(void);
|
#if ENABLE_GC
|
||||||
|
static void mm_freeFreedAndMerge(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LOG_GC
|
#ifdef LOG_GC
|
||||||
#include "../utils/time.h"
|
#include "../utils/time.h"
|
||||||
#endif
|
#endif
|
||||||
@ -73,18 +76,21 @@ static void gc_tryFree(Value* v) {
|
|||||||
u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount, gc_unkRefsBytes, gc_unkRefsCount;
|
u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount, gc_unkRefsBytes, gc_unkRefsCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GC_VISIT_V2
|
|
||||||
i32 visit_mode;
|
i32 visit_mode;
|
||||||
enum {
|
enum {
|
||||||
GC_DEC_REFC, // decrement refcount
|
GC_DEC_REFC, // decrement refcount
|
||||||
GC_INC_REFC, // increment refcount
|
GC_INC_REFC, // increment refcount
|
||||||
GC_MARK, // if unmarked, mark & visit
|
GC_MARK, // if unmarked, mark & visit
|
||||||
GC_LISTBAD, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void gc_onVisit(Value* x) {
|
void gc_onVisit(Value* x) {
|
||||||
switch (visit_mode) { default: UD;
|
switch (visit_mode) { default: UD;
|
||||||
case GC_DEC_REFC: x->refc--; return;
|
case GC_DEC_REFC:
|
||||||
|
#if DEBUG
|
||||||
|
if(x->refc==0) err("decrementing refc 0");
|
||||||
|
#endif
|
||||||
|
x->refc--;
|
||||||
|
return;
|
||||||
case GC_INC_REFC: x->refc++; return;
|
case GC_INC_REFC: x->refc++; return;
|
||||||
case GC_MARK: {
|
case GC_MARK: {
|
||||||
if (x->mmInfo&0x80) return;
|
if (x->mmInfo&0x80) return;
|
||||||
@ -108,6 +114,7 @@ static void gc_tryFree(Value* v) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_GC
|
||||||
static Value** gcv2_bufS;
|
static Value** gcv2_bufS;
|
||||||
static Value** gcv2_bufC;
|
static Value** gcv2_bufC;
|
||||||
static Value** gcv2_bufE;
|
static Value** gcv2_bufE;
|
||||||
@ -157,13 +164,6 @@ static void gc_tryFree(Value* v) {
|
|||||||
free(gcv2_bufS);
|
free(gcv2_bufS);
|
||||||
}
|
}
|
||||||
|
|
||||||
mm_forHeap(gc_tryFree);
|
|
||||||
mm_freeFreedAndMerge();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void gc_run(bool toplevel) {
|
|
||||||
mm_forHeap(gc_resetTag);
|
|
||||||
gc_visitRoots();
|
|
||||||
mm_forHeap(gc_tryFree);
|
mm_forHeap(gc_tryFree);
|
||||||
mm_freeFreedAndMerge();
|
mm_freeFreedAndMerge();
|
||||||
}
|
}
|
||||||
@ -183,9 +183,7 @@ void gc_forceGC(bool toplevel) {
|
|||||||
u64 endSize = mm_heapUsed();
|
u64 endSize = mm_heapUsed();
|
||||||
#ifdef LOG_GC
|
#ifdef LOG_GC
|
||||||
fprintf(stderr, "GC kept "N64d"B/"N64d" objs, freed "N64d"B, incl. directly "N64d"B/"N64d" objs", gc_visitBytes, gc_visitCount, startSize-endSize, gc_freedBytes, gc_freedCount);
|
fprintf(stderr, "GC kept "N64d"B/"N64d" objs, freed "N64d"B, incl. directly "N64d"B/"N64d" objs", gc_visitBytes, gc_visitCount, startSize-endSize, gc_freedBytes, gc_freedCount);
|
||||||
#if GC_VISIT_V2
|
|
||||||
fprintf(stderr, "; unknown refs: "N64d"B/"N64d" objs", gc_unkRefsBytes, gc_unkRefsCount);
|
fprintf(stderr, "; unknown refs: "N64d"B/"N64d" objs", gc_unkRefsBytes, gc_unkRefsCount);
|
||||||
#endif
|
|
||||||
fprintf(stderr, "; took %.3fms\n", (nsTime()-start)/1e6);
|
fprintf(stderr, "; took %.3fms\n", (nsTime()-start)/1e6);
|
||||||
#endif
|
#endif
|
||||||
gc_lastAlloc = endSize;
|
gc_lastAlloc = endSize;
|
||||||
|
|||||||
30
src/opt/gc.h
30
src/opt/gc.h
@ -8,7 +8,6 @@ static void gc_enable() { gc_depth--; }
|
|||||||
extern u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount;
|
extern u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GC_VISIT_V2
|
|
||||||
extern void gc_onVisit(Value*);
|
extern void gc_onVisit(Value*);
|
||||||
static void mm_visit(B x) {
|
static void mm_visit(B x) {
|
||||||
if (isVal(x)) gc_onVisit(v(x));
|
if (isVal(x)) gc_onVisit(v(x));
|
||||||
@ -16,32 +15,3 @@ extern u64 gc_visitBytes, gc_visitCount, gc_freedBytes, gc_freedCount;
|
|||||||
static void mm_visitP(void* xp) {
|
static void mm_visitP(void* xp) {
|
||||||
gc_onVisit(xp);
|
gc_onVisit(xp);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void mm_visit(B x) {
|
|
||||||
#ifdef HEAP_VERIFY
|
|
||||||
if(heapVerify_visit(x)) return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!isVal(x)) return;
|
|
||||||
Value* vx = v(x);
|
|
||||||
if (vx->mmInfo&0x80) return;
|
|
||||||
vx->mmInfo|= 0x80;
|
|
||||||
#ifdef LOG_GC
|
|
||||||
gc_visitBytes+= mm_size(vx); gc_visitCount++;
|
|
||||||
#endif
|
|
||||||
TI(x,visit)(vx);
|
|
||||||
}
|
|
||||||
static void mm_visitP(void* xp) {
|
|
||||||
#ifdef HEAP_VERIFY
|
|
||||||
if(heapVerify_visitP(xp)) return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Value* x = (Value*)xp;
|
|
||||||
if (x->mmInfo&0x80) return;
|
|
||||||
x->mmInfo|= 0x80;
|
|
||||||
#ifdef LOG_GC
|
|
||||||
gc_visitBytes+= mm_size(x); gc_visitCount++;
|
|
||||||
#endif
|
|
||||||
TIv(x,visit)(x);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -47,7 +47,7 @@ void mm_forFreedHeap(V2v f) {
|
|||||||
b1_forFreedHeap(f);
|
b1_forFreedHeap(f);
|
||||||
b3_forFreedHeap(f);
|
b3_forFreedHeap(f);
|
||||||
}
|
}
|
||||||
void mm_freeFreedAndMerge() {
|
static void mm_freeFreedAndMerge() {
|
||||||
b1_freeFreedAndMerge();
|
b1_freeFreedAndMerge();
|
||||||
b3_freeFreedAndMerge();
|
b3_freeFreedAndMerge();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ FORCE_INLINE void BN(splitTo)(EmptyValue* c, i64 from, i64 to, bool notEqual) {
|
|||||||
buckets[from] = c;
|
buckets[from] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GC_VISIT_V2 && !BUDDY_NO_GC
|
#if !BUDDY_NO_GC && ENABLE_GC
|
||||||
static bool BN(allocMore_rec);
|
static bool BN(allocMore_rec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -44,12 +44,12 @@ static NOINLINE void* BN(allocateMore)(i64 bucket, u8 type, i64 from, i64 to) {
|
|||||||
u64 sz = BSZ(from);
|
u64 sz = BSZ(from);
|
||||||
CHECK_INTERRUPT;
|
CHECK_INTERRUPT;
|
||||||
|
|
||||||
#if GC_VISIT_V2 && !BUDDY_NO_GC
|
#if !BUDDY_NO_GC && ENABLE_GC
|
||||||
if (gc_maybeGC(false)) goto alloc_rec;
|
if (gc_maybeGC(false)) goto alloc_rec;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mm_heapAlloc+sz >= mm_heapMax) {
|
if (mm_heapAlloc+sz >= mm_heapMax) {
|
||||||
#if GC_VISIT_V2 && !BUDDY_NO_GC
|
#if !BUDDY_NO_GC && ENABLE_GC
|
||||||
if (!BN(allocMore_rec)) {
|
if (!BN(allocMore_rec)) {
|
||||||
gc_forceGC(false);
|
gc_forceGC(false);
|
||||||
BN(allocMore_rec) = true;
|
BN(allocMore_rec) = true;
|
||||||
@ -130,6 +130,7 @@ void BN(forFreedHeap)(V2v f) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if !BUDDY_NO_GC && ENABLE_GC
|
||||||
static void BN(freeFreedAndMerge)() {
|
static void BN(freeFreedAndMerge)() {
|
||||||
for (u64 i = 0; i < 64; i++) buckets[i] = NULL;
|
for (u64 i = 0; i < 64; i++) buckets[i] = NULL;
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ static void BN(freeFreedAndMerge)() {
|
|||||||
Value* e = (Value*)(ci.sz + (u8*)ci.p);
|
Value* e = (Value*)(ci.sz + (u8*)ci.p);
|
||||||
assert(c!=e);
|
assert(c!=e);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (vg_def_v(c->type)==t_freed) BN(freeLink)(c, false);
|
if (vg_def_v(c->type)==t_freed) mm_freeLink(c, false);
|
||||||
|
|
||||||
Value* next = (Value*)(BSZ(vg_def_v(c->mmInfo)&63) + (u8*)c);
|
Value* next = (Value*)(BSZ(vg_def_v(c->mmInfo)&63) + (u8*)c);
|
||||||
if (vg_def_v(c->type)==t_empty) {
|
if (vg_def_v(c->type)==t_empty) {
|
||||||
@ -159,6 +160,7 @@ static void BN(freeFreedAndMerge)() {
|
|||||||
.mmInfo = MMI(b),
|
.mmInfo = MMI(b),
|
||||||
.next = buckets[b]
|
.next = buckets[b]
|
||||||
};
|
};
|
||||||
|
vg_undef_p(cv, sizeof(EmptyValue));
|
||||||
buckets[b] = cv;
|
buckets[b] = cv;
|
||||||
|
|
||||||
emptyStart+= curr*MUL;
|
emptyStart+= curr*MUL;
|
||||||
@ -175,6 +177,7 @@ static void BN(freeFreedAndMerge)() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void writeNum(FILE* f, u64 v, i32 len);
|
void writeNum(FILE* f, u64 v, i32 len);
|
||||||
void BN(dumpHeap)(FILE* f) {
|
void BN(dumpHeap)(FILE* f) {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ static void gc_enable() { }
|
|||||||
static void mm_visit(B x) { }
|
static void mm_visit(B x) { }
|
||||||
static void mm_visitP(void* x) { }
|
static void mm_visitP(void* x) { }
|
||||||
|
|
||||||
void gc_maybeGC(bool);
|
bool gc_maybeGC(bool);
|
||||||
void gc_forceGC(bool);
|
void gc_forceGC(bool);
|
||||||
void mm_forHeap(V2v f);
|
void mm_forHeap(V2v f);
|
||||||
void mm_dumpHeap(FILE* f);
|
void mm_dumpHeap(FILE* f);
|
||||||
|
|||||||
14
src/vm.c
14
src/vm.c
@ -690,7 +690,7 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
|
|||||||
if (!vmStack) vmStack = malloc(400);
|
if (!vmStack) vmStack = malloc(400);
|
||||||
i32 stackNum = bcDepth>>1;
|
i32 stackNum = bcDepth>>1;
|
||||||
vmStack[stackNum] = -1;
|
vmStack[stackNum] = -1;
|
||||||
printf("new eval\n");
|
fprintf(stderr,"new eval\n");
|
||||||
B* origStack = gStack;
|
B* origStack = gStack;
|
||||||
#endif
|
#endif
|
||||||
u32* bc = b->bc;
|
u32* bc = b->bc;
|
||||||
@ -728,9 +728,9 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
|
|||||||
u32* sbc = bc;
|
u32* sbc = bc;
|
||||||
i32 bcPos = BCPOS(b,sbc);
|
i32 bcPos = BCPOS(b,sbc);
|
||||||
vmStack[stackNum] = bcPos;
|
vmStack[stackNum] = bcPos;
|
||||||
for(i32 i = 0; i < bcDepth; i++) printf(" ");
|
for(i32 i = 0; i < bcDepth; i++) fprintf(stderr," ");
|
||||||
print_BC(sbc,20); printf("@%d in: ", bcPos);
|
print_BC(stderr,sbc,20); fprintf(stderr,"@%d in: ",bcPos);
|
||||||
for (i32 i = 0; i < lgStack-origStack; i++) { if(i)printf("; "); printI(origStack[i]); } putchar('\n'); fflush(stdout);
|
for (i32 i = 0; i < lgStack-origStack; i++) { if(i)fprintf(stderr,"; "); fprintI(stderr,origStack[i]); } fputc('\n',stderr); fflush(stderr);
|
||||||
bcCtr++;
|
bcCtr++;
|
||||||
for (i32 i = 0; i < sc->varAm; i++) VALIDATE(sc->vars[i]);
|
for (i32 i = 0; i < sc->varAm; i++) VALIDATE(sc->vars[i]);
|
||||||
#endif
|
#endif
|
||||||
@ -930,9 +930,9 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
for(i32 i = 0; i < bcDepth; i++) printf(" ");
|
for(i32 i = 0; i < bcDepth; i++) fprintf(stderr," ");
|
||||||
print_BC(sbc,20); printf("@%d out: ", BCPOS(b, sbc));
|
print_BC(stderr,sbc,20); fprintf(stderr,"@%d out: ",BCPOS(b, sbc));
|
||||||
for (i32 i = 0; i < lgStack-origStack; i++) { if(i)printf("; "); printI(origStack[i]); } putchar('\n'); fflush(stdout);
|
for (i32 i = 0; i < lgStack-origStack; i++) { if(i)fprintf(stderr,"; "); fprintI(stderr,origStack[i]); } fputc('\n',stderr); fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
end:;
|
end:;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ make single-debug && ./BQN -p 2+2 || exit
|
|||||||
make heapverify && ./BQN -p 2+2 || exit
|
make heapverify && ./BQN -p 2+2 || exit
|
||||||
make rtverify && ./BQN -p 2+2 || exit
|
make rtverify && ./BQN -p 2+2 || exit
|
||||||
make rtperf && ./BQN -p 2+2 | head -2 || exit
|
make rtperf && ./BQN -p 2+2 | head -2 || exit
|
||||||
make f='-DDEBUG -DDEBUG_VM' c && ./BQN -p 2+2 | tail -2 || exit
|
make f='-DDEBUG -DDEBUG_VM' c && ./BQN -p 2+2 2>&1 | tail -2 || exit
|
||||||
make f='-DWARN_SLOW' c && ./BQN -p 2+2 2> /dev/null || exit
|
make f='-DWARN_SLOW' c && ./BQN -p 2+2 2> /dev/null || exit
|
||||||
make f='-DMM=0 -DENABLE_GC=0' c && ./BQN -p 2+2 || exit
|
make f='-DMM=0 -DENABLE_GC=0' c && ./BQN -p 2+2 || exit
|
||||||
make f='-DMM=1' c && ./BQN -p 2+2 || exit
|
make f='-DMM=1' c && ./BQN -p 2+2 || exit
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user