From 5c596d3797fe5a322485f2b865f02314524b45e1 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 21 Oct 2016 22:08:12 -0500 Subject: [PATCH] Change VM to increment PC after each instruction rather than before - VC++ generated horribly stupid code for x64 when incrementing pc at the beginning of each instruction by storing hundreds of copies of it for every opcode executed. Incrementing pc at the end avoids this madness. - It is possible I messed something up with this change. Hopefully not. --- src/zscript/vmexec.cpp | 22 +++++++++++----------- src/zscript/vmexec.h | 24 +++++++++++++++--------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/zscript/vmexec.cpp b/src/zscript/vmexec.cpp index 454f02d03..7ee89329a 100644 --- a/src/zscript/vmexec.cpp +++ b/src/zscript/vmexec.cpp @@ -11,21 +11,21 @@ #if COMPGOTO #define OP(x) x -#define NEXTOP do { unsigned op = pc->op; a = pc->a; pc++; goto *ops[op]; } while(0) +#define NEXTOP do { pc++; unsigned op = pc->op; a = pc->a; goto *ops[op]; } while(0) #else #define OP(x) case OP_##x -#define NEXTOP break +#define NEXTOP pc++; break #endif #define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) -#define A (pc[-1].a) -#define B (pc[-1].b) -#define C (pc[-1].c) -#define Cs (pc[-1].cs) -#define BC (pc[-1].i16u) -#define BCs (pc[-1].i16) -#define ABCs (pc[-1].i24) +#define A (pc[0].a) +#define B (pc[0].b) +#define C (pc[0].c) +#define Cs (pc[0].cs) +#define BC (pc[0].i16u) +#define BCs (pc[0].i16) +#define ABCs (pc[0].i24) #define JMPOFS(x) ((x)->i24) #define KC (konstd[C]) @@ -48,8 +48,8 @@ #define CMPJMP(test) \ if ((test) == (a & CMP_CHECK)) { \ - assert(pc->op == OP_JMP); \ - pc += 1 + JMPOFS(pc); \ + assert(pc[1].op == OP_JMP); \ + pc += 1 + JMPOFS(pc+1); \ } else { \ pc += 1; \ } diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index adf2986c5..3637f2c1c 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -52,11 +52,17 @@ begin: { #if !COMPGOTO VM_UBYTE op; - for(;;) switch(op = pc->op, a = pc->a, pc++, op) + for(;;) switch(op = pc->op, a = pc->a, op) #else + pc--; NEXTOP; #endif { +#if !COMPGOTO + default: + assert(0 && "Undefined opcode hit"); + NEXTOP; +#endif OP(LI): ASSERTD(a); reg.d[a] = BCs; @@ -367,13 +373,13 @@ begin: } NEXTOP; OP(JMP): - pc += JMPOFS(pc - 1); + pc += JMPOFS(pc); NEXTOP; OP(IJMP): ASSERTD(a); pc += (BCs + reg.d[a]); - assert(pc->op == OP_JMP); - pc += 1 + JMPOFS(pc); + assert(pc[1].op == OP_JMP); + pc += 1 + JMPOFS(pc+1); NEXTOP; OP(PARAMI): assert(f->NumParam < sfunc->MaxParam); @@ -490,7 +496,7 @@ begin: VMReturn returns[MAX_RETURNS]; int numret; - FillReturns(reg, f, returns, pc, C); + FillReturns(reg, f, returns, pc+1, C); if (call->Native) { numret = static_cast(call)->NativeCall(stack, reg.param + f->NumParam - B, B, returns, C); @@ -603,8 +609,8 @@ begin: { THROW(X_TOO_MANY_TRIES); } - assert((pc + JMPOFS(pc - 1))->op == OP_CATCH); - exception_frames[try_depth++] = pc + JMPOFS(pc - 1); + assert((pc + JMPOFS(pc) + 1)->op == OP_CATCH); + exception_frames[try_depth++] = pc + JMPOFS(pc) + 1; NEXTOP; OP(UNTRY): assert(a <= try_depth); @@ -704,8 +710,8 @@ begin: } if (cmp == (a & CMP_CHECK)) { - assert(pc->op == OP_JMP); - pc += 1 + JMPOFS(pc); + assert(pc[1].op == OP_JMP); + pc += 1 + JMPOFS(pc+1); } else {