micro-optimize execBodyInline
This commit is contained in:
parent
3f583a2314
commit
6abce22447
@ -165,7 +165,7 @@ FORCE_INLINE B gotoNextBodyJIT(Scope* sc, Body* body) {
|
|||||||
u64 ga = blockGivenVars(bl);
|
u64 ga = blockGivenVars(bl);
|
||||||
for (u64 i = 0; i < ga; i++) inc(sc->vars[i]);
|
for (u64 i = 0; i < ga; i++) inc(sc->vars[i]);
|
||||||
Scope* nsc = m_scope(body, sc->psc, body->varAm, ga, sc->vars);
|
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;
|
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);
|
bool ok = v_seth(pscs, s, x); dec(x); dec(s);
|
||||||
|
|||||||
16
src/vm.c
16
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]);
|
for (u64 i = 0; i < ga; i++) inc(sc->vars[i]);
|
||||||
Scope* nsc = m_scope(body, sc->psc, body->varAm, ga, sc->vars);
|
Scope* nsc = m_scope(body, sc->psc, body->varAm, ga, sc->vars);
|
||||||
scope_dec(sc);
|
scope_dec(sc);
|
||||||
return execBodyInlineI(bl, body, nsc);
|
return execBodyInlineI(body, nsc, bl);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
@ -571,7 +571,7 @@ i32* vmStack;
|
|||||||
i32 bcCtr = 0;
|
i32 bcCtr = 0;
|
||||||
#endif
|
#endif
|
||||||
#define BCPOS(B,P) (B->bl->map[(P)-(u32*)B->bl->bc])
|
#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
|
#ifdef DEBUG_VM
|
||||||
bcDepth+= 2;
|
bcDepth+= 2;
|
||||||
if (!vmStack) vmStack = malloc(400);
|
if (!vmStack) vmStack = malloc(400);
|
||||||
@ -830,14 +830,22 @@ Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars) {
|
|||||||
return sc;
|
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
|
FORCE_INLINE B execBlock(Block* block, Body* body, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
||||||
u16 varAm = body->varAm;
|
u16 varAm = body->varAm;
|
||||||
assert(varAm>=ga);
|
assert(varAm>=ga);
|
||||||
assert(ga == blockGivenVars(block));
|
assert(ga == blockGivenVars(block));
|
||||||
Scope* sc = m_scope(body, psc, varAm, ga, svar);
|
Scope* sc = m_scope(body, psc, varAm, ga, svar);
|
||||||
B r = execBodyInlineI(block, body, sc);
|
B r = execBodyInlineI(body, sc, block);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
src/vm.h
23
src/vm.h
@ -160,24 +160,25 @@ Nvm_res m_nvm(Body* b);
|
|||||||
void nvm_free(u8* ptr);
|
void nvm_free(u8* ptr);
|
||||||
|
|
||||||
B evalJIT(Body* b, Scope* sc, u8* ptr);
|
B evalJIT(Body* b, Scope* sc, u8* ptr);
|
||||||
B evalBC(Block* bl, Body* b, Scope* sc);
|
B evalBC(Body* b, Scope* sc, Block* bl);
|
||||||
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 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 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;
|
bool jit = true;
|
||||||
#if JIT_START > 0
|
#if JIT_START > 0
|
||||||
jit = body->callCount++ >= JIT_START;
|
jit = body->callCount++ >= JIT_START;
|
||||||
#endif
|
#endif
|
||||||
// jit = body->bc[2]==m_f64(123456).u>>32; // enable JIT for blocks starting with `123456⋄`
|
// jit = body->bc[2]==m_f64(123456).u>>32; // enable JIT for blocks starting with `123456⋄`
|
||||||
if (jit) {
|
if (jit) return mnvmExecBodyInline(body, sc);
|
||||||
Nvm_res r = m_nvm(body);
|
|
||||||
body->nvm = r.p;
|
|
||||||
body->nvmRefs = r.refs;
|
|
||||||
goto toJIT;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return evalBC(block, body, sc);
|
return evalBC(body, sc, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern u32 bL_m[BC_SIZE];
|
extern u32 bL_m[BC_SIZE];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user