faster VM_POS
This commit is contained in:
parent
ffbb6ce601
commit
23af3f56e9
@ -14,7 +14,7 @@
|
||||
// #define ALL_R0 // use all of r0.bqn for runtime_0
|
||||
// #define ALL_R1 // use all of r1.bqn for runtime
|
||||
// #define RT_SRC // whether ./genRuntimeSrc was used to generate precompiled sources
|
||||
#define VM_POS false // whether to store detailed execution position information for stacktraces
|
||||
#define VM_POS true // whether to store detailed execution position information for stacktraces
|
||||
#define CHECK_VALID true // whether to check for valid arguments in places where that would be detrimental to performance (e.g. left argument sortedness of ⍋/⍒, incompatible changes in ⌾, etc)
|
||||
#define EACH_FILLS false // whether to try to squeeze out fills for ¨ and ⌜
|
||||
#define SFNS_FILLS true // whether to insert fills for structural functions (∾, ≍, etc)
|
||||
|
||||
61
src/vm.c
61
src/vm.c
@ -315,21 +315,17 @@ void gsPrint() {
|
||||
|
||||
typedef struct Env {
|
||||
Scope* sc;
|
||||
union { i32** bcP; i32* bcL; i32 bcV; };
|
||||
union { i32* bcL; i32 bcV; };
|
||||
} Env;
|
||||
|
||||
Env* envCurr;
|
||||
Env* envStart;
|
||||
Env* envEnd;
|
||||
|
||||
static inline void pushEnv(Scope* sc, i32** bc) {
|
||||
static inline void pushEnv(Scope* sc, i32* bc) {
|
||||
if (envCurr==envEnd) thrM("Stack overflow");
|
||||
envCurr->sc = sc;
|
||||
#if VM_POS
|
||||
envCurr->bcP = bc;
|
||||
#else
|
||||
envCurr->bcL = *bc;
|
||||
#endif
|
||||
envCurr->bcL = bc;
|
||||
envCurr++;
|
||||
}
|
||||
static inline void popEnv() {
|
||||
@ -348,7 +344,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
B* objs = b->comp->objs->a;
|
||||
Block** blocks = b->comp->blocks;
|
||||
i32* bc = b->bc;
|
||||
pushEnv(sc, &bc);
|
||||
pushEnv(sc, bc);
|
||||
gsReserve(b->maxStack);
|
||||
Scope* pscs[b->maxPSC+1];
|
||||
pscs[0] = sc;
|
||||
@ -365,6 +361,11 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
#define ADD(X) { *(lgStack++) = X; } // fine, as, if an error occurs, lgStack is ignored anyways
|
||||
#define GS_UPD { gStack = lgStack; }
|
||||
#endif
|
||||
#if VM_POS
|
||||
#define POS_UPD (envCurr-1)->bcL = bc-1;
|
||||
#else
|
||||
#define POS_UPD
|
||||
#endif
|
||||
|
||||
while(true) {
|
||||
#ifdef DEBUG_VM
|
||||
@ -384,22 +385,22 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
break;
|
||||
}
|
||||
case FN1C: { P(f)P(x)
|
||||
GS_UPD;
|
||||
GS_UPD;POS_UPD;
|
||||
ADD(c1(f, x); dec(f));
|
||||
break;
|
||||
}
|
||||
case FN1O: { P(f)P(x)
|
||||
GS_UPD;
|
||||
GS_UPD;POS_UPD;
|
||||
ADD(isNothing(x)? x : c1(f, x)); dec(f);
|
||||
break;
|
||||
}
|
||||
case FN2C: { P(w)P(f)P(x)
|
||||
GS_UPD;
|
||||
GS_UPD;POS_UPD;
|
||||
ADD(c2(f, w, x); dec(f));
|
||||
break;
|
||||
}
|
||||
case FN2O: { P(w)P(f)P(x)
|
||||
GS_UPD;
|
||||
GS_UPD;POS_UPD;
|
||||
if (isNothing(x)) { dec(w); ADD(x); }
|
||||
else ADD(isNothing(w)? c1(f, x) : c2(f, w, x));
|
||||
dec(f);
|
||||
@ -421,7 +422,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
break;
|
||||
}
|
||||
case DFND: {
|
||||
GS_UPD;
|
||||
GS_UPD;POS_UPD;
|
||||
Block* bl = blocks[*bc++];
|
||||
switch(bl->ty) { default: UD;
|
||||
case 0: ADD(m_funBlock(bl, sc)); break;
|
||||
@ -430,11 +431,11 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP1D: { P(f)P(m) GS_UPD; ADD(m1_d (m,f )); break; }
|
||||
case OP2D: { P(f)P(m)P(g) GS_UPD; ADD(m2_d (m,f,g)); break; }
|
||||
case OP2H: { P(m)P(g) ADD(m2_h (m, g)); break; }
|
||||
case TR2D: { P(g)P(h) ADD(m_atop( g,h)); break; }
|
||||
case TR3D: { P(f)P(g)P(h) ADD(m_fork(f,g,h)); break; }
|
||||
case OP1D: { P(f)P(m) GS_UPD;POS_UPD; ADD(m1_d (m,f )); break; }
|
||||
case OP2D: { P(f)P(m)P(g) GS_UPD;POS_UPD; ADD(m2_d (m,f,g)); break; }
|
||||
case OP2H: { P(m)P(g) ADD(m2_h (m, g)); break; }
|
||||
case TR2D: { P(g)P(h) ADD(m_atop( g,h)); break; }
|
||||
case TR3D: { P(f)P(g)P(h) ADD(m_fork(f,g,h)); break; }
|
||||
case TR3O: { P(f)P(g)P(h)
|
||||
if (isNothing(f)) { ADD(m_atop(g,h)); dec(f); }
|
||||
else ADD(m_fork(f,g,h));
|
||||
@ -446,7 +447,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
}
|
||||
case LOCO: { i32 d = *bc++; i32 p = *bc++;
|
||||
B l = pscs[d]->vars[p];
|
||||
if(l.u==bi_noVar.u) thrM("Reading variable before its defined");
|
||||
if(l.u==bi_noVar.u) { POS_UPD; thrM("Reading variable before its defined"); }
|
||||
ADD(inc(l));
|
||||
break;
|
||||
}
|
||||
@ -456,16 +457,16 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
vars[p] = bi_optOut;
|
||||
break;
|
||||
}
|
||||
case SETN: { P(s) P(x) GS_UPD; v_set(pscs, s, x, false); dec(s); ADD(x); break; }
|
||||
case SETU: { P(s) P(x) GS_UPD; v_set(pscs, s, x, true ); dec(s); ADD(x); break; }
|
||||
case SETM: { P(s)P(f)P(x) GS_UPD;
|
||||
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false); dec(s); ADD(x); break; }
|
||||
case SETU: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, true ); dec(s); ADD(x); break; }
|
||||
case SETM: { P(s)P(f)P(x) GS_UPD; POS_UPD;
|
||||
B w = v_get(pscs, s);
|
||||
B r = c2(f,w,x); dec(f);
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
ADD(r);
|
||||
break;
|
||||
}
|
||||
case FLDO: { P(ns) GS_UPD; i32 p = *bc++;
|
||||
case FLDO: { P(ns) GS_UPD; i32 p = *bc++; POS_UPD;
|
||||
if (!isNsp(ns)) thrM("Trying to read a field from non-namespace");
|
||||
ADD(inc(ns_getU(ns, sc->body->nsDesc->nameList, p)));
|
||||
dec(ns);
|
||||
@ -746,15 +747,11 @@ NOINLINE void vm_pst(Env* s, Env* e) {
|
||||
}
|
||||
|
||||
static void unwindEnv(Env* envNew) {
|
||||
assert(envNew<=envCurr);
|
||||
while (envCurr!=envNew) {
|
||||
envCurr--;
|
||||
#if VM_POS
|
||||
envCurr->bcV = *envCurr->bcP - i32arr_ptr(envCurr->sc->body->comp->bc) - 1;
|
||||
#else
|
||||
envCurr->bcV = envCurr->bcL - i32arr_ptr(envCurr->sc->body->comp->bc);
|
||||
#endif
|
||||
}
|
||||
assert(envNew<=envCurr);
|
||||
while (envCurr!=envNew) {
|
||||
envCurr--;
|
||||
envCurr->bcV = envCurr->bcL - i32arr_ptr(envCurr->sc->body->comp->bc);
|
||||
}
|
||||
}
|
||||
|
||||
NOINLINE NORETURN void thr(B msg) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user