From 6abce22447ad272363ac419c7572765f7a73d476 Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 27 Apr 2022 19:22:13 +0300 Subject: [PATCH] micro-optimize execBodyInline --- src/jit/nvm_x86_64.c | 2 +- src/vm.c | 16 ++++++++++++---- src/vm.h | 23 ++++++++++++----------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/jit/nvm_x86_64.c b/src/jit/nvm_x86_64.c index 521639d4..6ab4ed17 100644 --- a/src/jit/nvm_x86_64.c +++ b/src/jit/nvm_x86_64.c @@ -165,7 +165,7 @@ FORCE_INLINE B gotoNextBodyJIT(Scope* sc, Body* body) { u64 ga = blockGivenVars(bl); for (u64 i = 0; i < ga; i++) inc(sc->vars[i]); Scope* nsc = m_scope(body, sc->psc, body->varAm, ga, sc->vars); - return execBodyInlineI(bl, body, nsc); + return execBodyInlineI(body, nsc, bl); } INS B i_SETH1(B s, B x, Scope** pscs, u32* bc, Body* v1) { POS_UPD; bool ok = v_seth(pscs, s, x); dec(x); dec(s); diff --git a/src/vm.c b/src/vm.c index f2c33989..e421beb8 100644 --- a/src/vm.c +++ b/src/vm.c @@ -562,7 +562,7 @@ FORCE_INLINE B gotoNextBody(Block* bl, Scope* sc, Body* body) { for (u64 i = 0; i < ga; i++) inc(sc->vars[i]); Scope* nsc = m_scope(body, sc->psc, body->varAm, ga, sc->vars); scope_dec(sc); - return execBodyInlineI(bl, body, nsc); + return execBodyInlineI(body, nsc, bl); } #ifdef DEBUG_VM @@ -571,7 +571,7 @@ i32* vmStack; i32 bcCtr = 0; #endif #define BCPOS(B,P) (B->bl->map[(P)-(u32*)B->bl->bc]) -B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume +B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume #ifdef DEBUG_VM bcDepth+= 2; if (!vmStack) vmStack = malloc(400); @@ -830,14 +830,22 @@ Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars) { return sc; } -B execBlockInline(Block* block, Scope* sc) { return execBodyInlineI(block, block->bodies[0], ptr_inc(sc)); } +B execBlockInlineImpl(Body* body, Scope* sc, Block* block) { return execBodyInlineI(block->bodies[0], ptr_inc(sc), block); } +B mnvmExecBodyInline(Body* body, Scope* sc) { + Nvm_res r = m_nvm(body); + body->nvm = r.p; + body->nvmRefs = r.refs; + return evalJIT(body, sc, body->nvm); +} + + FORCE_INLINE B execBlock(Block* block, Body* body, Scope* psc, i32 ga, B* svar) { // consumes svar contents u16 varAm = body->varAm; assert(varAm>=ga); assert(ga == blockGivenVars(block)); Scope* sc = m_scope(body, psc, varAm, ga, svar); - B r = execBodyInlineI(block, body, sc); + B r = execBodyInlineI(body, sc, block); return r; } diff --git a/src/vm.h b/src/vm.h index 759478cd..e055c46d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -160,24 +160,25 @@ Nvm_res m_nvm(Body* b); void nvm_free(u8* ptr); B evalJIT(Body* b, Scope* sc, u8* ptr); -B evalBC(Block* bl, Body* b, Scope* sc); -B execBlockInline(Block* block, Scope* sc); // doesn't consume; executes bytecode of the monadic body directly in the scope -FORCE_INLINE B execBodyInlineI(Block* block, Body* body, Scope* sc) { // consumes sc, unlike execBlockInline +B evalBC(Body* b, Scope* sc, Block* bl); + +B execBlockInlineImpl(Body* body, Scope* sc, Block* block); +static B execBlockInline(Block* block, Scope* sc) { // doesn't consume; executes bytecode of the monadic body directly in the scope + return execBlockInlineImpl(block->bodies[0], ptr_inc(sc), block); +} + +NOINLINE B mnvmExecBodyInline(Body* body, Scope* sc); +FORCE_INLINE B execBodyInlineI(Body* body, Scope* sc, Block* block) { // consumes sc, unlike execBlockInline #if JIT_START != -1 - if (body->nvm) { toJIT: return evalJIT(body, sc, body->nvm); } + if (LIKELY(body->nvm != NULL)) return evalJIT(body, sc, body->nvm); bool jit = true; #if JIT_START > 0 jit = body->callCount++ >= JIT_START; #endif // jit = body->bc[2]==m_f64(123456).u>>32; // enable JIT for blocks starting with `123456⋄` - if (jit) { - Nvm_res r = m_nvm(body); - body->nvm = r.p; - body->nvmRefs = r.refs; - goto toJIT; - } + if (jit) return mnvmExecBodyInline(body, sc); #endif - return evalBC(block, body, sc); + return evalBC(body, sc, block); } extern u32 bL_m[BC_SIZE];