RT_VERIFY
This commit is contained in:
parent
f4ec365a3e
commit
6b4c5913ff
@ -3,8 +3,8 @@ build/run:
|
|||||||
1. `./genRuntime path/to/mlochbaum/BQN`
|
1. `./genRuntime path/to/mlochbaum/BQN`
|
||||||
2. Optionally choose what to build by changing `src/h.h`
|
2. Optionally choose what to build by changing `src/h.h`
|
||||||
3. `make`
|
3. `make`
|
||||||
- Options: `make o3`, `make debug` (`make rtperf` and `make heapverify` may also be useful)
|
- 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
|
- 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
|
- `./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)
|
4. `./BQN` (or `rlwrap ./BQN` for a fancier interface)
|
||||||
|
|
||||||
|
|||||||
6
makefile
6
makefile
@ -9,6 +9,8 @@ rtperf:
|
|||||||
@$(MAKE) $(J) -C obj/rtperf rtperf
|
@$(MAKE) $(J) -C obj/rtperf rtperf
|
||||||
heapverify:
|
heapverify:
|
||||||
@$(MAKE) $(J) -C obj/heapverify heapverify
|
@$(MAKE) $(J) -C obj/heapverify heapverify
|
||||||
|
rtverify:
|
||||||
|
@$(MAKE) $(J) -C obj/rtverify rtverify
|
||||||
|
|
||||||
o3-clean:
|
o3-clean:
|
||||||
@$(MAKE) -C obj/o3 clean
|
@$(MAKE) -C obj/o3 clean
|
||||||
@ -18,5 +20,7 @@ rtperf-clean:
|
|||||||
@$(MAKE) -C obj/rtperf clean
|
@$(MAKE) -C obj/rtperf clean
|
||||||
heapverify-clean:
|
heapverify-clean:
|
||||||
@$(MAKE) -C obj/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
|
rtperf: gen
|
||||||
heapverify: FLAGS=-DDEBUG -g -DHEAP_VERIFY
|
heapverify: FLAGS=-DDEBUG -g -DHEAP_VERIFY
|
||||||
heapverify: gen
|
heapverify: gen
|
||||||
|
rtverify: FLAGS=-O3 -DRT_VERIFY
|
||||||
|
rtverify: gen
|
||||||
|
|
||||||
gen: builtins core base utils
|
gen: builtins core base utils
|
||||||
@$(CC) -o BQN *.o -lm
|
@$(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-
|
@echo $< | cut -c 11-
|
||||||
@$(CMD) $@.d -c $<
|
@$(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
|
%.o: ../../src/%.c
|
||||||
@echo $< | cut -c 11-
|
@echo $< | cut -c 11-
|
||||||
@$(CMD) $@.d -c $<
|
@$(CMD) $@.d -c $<
|
||||||
|
|||||||
@ -99,14 +99,14 @@ B scan_c1(B d, B x) { B f = c(Md1D,d)->f;
|
|||||||
i64 c = 0;
|
i64 c = 0;
|
||||||
for (usz i = 0; i < ia; i++) {
|
for (usz i = 0; i < ia; i++) {
|
||||||
rp[i] = c+= xp[i];
|
rp[i] = c+= xp[i];
|
||||||
if (c>I32_MAX) goto base;
|
if (c>I32_MAX) { dec(r); goto base; }
|
||||||
}
|
}
|
||||||
dec(x);
|
dec(x);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (rtid==7) {
|
if (rtid==7) {
|
||||||
i32* rp; B r = m_i32arrv(&rp, ia);
|
i32* rp; B r = m_i32arrv(&rp, ia);
|
||||||
i32 c = 0;
|
i32 c = I32_MIN;
|
||||||
for (usz i = 0; i < ia; i++) {
|
for (usz i = 0; i < ia; i++) {
|
||||||
if (xp[i]>c) c = xp[i];
|
if (xp[i]>c) c = xp[i];
|
||||||
rp[i] = c;
|
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;
|
i64 c = wv;
|
||||||
for (usz i = 0; i < ia; i++) {
|
for (usz i = 0; i < ia; i++) {
|
||||||
rp[i] = c+= xp[i];
|
rp[i] = c+= xp[i];
|
||||||
if (c>I32_MAX) goto base;
|
if (c>I32_MAX) { dec(r); goto base; }
|
||||||
}
|
}
|
||||||
dec(x);
|
dec(x);
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@ -21,6 +21,10 @@
|
|||||||
#include "core/fillarr.h"
|
#include "core/fillarr.h"
|
||||||
#include "core/derv.h"
|
#include "core/derv.h"
|
||||||
|
|
||||||
|
#ifdef RT_VERIFY
|
||||||
|
extern B r1Objs[rtLen];
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct BFn {
|
typedef struct BFn {
|
||||||
struct Fun;
|
struct Fun;
|
||||||
B ident;
|
B ident;
|
||||||
|
|||||||
@ -231,7 +231,6 @@ i32 compare(B w, B x) {
|
|||||||
#undef CMP
|
#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)
|
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(isF64(w)&isF64(x)) return w.f==x.f;
|
||||||
if (w.u==x.u) return true;
|
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; }
|
if (o2i(wdp[0])<=1) { dec(wd);dec(xd); return false; }
|
||||||
usz wia = a(wd)->ia;
|
usz wia = a(wd)->ia;
|
||||||
if (wia!=a(xd)->ia) { dec(wd);dec(xd); return false; }
|
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 false; }
|
||||||
dec(wd);dec(xd); return true;
|
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;
|
for (usz i = 0; i < ia; i++) if(!equal(wgetU(w,i),xgetU(x,i))) return false;
|
||||||
return true;
|
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
|
u64 depth(B x) { // doesn't consume
|
||||||
if (isAtm(x)) return 0;
|
if (isAtm(x)) return 0;
|
||||||
if (TI(x).arrD1) return 1;
|
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_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_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";
|
case t_freed:return"(freed by GC)"; case t_harrPartial:return"partHarr";
|
||||||
#ifdef RT_PERF
|
#ifdef RT_WRAP
|
||||||
case t_funPerf:return"perf fn"; case t_md1Perf:return"perf m1"; case t_md2Perf:return "perf m2";
|
case t_funWrap:return"wrapped function"; case t_md1Wrap:return"wrapped 1-modifier"; case t_md2Wrap:return "wrapped 2-modifier";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/h.h
13
src/h.h
@ -26,6 +26,7 @@
|
|||||||
// #define FORMATTER // use self-hosted formatter for output
|
// #define FORMATTER // use self-hosted formatter for output
|
||||||
// #define TIME // output runtime of every expression
|
// #define TIME // output runtime of every expression
|
||||||
// #define RT_PERF // time runtime primitives
|
// #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
|
// #define NO_COMP // don't load the compiler, instead execute src/interp; needed for ./precompiled.bqn
|
||||||
|
|
||||||
|
|
||||||
@ -42,6 +43,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define rtLen 63
|
#define rtLen 63
|
||||||
|
|
||||||
#ifdef CATCH_ERRORS
|
#ifdef CATCH_ERRORS
|
||||||
#define PROPER_FILLS (EACH_FILLS&SFNS_FILLS)
|
#define PROPER_FILLS (EACH_FILLS&SFNS_FILLS)
|
||||||
#else
|
#else
|
||||||
@ -49,6 +51,12 @@
|
|||||||
#define EACH_FILLS false
|
#define EACH_FILLS false
|
||||||
#define PROPER_FILLS false
|
#define PROPER_FILLS false
|
||||||
#endif
|
#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 i8 int8_t
|
||||||
#define u8 uint8_t
|
#define u8 uint8_t
|
||||||
@ -127,8 +135,8 @@ enum Type {
|
|||||||
/*25*/ t_comp, t_block, t_body, t_scope,
|
/*25*/ t_comp, t_block, t_body, t_scope,
|
||||||
/*29*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp,
|
/*29*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp,
|
||||||
/*34*/ t_freed, t_harrPartial,
|
/*34*/ t_freed, t_harrPartial,
|
||||||
#ifdef RT_PERF
|
#ifdef RT_WRAP
|
||||||
/*36*/ t_funPerf, t_md1Perf, t_md2Perf,
|
/*36*/ t_funWrap, t_md1Wrap, t_md2Wrap,
|
||||||
#endif
|
#endif
|
||||||
t_COUNT
|
t_COUNT
|
||||||
};
|
};
|
||||||
@ -257,6 +265,7 @@ void printRaw(B x); // doesn't consume
|
|||||||
void print(B x); // doesn't consume
|
void print(B x); // doesn't consume
|
||||||
void arr_print(B x); // doesn't consume
|
void arr_print(B x); // doesn't consume
|
||||||
bool equal(B w, 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)
|
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
|
bool atomEqual(B w, B x); // doesn't consume
|
||||||
u64 depth(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
|
#undef F
|
||||||
TypeInfo ti[t_COUNT];
|
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_currPath;
|
||||||
_Thread_local B comp_currArgs;
|
_Thread_local B comp_currArgs;
|
||||||
@ -154,6 +156,9 @@ static inline void load_init() {
|
|||||||
rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell);
|
rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell);
|
||||||
|
|
||||||
for (usz i = 0; i < rtLen; i++) {
|
for (usz i = 0; i < rtLen; i++) {
|
||||||
|
#ifdef RT_WRAP
|
||||||
|
r1Objs[i] = rtObjGet(rtObjRaw, i); gc_add(r1Objs[i]);
|
||||||
|
#endif
|
||||||
#ifdef ALL_R1
|
#ifdef ALL_R1
|
||||||
B r = rtObjGet(rtObjRaw, i);
|
B r = rtObjGet(rtObjRaw, i);
|
||||||
#else
|
#else
|
||||||
@ -161,8 +166,8 @@ static inline void load_init() {
|
|||||||
#endif
|
#endif
|
||||||
if (isNothing(r)) { printf("· in runtime!\n"); exit(1); }
|
if (isNothing(r)) { printf("· in runtime!\n"); exit(1); }
|
||||||
if (isVal(r)) v(r)->flags|= i+1;
|
if (isVal(r)) v(r)->flags|= i+1;
|
||||||
#ifdef RT_PERF
|
#ifdef RT_WRAP
|
||||||
r = rtPerf_wrap(r);
|
r = rtWrap_wrap(r);
|
||||||
if (isVal(r)) v(r)->flags|= i+1;
|
if (isVal(r)) v(r)->flags|= i+1;
|
||||||
#endif
|
#endif
|
||||||
runtimeH.a[i] = r;
|
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
|
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();
|
#define F(X) void X##_init();
|
||||||
FOR_INIT(F)
|
FOR_INIT(F)
|
||||||
#undef F
|
#undef F
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// TODO these are hacks around not needing tiny headers
|
// TODO these are hacks around not needing tiny headers
|
||||||
Block* bqn_comp(B str, B path, B args);
|
Block* bqn_comp(B str, B path, B args);
|
||||||
void rtPerf_print();
|
void rtWrap_print();
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
cbqn_init();
|
cbqn_init();
|
||||||
@ -27,7 +27,7 @@ int main(int argc, char* argv[]) {
|
|||||||
#ifdef COMP_COMP_TIME
|
#ifdef COMP_COMP_TIME
|
||||||
gc_add(srcB);
|
gc_add(srcB);
|
||||||
for (i32 i = 0; i < 100; i++) { dec(bqn_exec(inc(srcB), bi_N, bi_N)); gc_maybeGC(); }
|
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)
|
CTR_FOR(CTR_PRINT)
|
||||||
exit(0);
|
exit(0);
|
||||||
#endif
|
#endif
|
||||||
@ -155,7 +155,7 @@ int main(int argc, char* argv[]) {
|
|||||||
#ifdef HEAP_VERIFY
|
#ifdef HEAP_VERIFY
|
||||||
heapVerify();
|
heapVerify();
|
||||||
#endif
|
#endif
|
||||||
rtPerf_print();
|
rtWrap_print();
|
||||||
CTR_FOR(CTR_PRINT)
|
CTR_FOR(CTR_PRINT)
|
||||||
// printf("done\n");fflush(stdout); while(1);
|
// printf("done\n");fflush(stdout); while(1);
|
||||||
printAllocStats();
|
printAllocStats();
|
||||||
|
|||||||
@ -20,6 +20,6 @@
|
|||||||
#include "../builtins/md2.c"
|
#include "../builtins/md2.c"
|
||||||
#include "../vm.c"
|
#include "../vm.c"
|
||||||
#include "../ns.c"
|
#include "../ns.c"
|
||||||
#include "../rtPerf.c"
|
#include "../rtwrap.c"
|
||||||
#include "../load.c"
|
#include "../load.c"
|
||||||
#include "../main.c"
|
#include "../main.c"
|
||||||
|
|||||||
@ -1,13 +1,19 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
#ifdef RT_PERF
|
|
||||||
|
#ifdef RT_WRAP
|
||||||
typedef struct WFun WFun;
|
typedef struct WFun WFun;
|
||||||
struct WFun {
|
struct WFun {
|
||||||
struct Fun;
|
struct Fun;
|
||||||
u64 c1t, c2t;
|
|
||||||
u32 c1a, c2a;
|
|
||||||
B v;
|
B v;
|
||||||
WFun* prev;
|
WFun* prev;
|
||||||
|
#ifdef RT_PERF
|
||||||
|
u64 c1t, c2t;
|
||||||
|
u32 c1a, c2a;
|
||||||
|
#else
|
||||||
|
B r1;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
WFun* lastWF;
|
WFun* lastWF;
|
||||||
void wf_visit(Value* x) { mm_visit(((WFun*)x)->v); }
|
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;
|
B f = c(WFun,x)->v;
|
||||||
return inc(TI(f).identity(f));
|
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;
|
u64 fwTotal;
|
||||||
B wf_c1(B t, B x) {
|
B wf_c1(B t, B x) {
|
||||||
WFun* c = c(WFun,t);
|
WFun* c = c(WFun,t);
|
||||||
B f = c->v;
|
B f = c->v;
|
||||||
BB2B fi = c(Fun,f)->c1;
|
BB2B fi = c(Fun,f)->c1;
|
||||||
u64 s = nsTime();
|
#ifdef RT_PERF
|
||||||
B r = fi(f, x);
|
u64 s = nsTime();
|
||||||
u64 e = nsTime();
|
B r = fi(f, x);
|
||||||
c->c1a++;
|
u64 e = nsTime();
|
||||||
c->c1t+= e-s;
|
c->c1a++;
|
||||||
fwTotal+= e-s+20;
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
B wf_c2(B t, B w, B x) {
|
B wf_c2(B t, B w, B x) {
|
||||||
WFun* c = c(WFun,t);
|
WFun* c = c(WFun,t);
|
||||||
B f = c->v;
|
B f = c->v;
|
||||||
BBB2B fi = c(Fun,f)->c2;
|
BBB2B fi = c(Fun,f)->c2;
|
||||||
u64 s = nsTime();
|
#ifdef RT_PERF
|
||||||
B r = fi(f, w, x);
|
u64 s = nsTime();
|
||||||
u64 e = nsTime();
|
B r = fi(f, w, x);
|
||||||
c->c2a++;
|
u64 e = nsTime();
|
||||||
c->c2t+= e-s;
|
c->c2a++;
|
||||||
fwTotal+= e-s+20;
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
#undef CHK
|
||||||
|
|
||||||
typedef struct WMd1 WMd1;
|
typedef struct WMd1 WMd1;
|
||||||
struct 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)) {
|
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)->extra = v(t)->extra;
|
||||||
c(Value,r)->flags = v(t)->flags;
|
c(Value,r)->flags = v(t)->flags;
|
||||||
c(Fun,r)->c1 = wf_c1;
|
c(Fun,r)->c1 = wf_c1;
|
||||||
c(Fun,r)->c2 = wf_c2;
|
c(Fun,r)->c2 = wf_c2;
|
||||||
c(WFun,r)->v = t;
|
c(WFun,r)->v = t;
|
||||||
c(WFun,r)->prev = lastWF;
|
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);
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
#ifdef RT_PERF
|
||||||
if (isMd1(t)) {
|
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)->extra = v(t)->extra;
|
||||||
c(Value,r)->flags = v(t)->flags;
|
c(Value,r)->flags = v(t)->flags;
|
||||||
c(Md1,r)->c1 = wm1_c1;
|
c(Md1,r)->c1 = wm1_c1;
|
||||||
@ -155,7 +183,7 @@ B rtPerf_wrap(B t) {
|
|||||||
}
|
}
|
||||||
if (isMd2(t)) {
|
if (isMd2(t)) {
|
||||||
Md2* fc = c(Md2,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)->c1 = wm2_c1;
|
||||||
c(Md2,r)->c2 = wm2_c2;
|
c(Md2,r)->c2 = wm2_c2;
|
||||||
c(Md2,r)->extra = fc->extra;
|
c(Md2,r)->extra = fc->extra;
|
||||||
@ -167,29 +195,10 @@ B rtPerf_wrap(B t) {
|
|||||||
lastWM2 = c(WMd2,r);
|
lastWM2 = c(WMd2,r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return t;
|
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); }
|
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_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); }
|
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() {
|
void rtWrap_init() {
|
||||||
ti[t_funPerf].visit = wf_visit; ti[t_funPerf].identity = wf_identity;
|
ti[t_funWrap].visit = wf_visit; ti[t_funWrap].identity = wf_identity;
|
||||||
ti[t_md1Perf].visit = wm1_visit; ti[t_md1Perf].m1_d = m_md1D;
|
ti[t_md1Wrap].visit = wm1_visit; ti[t_md1Wrap].m1_d = m_md1D;
|
||||||
ti[t_md2Perf].visit = wm2_visit; ti[t_md2Perf].m2_d = m_md2D;
|
ti[t_md2Wrap].visit = wm2_visit; ti[t_md2Wrap].m2_d = m_md2D;
|
||||||
ti[t_funPerf].fn_uc1 = wfn_uc1;
|
ti[t_funWrap].fn_uc1 = wfn_uc1;
|
||||||
ti[t_funPerf].fn_ucw = wfn_ucw;
|
ti[t_funWrap].fn_ucw = wfn_ucw;
|
||||||
ti[t_md1Perf].m1_uc1 = wm1_uc1;
|
ti[t_md1Wrap].m1_uc1 = wm1_uc1;
|
||||||
ti[t_md1Perf].m1_ucw = wm1_ucw;
|
ti[t_md1Wrap].m1_ucw = wm1_ucw;
|
||||||
ti[t_md2Perf].m2_uc1 = wm2_uc1;
|
ti[t_md2Wrap].m2_uc1 = wm2_uc1;
|
||||||
ti[t_md2Perf].m2_ucw = wm2_ucw;
|
ti[t_md2Wrap].m2_ucw = wm2_ucw;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void rtPerf_init() { }
|
void rtWrap_init() { }
|
||||||
void rtPerf_print() { }
|
|
||||||
#endif
|
#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 EQUAL(A,B) equal(A,B)
|
||||||
#define VALS
|
#define VALS
|
||||||
#define VT i32
|
#define VT i32
|
||||||
#include "hashmap.h"
|
#include "hashmapTemplate.h"
|
||||||
|
|
||||||
#define N(X) X##_Sb
|
#define N(X) X##_Sb
|
||||||
#define HT u64
|
#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 HDEF 0
|
||||||
#define KEYS
|
#define KEYS
|
||||||
#define EQUAL(A,B) equal(A,B)
|
#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--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NOINLINE void vm_pstLive(Env* s, Env* e) {
|
NOINLINE void vm_pstLive() {
|
||||||
vm_pst(envStart, envCurr);
|
vm_pst(envStart, envCurr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
5
src/vm.h
5
src/vm.h
@ -47,8 +47,9 @@ typedef struct Env {
|
|||||||
union { i32* bcL; i32 bcV; };
|
union { i32* bcL; i32 bcV; };
|
||||||
} Env;
|
} Env;
|
||||||
|
|
||||||
NOINLINE Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src);
|
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src);
|
||||||
NOINLINE void vm_pst(Env* s, Env* e);
|
void vm_pst(Env* s, Env* e);
|
||||||
|
void vm_pstLive();
|
||||||
|
|
||||||
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
|
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
|
||||||
typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block;
|
typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user