From 3ebdb16571a39e3f0113f91b812652271aab90e9 Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 28 Apr 2021 23:33:45 +0300 Subject: [PATCH] ahead-of-time computed scope parents not much of a difference in performance, but whatever --- src/vm.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/vm.c b/src/vm.c index 6da882d6..88f82fe1 100644 --- a/src/vm.c +++ b/src/vm.c @@ -122,6 +122,7 @@ typedef struct Body { // B* objs; i32* bc; // pointer in comp->bc u32 maxStack; + u16 maxPSC; u16 varAm; // HArr* vNames; } Body; @@ -169,20 +170,23 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all i32* scan = cbc; i32 ssz = 0, mssz=0; + i32 mpsc = 0; while (*scan!=RETN & *scan!=RETD) { ssz+= stackDiff(scan); if (ssz>mssz) mssz = ssz; - if (*scan==LOCO | *scan==LOCM) { - if (scan[1]>U16_MAX) return c(Block,err("LOC_ too deep")); + if (*scan==LOCO | *scan==LOCM | *scan==LOCU) { + if (scan[1]>mpsc) mpsc = scan[1]; } scan = nextBC(scan); if (scan-bc >= bcl) return c(Block,err("no RETN/RETD found at end of bytecode")); } + if (mpsc>U16_MAX) thrM("LOC_ too deep"); Body* body = mm_allocN(sizeof(Body), t_body); body->comp = comp; body->bc = cbc; body->maxStack = mssz; + body->maxPSC = mpsc; body->varAm = vam; ptr_inc(comp); @@ -201,14 +205,9 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all return ret; } -Scope* scd(Scope* sc, u16 d) { - for (i32 i = 0; i < d; i++) sc = sc->psc; - return sc; -} - -void v_set(Scope* sc, B s, B x, bool upd) { // frees s, doesn't consume x +void v_set(Scope* pscs[], B s, B x, bool upd) { // frees s, doesn't consume x if (isVar(s)) { - sc = scd(sc, (u16)(s.u>>32)); + Scope* sc = pscs[(u16)(s.u>>32)]; B prev = sc->vars[(u32)s.u]; if (upd) { if (prev.u==bi_noVar.u) err("updating undefined variable"); @@ -224,14 +223,14 @@ void v_set(Scope* sc, B s, B x, bool upd) { // frees s, doesn't consume x B* sp = harr_ptr(s); BS2B xgetU = TI(x).getU; for (u64 i = 0; i < ia; i++) { - v_set(sc, sp[i], xgetU(x,i), upd); + v_set(pscs, sp[i], xgetU(x,i), upd); } dec(s); } } -B v_get(Scope* sc, B s) { // get value representing s, replacing with bi_optOut; doesn't consume +B v_get(Scope* pscs[], B s) { // get value representing s, replacing with bi_optOut; doesn't consume if (isVar(s)) { - sc = scd(sc, (u16)(s.u>>32)); + Scope* sc = pscs[(u16)(s.u>>32)]; B r = sc->vars[(u32)s.u]; sc->vars[(u32)s.u] = bi_optOut; return r; @@ -240,7 +239,7 @@ B v_get(Scope* sc, B s) { // get value representing s, replacing with bi_optOut; usz ia = a(s)->ia; B* sp = harr_ptr(s); HArr_p r = m_harrUv(ia); - for (u64 i = 0; i < ia; i++) r.a[i] = v_get(sc, sp[i]); + for (u64 i = 0; i < ia; i++) r.a[i] = v_get(pscs, sp[i]); return r.b; } } @@ -277,7 +276,6 @@ void gsAdd(B x) { B gsPop() { return *--gStack; } - B evalBC(Body* b, Scope* sc) { // doesn't consume #ifdef DEBUG_VM bcDepth+= 2; @@ -290,6 +288,10 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume Block** blocks = b->comp->blocks; i32* bc = b->bc; gsReserve(b->maxStack); + Scope* pscs[b->maxPSC+1]; + pscs[0] = sc; + for (i32 i = 0; i < b->maxPSC; i++) pscs[i+1] = pscs[i]->psc; + #define POP (*--gStack) #define P(N) B N=POP; #define ADD(X) { B tr=X; *(gStack++) = tr; } // if ordering is needed @@ -361,21 +363,21 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume break; } case LOCO: { i32 d = *bc++; i32 p = *bc++; - ADD(inc(scd(sc,d)->vars[p])); + ADD(inc(pscs[d]->vars[p])); break; } case LOCU: { i32 d = *bc++; i32 p = *bc++; - B* vars = scd(sc,d)->vars; + B* vars = pscs[d]->vars; ADD(vars[p]); vars[p] = bi_optOut; break; } - case SETN: { P(s) P(x) v_set(sc, s, x, false); ADD(x); break; } - case SETU: { P(s) P(x) v_set(sc, s, x, true ); ADD(x); break; } + case SETN: { P(s) P(x) v_set(pscs, s, x, false); ADD(x); break; } + case SETU: { P(s) P(x) v_set(pscs, s, x, true ); ADD(x); break; } case SETM: { P(s)P(f)P(x) - B w = v_get(sc, s); + B w = v_get(pscs, s); B r = c2(f,w,x); dec(f); - v_set(sc, s, r, true); + v_set(pscs, s, r, true); ADD(r); break; }