manually allocate parent scope array
~0.11% performance improvement for safe prim tests
This commit is contained in:
parent
a6c4f8c84d
commit
bad72186de
@ -445,30 +445,42 @@ static u32 readBytes4(u8* d) {
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef B JITFn(B* cStack, Scope** pscs, Scope* sc);
|
||||
typedef B JITFn(B* cStack, Scope* sc);
|
||||
static inline i32 maxi32(i32 a, i32 b) { return a>b?a:b; }
|
||||
Nvm_res m_nvm(Body* body) {
|
||||
ALLOC_ASM(64);
|
||||
#if ASM_TEST
|
||||
asm_test();
|
||||
#endif
|
||||
Reg r_ENV = 15;
|
||||
Reg r_PSCS = 14;
|
||||
Reg r_CS = 3;
|
||||
Reg r_SC = 12;
|
||||
PUSH(R_BP);
|
||||
PUSH(r_ENV);
|
||||
PUSH(r_PSCS); // Scope* pscs[]
|
||||
PUSH(r_CS); // starting gStack
|
||||
PUSH(r_SC); // Scope* sc
|
||||
MOV(r_CS , R_A0);
|
||||
MOV(r_PSCS, R_A1);
|
||||
MOV(r_SC , R_A2);
|
||||
Reg r_CS = R_P0;
|
||||
Reg r_SC = R_P1;
|
||||
Reg r_ENV = R_P2;
|
||||
u64 pushAm = 0;
|
||||
PUSH(R_BP ); pushAm++; // idk, rbp; todo make gdb happy
|
||||
PUSH(r_ENV); pushAm++; // env pointer for quick bytecode pos updating
|
||||
PUSH(r_CS ); pushAm++; // starting gStack
|
||||
PUSH(r_SC ); pushAm++; // Scope* sc
|
||||
u64 lsz = 0; // local variable used up space
|
||||
#define ALLOCL(NAME,N) u64 NAME##Off = lsz; lsz+= (N)
|
||||
|
||||
ALLOCL(pscs, (body->maxPSC+1)*8);
|
||||
while (((lsz+pushAm*8)&0xf) != 8) lsz++; // lazy way to make sure we're properly aligned
|
||||
SUBi(R_SP, lsz);
|
||||
|
||||
MOV(r_CS, R_A0);
|
||||
MOV(r_SC, R_A1);
|
||||
MOV8rp(r_ENV, (u64)&envCurr - 4);
|
||||
|
||||
#define VAR(OFF,N) (OFF##Off + (N))
|
||||
#define VAR8(OFF,N) VAR(OFF,(N)*8)
|
||||
ADDi(R_A4, 0x12);
|
||||
MOV8mro(R_SP, R_A1, VAR8(pscs,0));
|
||||
for (i32 i = 1; i < body->maxPSC+1; i++) {
|
||||
MOV8rmo(R_A2, R_A2, offsetof(Scope, psc));
|
||||
MOV8mro(r_PSCS, R_A2, i*8);
|
||||
MOV8rmo(R_A1, R_A1, offsetof(Scope, psc));
|
||||
MOV8mro(R_SP, R_A1, VAR8(pscs,i));
|
||||
}
|
||||
ADDi(R_A4, 0x34);
|
||||
|
||||
if ((u64)i_RETD > I32_MAX || (u64)&gStack > I32_MAX || (u64)&envEnd > I32_MAX) thrM("JIT: Refusing to run with CBQN code outside of the 32-bit address range");
|
||||
#define CCALL(F) { u64 f=(u64)(F); if(f>I32_MAX)thrM("JIT: Function address too large for call"); CALLi(f-4); }
|
||||
u32* origBC = body->bc;
|
||||
@ -494,7 +506,7 @@ Nvm_res m_nvm(Body* body) {
|
||||
#endif
|
||||
#define TOPp MOV(R_A0,R_RES)
|
||||
#define TOPs if (depth) { u8 t = SPOS(R_A3, 0, 0); MOV8mr(t, R_RES); }
|
||||
#define LSC(R,D) { if(D) MOV8rmo(R,r_PSCS,D*8); else MOV(R,r_SC); }
|
||||
#define LSC(R,D) { if(D) MOV8rmo(R,R_SP,VAR8(pscs,D)); else MOV(R,r_SC); }
|
||||
#define INCV(R) INC4mo(R, offsetof(Value,refc)); // ADD4mi(R_A3, 1); CCALL(i_INC);
|
||||
#ifdef __BMI2__ // TODO move to runtime detection maybe
|
||||
#define INCB(R,T,U) IMM(T,0xfffffffffffffull);ADD(T,R);IMM(U,0x7fffffffffffeull);CMP(T,U);{JA(lI);MOVi1l(U,0x30);BZHI(U,R,U);INCV(U);LBL1(lI);}
|
||||
@ -561,9 +573,9 @@ Nvm_res m_nvm(Body* body) {
|
||||
case EXTO: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); IMM(R_A2,off); INV(3,1,i_EXTO); } break; // (u32 p, Scope* sc, u32* bc, S)
|
||||
case LOCU: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); CCALL(i_LOCU); } break; // (u32 p, Scope* sc, S)
|
||||
case EXTU: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); CCALL(i_EXTU); } break; // (u32 p, Scope* sc, S)
|
||||
case SETN: TOPp; MOV(R_A1,r_PSCS); IMM(R_A2,off); INV(3,0,i_SETN); break; // (B, Scope** pscs, u32* bc, S)
|
||||
case SETU: TOPp; MOV(R_A1,r_PSCS); IMM(R_A2,off); INV(3,0,i_SETU); break; // (B, Scope** pscs, u32* bc, S)
|
||||
case SETM: TOPp; MOV(R_A1,r_PSCS); IMM(R_A2,off); INV(3,0,i_SETM); break; // (B, Scope** pscs, u32* bc, S)
|
||||
case SETN: TOPp; LEAi(R_A1,R_SP,VAR8(pscs,0)); IMM(R_A2,off); INV(3,0,i_SETN); break; // (B, Scope** pscs, u32* bc, S)
|
||||
case SETU: TOPp; LEAi(R_A1,R_SP,VAR8(pscs,0)); IMM(R_A2,off); INV(3,0,i_SETU); break; // (B, Scope** pscs, u32* bc, S)
|
||||
case SETM: TOPp; LEAi(R_A1,R_SP,VAR8(pscs,0)); IMM(R_A2,off); INV(3,0,i_SETM); break; // (B, Scope** pscs, u32* bc, S)
|
||||
case SETNi:TOPp; { u64 d=*bc++; u64 p=*bc++; LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); INV(4,0,i_SETNi); break; } // (B, Scope* sc, u32 p, u32* bc, S)
|
||||
case SETUi:TOPp; { u64 d=*bc++; u64 p=*bc++; LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); INV(4,0,i_SETUi); break; } // (B, Scope* sc, u32 p, u32* bc, S)
|
||||
case SETMi:TOPp; { u64 d=*bc++; u64 p=*bc++; LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); INV(4,0,i_SETMi); break; } // (B, Scope* sc, u32 p, u32* bc, S)
|
||||
@ -588,13 +600,16 @@ Nvm_res m_nvm(Body* body) {
|
||||
if (ret) break;
|
||||
}
|
||||
freeOpt(optRes);
|
||||
ADDi(R_SP, lsz);
|
||||
POP(r_SC);
|
||||
POP(r_CS);
|
||||
POP(r_PSCS);
|
||||
POP(r_ENV);
|
||||
POP(R_BP);
|
||||
RET();
|
||||
#undef CCALL
|
||||
#undef VAR8
|
||||
#undef VAR
|
||||
#undef ALLOCL
|
||||
GET_ASM();
|
||||
u64 sz = ASM_SIZE;
|
||||
u8* binEx = nvm_alloc(sz);
|
||||
@ -619,14 +634,10 @@ Nvm_res m_nvm(Body* body) {
|
||||
return (Nvm_res){.p = binEx, .refs = optRes.refs};
|
||||
}
|
||||
B evalJIT(Body* b, Scope* sc, u8* ptr) { // doesn't consume
|
||||
u32* bc = b->bc;
|
||||
pushEnv(sc, bc);
|
||||
pushEnv(sc, b->bc);
|
||||
gsReserve(b->maxStack);
|
||||
Scope* pscs[b->maxPSC+1];
|
||||
pscs[0] = sc;
|
||||
|
||||
// B* sp = gStack;
|
||||
B r = ((JITFn*)ptr)(gStack, pscs, sc);
|
||||
B r = ((JITFn*)ptr)(gStack, sc);
|
||||
// if (sp!=gStack) thrM("uh oh");
|
||||
|
||||
popEnv();
|
||||
|
||||
@ -20,16 +20,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#include "../utils/talloc.h"
|
||||
|
||||
// V - volatile (overwritten by calls)
|
||||
// 0 rax result
|
||||
// 1 rcx arg 3
|
||||
// 2 rdx arg 2
|
||||
// 3 rbx V
|
||||
// 4 rsp V stack
|
||||
// 5 rbp V base
|
||||
// 6 rsi arg 1
|
||||
// 7 rdi arg 0
|
||||
// 8 r8 arg 4
|
||||
// 9 r9 arg 5
|
||||
// 0 rax V result
|
||||
// 1 rcx V arg 3
|
||||
// 2 rdx V arg 2
|
||||
// 3 rbx
|
||||
// 4 rsp stack
|
||||
// 5 rbp base
|
||||
// 6 rsi V arg 1
|
||||
// 7 rdi V arg 0
|
||||
// 8 r8 V arg 4
|
||||
// 9 r9 V arg 5
|
||||
// . r10 V
|
||||
// . r11 V
|
||||
// . r12
|
||||
@ -54,11 +54,11 @@ typedef u8 Reg;
|
||||
#define R_V0 10
|
||||
#define R_V1 11
|
||||
// non-volatile/callee-saved/preserved registers
|
||||
#define R_P0 3 // rbx
|
||||
#define R_P1 12 // r12
|
||||
#define R_P2 13 // r13
|
||||
#define R_P3 14 // r14
|
||||
#define R_P4 15 // r15
|
||||
#define R_P0 3 // rbx
|
||||
#define R_P1 14 // r14
|
||||
#define R_P2 15 // r15
|
||||
#define R_P3 13 // r13
|
||||
#define R_P4 12 // r12
|
||||
|
||||
|
||||
#define ALLOC_ASM_ARR(N) TStack* b_o = (TStack*)mm_allocN(sizeof(TStack)+(N), t_temp); b_o->size=0; b_o->cap=(N)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user