RT_VERIFY
This commit is contained in:
parent
f4ec365a3e
commit
6b4c5913ff
@ -3,8 +3,8 @@ build/run:
|
||||
1. `./genRuntime path/to/mlochbaum/BQN`
|
||||
2. Optionally choose what to build by changing `src/h.h`
|
||||
3. `make`
|
||||
- Options: `make o3`, `make debug` (`make rtperf` and `make heapverify` may also be useful)
|
||||
- Do `make clean` or `make [o3|debug]-clean` before to force recompile
|
||||
- Options: `make o3`, `make debug` (`make rtperf`, `make heapverify` and `make rtverify` also exist for further testing/debugging)
|
||||
- Do `make clean` or `make [o3|debug|…]-clean` before to force recompile
|
||||
- `./build` and `./debugBuild` compile everything at once and allow specifying extra compiler arguments, but may be slower
|
||||
4. `./BQN` (or `rlwrap ./BQN` for a fancier interface)
|
||||
|
||||
|
||||
6
makefile
6
makefile
@ -9,6 +9,8 @@ rtperf:
|
||||
@$(MAKE) $(J) -C obj/rtperf rtperf
|
||||
heapverify:
|
||||
@$(MAKE) $(J) -C obj/heapverify heapverify
|
||||
rtverify:
|
||||
@$(MAKE) $(J) -C obj/rtverify rtverify
|
||||
|
||||
o3-clean:
|
||||
@$(MAKE) -C obj/o3 clean
|
||||
@ -18,5 +20,7 @@ rtperf-clean:
|
||||
@$(MAKE) -C obj/rtperf clean
|
||||
heapverify-clean:
|
||||
@$(MAKE) -C obj/heapverify clean
|
||||
rtverify-clean:
|
||||
@$(MAKE) -C obj/rtverify clean
|
||||
|
||||
clean: o3-clean debug-clean rtperf-clean heapverify-clean
|
||||
clean: o3-clean debug-clean rtperf-clean heapverify-clean rtverify-clean
|
||||
|
||||
1
obj/rtverify/makefile
Symbolic link
1
obj/rtverify/makefile
Symbolic link
@ -0,0 +1 @@
|
||||
../subMakefile
|
||||
@ -13,6 +13,8 @@ rtperf: FLAGS=-O3 -DRT_PERF
|
||||
rtperf: gen
|
||||
heapverify: FLAGS=-DDEBUG -g -DHEAP_VERIFY
|
||||
heapverify: gen
|
||||
rtverify: FLAGS=-O3 -DRT_VERIFY
|
||||
rtverify: gen
|
||||
|
||||
gen: builtins core base utils
|
||||
@$(CC) -o BQN *.o -lm
|
||||
@ -24,7 +26,7 @@ core: i32arr.o c32arr.o f64arr.o harr.o fillarr.o stuff.o derv.o mm.o heap.o
|
||||
@echo $< | cut -c 11-
|
||||
@$(CMD) $@.d -c $<
|
||||
|
||||
base: load.o main.o rtPerf.o vm.o ns.o
|
||||
base: load.o main.o rtwrap.o vm.o ns.o
|
||||
%.o: ../../src/%.c
|
||||
@echo $< | cut -c 11-
|
||||
@$(CMD) $@.d -c $<
|
||||
|
||||
@ -99,14 +99,14 @@ B scan_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
i64 c = 0;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
rp[i] = c+= xp[i];
|
||||
if (c>I32_MAX) goto base;
|
||||
if (c>I32_MAX) { dec(r); goto base; }
|
||||
}
|
||||
dec(x);
|
||||
return r;
|
||||
}
|
||||
if (rtid==7) {
|
||||
i32* rp; B r = m_i32arrv(&rp, ia);
|
||||
i32 c = 0;
|
||||
i32 c = I32_MIN;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
if (xp[i]>c) c = xp[i];
|
||||
rp[i] = c;
|
||||
@ -155,7 +155,7 @@ B scan_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
||||
i64 c = wv;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
rp[i] = c+= xp[i];
|
||||
if (c>I32_MAX) goto base;
|
||||
if (c>I32_MAX) { dec(r); goto base; }
|
||||
}
|
||||
dec(x);
|
||||
return r;
|
||||
|
||||
@ -21,6 +21,10 @@
|
||||
#include "core/fillarr.h"
|
||||
#include "core/derv.h"
|
||||
|
||||
#ifdef RT_VERIFY
|
||||
extern B r1Objs[rtLen];
|
||||
#endif
|
||||
|
||||
typedef struct BFn {
|
||||
struct Fun;
|
||||
B ident;
|
||||
|
||||
@ -231,7 +231,6 @@ i32 compare(B w, B x) {
|
||||
#undef CMP
|
||||
|
||||
|
||||
static NOINLINE bool equalR(B w, B x) { return equal(w, x); }
|
||||
bool atomEqual(B w, B x) { // doesn't consume (not that that matters really currently)
|
||||
if(isF64(w)&isF64(x)) return w.f==x.f;
|
||||
if (w.u==x.u) return true;
|
||||
@ -244,7 +243,7 @@ bool atomEqual(B w, B x) { // doesn't consume (not that that matters really curr
|
||||
if (o2i(wdp[0])<=1) { dec(wd);dec(xd); return false; }
|
||||
usz wia = a(wd)->ia;
|
||||
if (wia!=a(xd)->ia) { dec(wd);dec(xd); return false; }
|
||||
for (i32 i = 0; i<wia; i++) if(!equalR(wdp[i], xdp[i]))
|
||||
for (i32 i = 0; i<wia; i++) if(!equal(wdp[i], xdp[i]))
|
||||
{ dec(wd);dec(xd); return false; }
|
||||
dec(wd);dec(xd); return true;
|
||||
}
|
||||
@ -260,6 +259,42 @@ bool equal(B w, B x) { // doesn't consume
|
||||
for (usz i = 0; i < ia; i++) if(!equal(wgetU(w,i),xgetU(x,i))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool atomEEqual(B w, B x) { // doesn't consume (not that that matters really currently)
|
||||
if (w.u==x.u) return true;
|
||||
if(isNum(w)|isNum(x)) return false;
|
||||
if (!isVal(w) | !isVal(x)) return false;
|
||||
if (v(w)->type!=v(x)->type) return false;
|
||||
B2B dcf = TI(w).decompose;
|
||||
if (dcf == def_decompose) return false;
|
||||
B wd=dcf(inc(w)); B* wdp = harr_ptr(wd);
|
||||
B xd=dcf(inc(x)); B* xdp = harr_ptr(xd);
|
||||
if (o2i(wdp[0])<=1) { dec(wd);dec(xd); return false; }
|
||||
usz wia = a(wd)->ia;
|
||||
if (wia!=a(xd)->ia) { dec(wd);dec(xd); return false; }
|
||||
for (i32 i = 0; i<wia; i++) if(!eequal(wdp[i], xdp[i]))
|
||||
{ dec(wd);dec(xd); return false; }
|
||||
dec(wd);dec(xd); return true;
|
||||
}
|
||||
bool eequal(B w, B x) { // doesn't consume
|
||||
if (w.u==x.u) return true;
|
||||
bool wa = isAtm(w);
|
||||
bool xa = isAtm(x);
|
||||
if (wa!=xa) return false;
|
||||
if (wa) return atomEEqual(w, x);
|
||||
// B wf = getFillQ(w);
|
||||
// B xf = getFillQ(x);
|
||||
// bool feq = eequal(wf, xf);
|
||||
// dec(wf); dec(xf);
|
||||
// if (!feq) return false;
|
||||
if (!eqShape(w,x)) return false;
|
||||
usz ia = a(x)->ia;
|
||||
BS2B xgetU = TI(x).getU;
|
||||
BS2B wgetU = TI(w).getU;
|
||||
for (usz i = 0; i < ia; i++) if(!eequal(wgetU(w,i),xgetU(x,i))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 depth(B x) { // doesn't consume
|
||||
if (isAtm(x)) return 0;
|
||||
if (TI(x).arrD1) return 1;
|
||||
@ -289,8 +324,8 @@ char* format_type(u8 u) {
|
||||
case t_comp:return"comp"; case t_block:return"block"; case t_body:return"body"; case t_scope:return"scope";
|
||||
case t_ns:return"ns"; case t_nsDesc:return"nsDesc"; case t_fldAlias:return"alias"; case t_hashmap:return"hashmap"; case t_temp:return"temporary";
|
||||
case t_freed:return"(freed by GC)"; case t_harrPartial:return"partHarr";
|
||||
#ifdef RT_PERF
|
||||
case t_funPerf:return"perf fn"; case t_md1Perf:return"perf m1"; case t_md2Perf:return "perf m2";
|
||||
#ifdef RT_WRAP
|
||||
case t_funWrap:return"wrapped function"; case t_md1Wrap:return"wrapped 1-modifier"; case t_md2Wrap:return "wrapped 2-modifier";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
13
src/h.h
13
src/h.h
@ -26,6 +26,7 @@
|
||||
// #define FORMATTER // use self-hosted formatter for output
|
||||
// #define TIME // output runtime of every expression
|
||||
// #define RT_PERF // time runtime primitives
|
||||
// #define RT_VERIFY // compare native and runtime versions of primitives
|
||||
// #define NO_COMP // don't load the compiler, instead execute src/interp; needed for ./precompiled.bqn
|
||||
|
||||
|
||||
@ -42,6 +43,7 @@
|
||||
#endif
|
||||
|
||||
#define rtLen 63
|
||||
|
||||
#ifdef CATCH_ERRORS
|
||||
#define PROPER_FILLS (EACH_FILLS&SFNS_FILLS)
|
||||
#else
|
||||
@ -49,6 +51,12 @@
|
||||
#define EACH_FILLS false
|
||||
#define PROPER_FILLS false
|
||||
#endif
|
||||
#if defined(RT_PERF) || defined(RT_VERIFY)
|
||||
#define RT_WRAP
|
||||
#if defined(RT_PERF) && defined(RT_VERIFY)
|
||||
#error "can't have both RT_PERF and RT_VERIFY"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define i8 int8_t
|
||||
#define u8 uint8_t
|
||||
@ -127,8 +135,8 @@ enum Type {
|
||||
/*25*/ t_comp, t_block, t_body, t_scope,
|
||||
/*29*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp,
|
||||
/*34*/ t_freed, t_harrPartial,
|
||||
#ifdef RT_PERF
|
||||
/*36*/ t_funPerf, t_md1Perf, t_md2Perf,
|
||||
#ifdef RT_WRAP
|
||||
/*36*/ t_funWrap, t_md1Wrap, t_md2Wrap,
|
||||
#endif
|
||||
t_COUNT
|
||||
};
|
||||
@ -257,6 +265,7 @@ void printRaw(B x); // doesn't consume
|
||||
void print(B x); // doesn't consume
|
||||
void arr_print(B x); // doesn't consume
|
||||
bool equal(B w, B x); // doesn't consume
|
||||
bool eequal(B w, B x); // doesn't consume
|
||||
i32 compare(B w, B x); // doesn't consume; -1 if w<x, 1 if w>x, 0 if w≡x; 0==compare(NaN,NaN)
|
||||
bool atomEqual(B w, B x); // doesn't consume
|
||||
u64 depth(B x); // doesn't consume
|
||||
|
||||
13
src/load.c
13
src/load.c
@ -14,7 +14,9 @@ FOR_PM2(F)
|
||||
#undef F
|
||||
TypeInfo ti[t_COUNT];
|
||||
|
||||
B rtPerf_wrap(B x); // consumes
|
||||
B r1Objs[rtLen];
|
||||
B rtWrap_wrap(B x); // consumes
|
||||
|
||||
|
||||
_Thread_local B comp_currPath;
|
||||
_Thread_local B comp_currArgs;
|
||||
@ -154,6 +156,9 @@ static inline void load_init() {
|
||||
rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell);
|
||||
|
||||
for (usz i = 0; i < rtLen; i++) {
|
||||
#ifdef RT_WRAP
|
||||
r1Objs[i] = rtObjGet(rtObjRaw, i); gc_add(r1Objs[i]);
|
||||
#endif
|
||||
#ifdef ALL_R1
|
||||
B r = rtObjGet(rtObjRaw, i);
|
||||
#else
|
||||
@ -161,8 +166,8 @@ static inline void load_init() {
|
||||
#endif
|
||||
if (isNothing(r)) { printf("· in runtime!\n"); exit(1); }
|
||||
if (isVal(r)) v(r)->flags|= i+1;
|
||||
#ifdef RT_PERF
|
||||
r = rtPerf_wrap(r);
|
||||
#ifdef RT_WRAP
|
||||
r = rtWrap_wrap(r);
|
||||
if (isVal(r)) v(r)->flags|= i+1;
|
||||
#endif
|
||||
runtimeH.a[i] = r;
|
||||
@ -272,7 +277,7 @@ static inline void base_init() {
|
||||
assert((MD1_TAG>>1) == (MD2_TAG>>1)); // just to be sure it isn't changed incorrectly, `isMd` depends on this
|
||||
}
|
||||
|
||||
#define FOR_INIT(F) F(base) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(hash) F(fns) F(sfns) F(arith) F(sort) F(md1) F(md2) F(sysfn) F(derv) F(comp) F(rtPerf) F(ns) F(load)
|
||||
#define FOR_INIT(F) F(base) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(hash) F(fns) F(sfns) F(arith) F(sort) F(md1) F(md2) F(sysfn) F(derv) F(comp) F(rtWrap) F(ns) F(load)
|
||||
#define F(X) void X##_init();
|
||||
FOR_INIT(F)
|
||||
#undef F
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
// TODO these are hacks around not needing tiny headers
|
||||
Block* bqn_comp(B str, B path, B args);
|
||||
void rtPerf_print();
|
||||
void rtWrap_print();
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
cbqn_init();
|
||||
@ -27,7 +27,7 @@ int main(int argc, char* argv[]) {
|
||||
#ifdef COMP_COMP_TIME
|
||||
gc_add(srcB);
|
||||
for (i32 i = 0; i < 100; i++) { dec(bqn_exec(inc(srcB), bi_N, bi_N)); gc_maybeGC(); }
|
||||
rtPerf_print();
|
||||
rtWrap_print();
|
||||
CTR_FOR(CTR_PRINT)
|
||||
exit(0);
|
||||
#endif
|
||||
@ -155,7 +155,7 @@ int main(int argc, char* argv[]) {
|
||||
#ifdef HEAP_VERIFY
|
||||
heapVerify();
|
||||
#endif
|
||||
rtPerf_print();
|
||||
rtWrap_print();
|
||||
CTR_FOR(CTR_PRINT)
|
||||
// printf("done\n");fflush(stdout); while(1);
|
||||
printAllocStats();
|
||||
|
||||
@ -20,6 +20,6 @@
|
||||
#include "../builtins/md2.c"
|
||||
#include "../vm.c"
|
||||
#include "../ns.c"
|
||||
#include "../rtPerf.c"
|
||||
#include "../rtwrap.c"
|
||||
#include "../load.c"
|
||||
#include "../main.c"
|
||||
|
||||
@ -1,13 +1,19 @@
|
||||
#include "core.h"
|
||||
#include "vm.h"
|
||||
|
||||
#ifdef RT_PERF
|
||||
|
||||
#ifdef RT_WRAP
|
||||
typedef struct WFun WFun;
|
||||
struct WFun {
|
||||
struct Fun;
|
||||
u64 c1t, c2t;
|
||||
u32 c1a, c2a;
|
||||
B v;
|
||||
WFun* prev;
|
||||
#ifdef RT_PERF
|
||||
u64 c1t, c2t;
|
||||
u32 c1a, c2a;
|
||||
#else
|
||||
B r1;
|
||||
#endif
|
||||
};
|
||||
WFun* lastWF;
|
||||
void wf_visit(Value* x) { mm_visit(((WFun*)x)->v); }
|
||||
@ -15,33 +21,47 @@ B wf_identity(B x) {
|
||||
B f = c(WFun,x)->v;
|
||||
return inc(TI(f).identity(f));
|
||||
}
|
||||
|
||||
#define CHK(A,B) { if (!eequal(A,B)) { print(f); printf(": failed RT_VERIFY\n"); vm_pstLive(); exit(1); } }
|
||||
u64 fwTotal;
|
||||
B wf_c1(B t, B x) {
|
||||
WFun* c = c(WFun,t);
|
||||
B f = c->v;
|
||||
BB2B fi = c(Fun,f)->c1;
|
||||
u64 s = nsTime();
|
||||
B r = fi(f, x);
|
||||
u64 e = nsTime();
|
||||
c->c1a++;
|
||||
c->c1t+= e-s;
|
||||
fwTotal+= e-s+20;
|
||||
#ifdef RT_PERF
|
||||
u64 s = nsTime();
|
||||
B r = fi(f, x);
|
||||
u64 e = nsTime();
|
||||
c->c1a++;
|
||||
c->c1t+= e-s;
|
||||
fwTotal+= e-s+20;
|
||||
#else
|
||||
B exp = c1(c->r1, inc(x));
|
||||
B r = fi(f, x);
|
||||
CHK(exp, r);
|
||||
dec(exp);
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
B wf_c2(B t, B w, B x) {
|
||||
WFun* c = c(WFun,t);
|
||||
B f = c->v;
|
||||
BBB2B fi = c(Fun,f)->c2;
|
||||
u64 s = nsTime();
|
||||
B r = fi(f, w, x);
|
||||
u64 e = nsTime();
|
||||
c->c2a++;
|
||||
c->c2t+= e-s;
|
||||
fwTotal+= e-s+20;
|
||||
#ifdef RT_PERF
|
||||
u64 s = nsTime();
|
||||
B r = fi(f, w, x);
|
||||
u64 e = nsTime();
|
||||
c->c2a++;
|
||||
c->c2t+= e-s;
|
||||
fwTotal+= e-s+20;
|
||||
#else
|
||||
B exp = c2(c->r1, inc(w), inc(x));
|
||||
B r = fi(f, w, x);
|
||||
CHK(exp, r);
|
||||
dec(exp);
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
#undef CHK
|
||||
|
||||
typedef struct WMd1 WMd1;
|
||||
struct WMd1 {
|
||||
@ -126,22 +146,30 @@ B wm2_c2(B d, B w, B x) { B f = c(Md2D,d)->f; B g = c(Md2D,d)->g; B t = c(Md2D,d
|
||||
|
||||
|
||||
|
||||
B rtPerf_wrap(B t) {
|
||||
B rtWrap_wrap(B t) {
|
||||
if (isFun(t)) {
|
||||
B r = mm_alloc(sizeof(WFun), t_funPerf, ftag(FUN_TAG));
|
||||
#ifdef RT_VERIFY
|
||||
if(v(t)->flags==0) return t;
|
||||
#endif
|
||||
B r = mm_alloc(sizeof(WFun), t_funWrap, ftag(FUN_TAG));
|
||||
c(Value,r)->extra = v(t)->extra;
|
||||
c(Value,r)->flags = v(t)->flags;
|
||||
c(Fun,r)->c1 = wf_c1;
|
||||
c(Fun,r)->c2 = wf_c2;
|
||||
c(WFun,r)->v = t;
|
||||
c(WFun,r)->prev = lastWF;
|
||||
c(WFun,r)->c1t = 0; c(WFun,r)->c1a = 0;
|
||||
c(WFun,r)->c2t = 0; c(WFun,r)->c2a = 0;
|
||||
lastWF = c(WFun,r);
|
||||
#ifdef RT_VERIFY
|
||||
c(WFun,r)->r1 = r1Objs[v(t)->flags-1];
|
||||
#else
|
||||
c(WFun,r)->c1t = 0; c(WFun,r)->c1a = 0;
|
||||
c(WFun,r)->c2t = 0; c(WFun,r)->c2a = 0;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
#ifdef RT_PERF
|
||||
if (isMd1(t)) {
|
||||
B r = mm_alloc(sizeof(WMd1), t_md1Perf, ftag(MD1_TAG));
|
||||
B r = mm_alloc(sizeof(WMd1), t_md1Wrap, ftag(MD1_TAG));
|
||||
c(Value,r)->extra = v(t)->extra;
|
||||
c(Value,r)->flags = v(t)->flags;
|
||||
c(Md1,r)->c1 = wm1_c1;
|
||||
@ -155,7 +183,7 @@ B rtPerf_wrap(B t) {
|
||||
}
|
||||
if (isMd2(t)) {
|
||||
Md2* fc = c(Md2,t);
|
||||
B r = mm_alloc(sizeof(WMd2), t_md2Perf, ftag(MD2_TAG));
|
||||
B r = mm_alloc(sizeof(WMd2), t_md2Wrap, ftag(MD2_TAG));
|
||||
c(Md2,r)->c1 = wm2_c1;
|
||||
c(Md2,r)->c2 = wm2_c2;
|
||||
c(Md2,r)->extra = fc->extra;
|
||||
@ -167,29 +195,10 @@ B rtPerf_wrap(B t) {
|
||||
lastWM2 = c(WMd2,r);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
|
||||
void rtPerf_print() {
|
||||
WFun* cf = lastWF;
|
||||
while (cf) {
|
||||
printRaw(c1(bi_fmtF, tag(cf,FUN_TAG)));
|
||||
printf(": m=%d %.3fms | d=%d %.3fms\n", cf->c1a, cf->c1t/1e6, cf->c2a, cf->c2t/1e6);
|
||||
cf = cf->prev;
|
||||
}
|
||||
WMd1* cm1 = lastWM1;
|
||||
while (cm1) {
|
||||
printRaw(c1(bi_fmtF, tag(cm1,MD1_TAG)));
|
||||
printf(": m=%d %.3fms | d=%d %.3fms\n", cm1->c1a, cm1->c1t/1e6, cm1->c2a, cm1->c2t/1e6);
|
||||
cm1 = cm1->prev;
|
||||
}
|
||||
WMd2* cm2 = lastWM2;
|
||||
while (cm2) {
|
||||
printRaw(c1(bi_fmtF, tag(cm2,MD2_TAG)));
|
||||
printf(": m=%d %.3fms | d=%d %.3fms\n", cm2->c1a, cm2->c1t/1e6, cm2->c2a, cm2->c2t/1e6);
|
||||
cm2 = cm2->prev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
B wfn_uc1(B t, B o, B x) { B t2 = c(WFun,t)->v; return TI(t2).fn_uc1(t2, o, x); }
|
||||
@ -199,18 +208,39 @@ B wm1_ucw(B t, B o, B f, B w, B x) { B t2 = c(WMd1,t)->v; return TI(t2).m1_
|
||||
B wm2_uc1(B t, B o, B f, B g, B x) { B t2 = c(WMd2,t)->v; return TI(t2).m2_uc1(t2, o, f, g, x); }
|
||||
B wm2_ucw(B t, B o, B f, B g, B w, B x) { B t2 = c(WMd2,t)->v; return TI(t2).m2_ucw(t2, o, f, g, w, x); }
|
||||
|
||||
void rtPerf_init() {
|
||||
ti[t_funPerf].visit = wf_visit; ti[t_funPerf].identity = wf_identity;
|
||||
ti[t_md1Perf].visit = wm1_visit; ti[t_md1Perf].m1_d = m_md1D;
|
||||
ti[t_md2Perf].visit = wm2_visit; ti[t_md2Perf].m2_d = m_md2D;
|
||||
ti[t_funPerf].fn_uc1 = wfn_uc1;
|
||||
ti[t_funPerf].fn_ucw = wfn_ucw;
|
||||
ti[t_md1Perf].m1_uc1 = wm1_uc1;
|
||||
ti[t_md1Perf].m1_ucw = wm1_ucw;
|
||||
ti[t_md2Perf].m2_uc1 = wm2_uc1;
|
||||
ti[t_md2Perf].m2_ucw = wm2_ucw;
|
||||
void rtWrap_init() {
|
||||
ti[t_funWrap].visit = wf_visit; ti[t_funWrap].identity = wf_identity;
|
||||
ti[t_md1Wrap].visit = wm1_visit; ti[t_md1Wrap].m1_d = m_md1D;
|
||||
ti[t_md2Wrap].visit = wm2_visit; ti[t_md2Wrap].m2_d = m_md2D;
|
||||
ti[t_funWrap].fn_uc1 = wfn_uc1;
|
||||
ti[t_funWrap].fn_ucw = wfn_ucw;
|
||||
ti[t_md1Wrap].m1_uc1 = wm1_uc1;
|
||||
ti[t_md1Wrap].m1_ucw = wm1_ucw;
|
||||
ti[t_md2Wrap].m2_uc1 = wm2_uc1;
|
||||
ti[t_md2Wrap].m2_ucw = wm2_ucw;
|
||||
}
|
||||
#else
|
||||
void rtPerf_init() { }
|
||||
void rtPerf_print() { }
|
||||
void rtWrap_init() { }
|
||||
#endif
|
||||
void rtWrap_print() {
|
||||
#ifdef RT_PERF
|
||||
WFun* cf = lastWF;
|
||||
while (cf) {
|
||||
printRaw(c1(bi_fmtF, tag(cf,FUN_TAG)));
|
||||
printf(": m=%d %.3fms | d=%d %.3fms\n", cf->c1a, cf->c1t/1e6, cf->c2a, cf->c2t/1e6);
|
||||
cf = cf->prev;
|
||||
}
|
||||
WMd1* cm1 = lastWM1;
|
||||
while (cm1) {
|
||||
printRaw(c1(bi_fmtF, tag(cm1,MD1_TAG)));
|
||||
printf(": m=%d %.3fms | d=%d %.3fms\n", cm1->c1a, cm1->c1t/1e6, cm1->c2a, cm1->c2t/1e6);
|
||||
cm1 = cm1->prev;
|
||||
}
|
||||
WMd2* cm2 = lastWM2;
|
||||
while (cm2) {
|
||||
printRaw(c1(bi_fmtF, tag(cm2,MD2_TAG)));
|
||||
printf(": m=%d %.3fms | d=%d %.3fms\n", cm2->c1a, cm2->c1t/1e6, cm2->c2a, cm2->c2t/1e6);
|
||||
cm2 = cm2->prev;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -53,7 +53,7 @@ static u64 bqn_hashP(B x, const u64 secret[4]) { // bqn_hash but never zero
|
||||
#define EQUAL(A,B) equal(A,B)
|
||||
#define VALS
|
||||
#define VT i32
|
||||
#include "hashmap.h"
|
||||
#include "hashmapTemplate.h"
|
||||
|
||||
#define N(X) X##_Sb
|
||||
#define HT u64
|
||||
@ -65,4 +65,4 @@ static u64 bqn_hashP(B x, const u64 secret[4]) { // bqn_hash but never zero
|
||||
#define HDEF 0
|
||||
#define KEYS
|
||||
#define EQUAL(A,B) equal(A,B)
|
||||
#include "hashmap.h"
|
||||
#include "hashmapTemplate.h"
|
||||
|
||||
2
src/vm.c
2
src/vm.c
@ -692,7 +692,7 @@ NOINLINE void vm_pst(Env* s, Env* e) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
NOINLINE void vm_pstLive(Env* s, Env* e) {
|
||||
NOINLINE void vm_pstLive() {
|
||||
vm_pst(envStart, envCurr);
|
||||
}
|
||||
|
||||
|
||||
5
src/vm.h
5
src/vm.h
@ -47,8 +47,9 @@ typedef struct Env {
|
||||
union { i32* bcL; i32 bcV; };
|
||||
} Env;
|
||||
|
||||
NOINLINE Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src);
|
||||
NOINLINE void vm_pst(Env* s, Env* e);
|
||||
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src);
|
||||
void vm_pst(Env* s, Env* e);
|
||||
void vm_pstLive();
|
||||
|
||||
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
|
||||
typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user