From d9110e8b5a906dc7038603051554618d74a321f3 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 27 May 2021 19:00:08 +0300 Subject: [PATCH] optimize v_get, v_set, and a bit of fills --- src/core/fillarr.h | 15 ++++++++------- src/h.h | 10 +++++----- src/vm.c | 46 ++++++++++++++++++++++++++++------------------ 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/core/fillarr.h b/src/core/fillarr.h index 12f70374..4b03b22c 100644 --- a/src/core/fillarr.h +++ b/src/core/fillarr.h @@ -13,26 +13,27 @@ void validateFill(B x); bool fillEqual(B w, B x); B withFill(B x, B fill); // consumes both static B qWithFill(B x, B fill) { // consumes both - if (noFill(fill)) return x; + assert(isArr(x)); + if (noFill(fill) || TI(x).elType!=el_B) return x; return withFill(x, fill); } static B getFillR(B x) { // doesn't consume; can return bi_noFill if (isArr(x)) { + u8 xe = TI(x).elType; + if (xe<=el_f64) return m_f64(0); + if (xe==el_c32) return m_c32(' '); u8 t = v(x)->type; - if (t==t_fillarr ) { B r = inc(c(FillArr,x )->fill); return r; } - if (t==t_fillslice) { B r = inc(c(FillArr,c(Slice,x)->p)->fill); return r; } - if (t==t_c32arr || t==t_c32slice) return m_c32(' '); - if (t==t_i32arr || t==t_i32slice) return m_f64(0 ); - if (t==t_f64arr || t==t_f64slice) return m_f64(0 ); + if (t==t_fillarr ) return inc(c(FillArr,x )->fill); + if (t==t_fillslice) return inc(c(FillArr,c(Slice,x)->p)->fill); return bi_noFill; } if (isF64(x)|isI32(x)) return m_i32(0); if (isC32(x)) return m_c32(' '); return bi_noFill; } -static B getFillQ(B x) { // doesn't consume; can return bi_noFill if CATCH_ERRORS +static B getFillQ(B x) { // doesn't consume; returns 0 if !CATCH_ERRORS B r = getFillR(x); #ifdef CATCH_ERRORS return r; diff --git a/src/h.h b/src/h.h index cb0c40b0..db0c8954 100644 --- a/src/h.h +++ b/src/h.h @@ -234,11 +234,11 @@ void gc_forceGC(); // force a gc; who knows what happens if gc is disabled (prob void gc_visitRoots(); // some primitive actions -static const B bi_N = tag(0, TAG_TAG); -static const B bi_noVar = tag(1, TAG_TAG); -static const B bi_badHdr = tag(2, TAG_TAG); -static const B bi_optOut = tag(3, TAG_TAG); -static const B bi_noFill = tag(5, TAG_TAG); +static const B bi_N = tag(0, TAG_TAG); +static const B bi_noVar = tag(1, TAG_TAG); +static const B bi_badHdr = tag(2, TAG_TAG); +static const B bi_optOut = tag(3, TAG_TAG); +static const B bi_noFill = tag(5, TAG_TAG); extern B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec; static void dec(B x); static B inc(B x); diff --git a/src/vm.c b/src/vm.c index 1c92607e..a9991be3 100644 --- a/src/vm.c +++ b/src/vm.c @@ -297,22 +297,26 @@ typedef struct FldAlias { B obj; i32 p; } FldAlias; -void v_set(Scope* pscs[], B s, B x, bool upd) { // doesn't consume - if (isVar(s)) { - Scope* sc = pscs[(u16)(s.u>>32)]; - B prev = sc->vars[(u32)s.u]; - if (upd) { - if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable"); - dec(prev); - } // else if (prev.u!=bi_noVar.u) thrM("←: Redefining variable"); - sc->vars[(u32)s.u] = inc(x); - } else if (isExt(s)) { + +static NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd); +static void v_set(Scope* pscs[], B s, B x, bool upd) { // doesn't consume + if (RARE(!isVar(s))) return v_setR(pscs, s, x, upd);; + Scope* sc = pscs[(u16)(s.u>>32)]; + B prev = sc->vars[(u32)s.u]; + if (upd) { + if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable"); + dec(prev); + } + sc->vars[(u32)s.u] = inc(x); +} +static NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd) { + if (isExt(s)) { Scope* sc = pscs[(u16)(s.u>>32)]; B prev = sc->ext->vars[(u32)s.u]; if (upd) { if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable"); dec(prev); - } // else if (prev.u!=bi_noVar.u) thrM("←: Redefining variable"); + } sc->ext->vars[(u32)s.u] = inc(x); } else { VTY(s, t_harr); @@ -344,13 +348,19 @@ void v_set(Scope* pscs[], B s, B x, bool upd) { // doesn't consume for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], xgetU(x,i), upd); } } -B v_get(Scope* pscs[], B s) { // get value representing s, replacing with bi_optOut; doesn't consume - if (isVar(s)) { - Scope* sc = pscs[(u16)(s.u>>32)]; - B r = sc->vars[(u32)s.u]; - sc->vars[(u32)s.u] = bi_optOut; - return r; - } else if (isExt(s)) { + + + +static NOINLINE B v_getR(Scope* pscs[], B s); +static B v_get(Scope* pscs[], B s) { // get value representing s, replacing with bi_optOut; doesn't consume + if (RARE(!isVar(s))) return v_getR(pscs, s); + Scope* sc = pscs[(u16)(s.u>>32)]; + B r = sc->vars[(u32)s.u]; + sc->vars[(u32)s.u] = bi_optOut; + return r; +} +static NOINLINE B v_getR(Scope* pscs[], B s) { + if (isExt(s)) { Scope* sc = pscs[(u16)(s.u>>32)]; B r = sc->ext->vars[(u32)s.u]; sc->ext->vars[(u32)s.u] = bi_optOut;