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.
This commit is contained in:
Marisa Heit 2016-10-21 22:08:12 -05:00
parent b1289fa783
commit 5c596d3797
2 changed files with 26 additions and 20 deletions

View file

@ -11,21 +11,21 @@
#if COMPGOTO #if COMPGOTO
#define OP(x) x #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 #else
#define OP(x) case OP_##x #define OP(x) case OP_##x
#define NEXTOP break #define NEXTOP pc++; break
#endif #endif
#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) #define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
#define A (pc[-1].a) #define A (pc[0].a)
#define B (pc[-1].b) #define B (pc[0].b)
#define C (pc[-1].c) #define C (pc[0].c)
#define Cs (pc[-1].cs) #define Cs (pc[0].cs)
#define BC (pc[-1].i16u) #define BC (pc[0].i16u)
#define BCs (pc[-1].i16) #define BCs (pc[0].i16)
#define ABCs (pc[-1].i24) #define ABCs (pc[0].i24)
#define JMPOFS(x) ((x)->i24) #define JMPOFS(x) ((x)->i24)
#define KC (konstd[C]) #define KC (konstd[C])
@ -48,8 +48,8 @@
#define CMPJMP(test) \ #define CMPJMP(test) \
if ((test) == (a & CMP_CHECK)) { \ if ((test) == (a & CMP_CHECK)) { \
assert(pc->op == OP_JMP); \ assert(pc[1].op == OP_JMP); \
pc += 1 + JMPOFS(pc); \ pc += 1 + JMPOFS(pc+1); \
} else { \ } else { \
pc += 1; \ pc += 1; \
} }

View file

@ -52,11 +52,17 @@ begin:
{ {
#if !COMPGOTO #if !COMPGOTO
VM_UBYTE op; VM_UBYTE op;
for(;;) switch(op = pc->op, a = pc->a, pc++, op) for(;;) switch(op = pc->op, a = pc->a, op)
#else #else
pc--;
NEXTOP; NEXTOP;
#endif #endif
{ {
#if !COMPGOTO
default:
assert(0 && "Undefined opcode hit");
NEXTOP;
#endif
OP(LI): OP(LI):
ASSERTD(a); ASSERTD(a);
reg.d[a] = BCs; reg.d[a] = BCs;
@ -367,13 +373,13 @@ begin:
} }
NEXTOP; NEXTOP;
OP(JMP): OP(JMP):
pc += JMPOFS(pc - 1); pc += JMPOFS(pc);
NEXTOP; NEXTOP;
OP(IJMP): OP(IJMP):
ASSERTD(a); ASSERTD(a);
pc += (BCs + reg.d[a]); pc += (BCs + reg.d[a]);
assert(pc->op == OP_JMP); assert(pc[1].op == OP_JMP);
pc += 1 + JMPOFS(pc); pc += 1 + JMPOFS(pc+1);
NEXTOP; NEXTOP;
OP(PARAMI): OP(PARAMI):
assert(f->NumParam < sfunc->MaxParam); assert(f->NumParam < sfunc->MaxParam);
@ -490,7 +496,7 @@ begin:
VMReturn returns[MAX_RETURNS]; VMReturn returns[MAX_RETURNS];
int numret; int numret;
FillReturns(reg, f, returns, pc, C); FillReturns(reg, f, returns, pc+1, C);
if (call->Native) if (call->Native)
{ {
numret = static_cast<VMNativeFunction *>(call)->NativeCall(stack, reg.param + f->NumParam - B, B, returns, C); numret = static_cast<VMNativeFunction *>(call)->NativeCall(stack, reg.param + f->NumParam - B, B, returns, C);
@ -603,8 +609,8 @@ begin:
{ {
THROW(X_TOO_MANY_TRIES); THROW(X_TOO_MANY_TRIES);
} }
assert((pc + JMPOFS(pc - 1))->op == OP_CATCH); assert((pc + JMPOFS(pc) + 1)->op == OP_CATCH);
exception_frames[try_depth++] = pc + JMPOFS(pc - 1); exception_frames[try_depth++] = pc + JMPOFS(pc) + 1;
NEXTOP; NEXTOP;
OP(UNTRY): OP(UNTRY):
assert(a <= try_depth); assert(a <= try_depth);
@ -704,8 +710,8 @@ begin:
} }
if (cmp == (a & CMP_CHECK)) if (cmp == (a & CMP_CHECK))
{ {
assert(pc->op == OP_JMP); assert(pc[1].op == OP_JMP);
pc += 1 + JMPOFS(pc); pc += 1 + JMPOFS(pc+1);
} }
else else
{ {