avoid local "pc" in interpreter loop (tricky optimization with no real gain)

This commit is contained in:
Roberto Ierusalimschy 2006-09-19 10:57:50 -03:00
parent d513c3c66b
commit d1ef7e0ec6
4 changed files with 48 additions and 51 deletions

View File

@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.c,v 2.31 2006/08/07 19:04:06 roberto Exp roberto $ ** $Id: ldebug.c,v 2.32 2006/09/11 14:07:24 roberto Exp roberto $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -58,6 +58,7 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
mask = 0; mask = 0;
func = NULL; func = NULL;
} }
L->oldpc = L->savedpc;
L->hook = func; L->hook = func;
L->basehookcount = count; L->basehookcount = count;
resethookcount(L); resethookcount(L);

5
ldo.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: ldo.c,v 2.41 2006/09/11 12:44:56 roberto Exp roberto $ ** $Id: ldo.c,v 2.42 2006/09/11 14:07:24 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -346,8 +346,11 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
StkId res; StkId res;
int wanted, i; int wanted, i;
CallInfo *ci; CallInfo *ci;
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
if (L->hookmask & LUA_MASKRET) if (L->hookmask & LUA_MASKRET)
firstResult = callrethooks(L, firstResult); firstResult = callrethooks(L, firstResult);
L->oldpc = (L->ci - 1)->savedpc; /* set 'oldpc' for returning function */
}
ci = L->ci--; ci = L->ci--;
res = ci->func; /* res == final position of 1st result */ res = ci->func; /* res == final position of 1st result */
wanted = ci->nresults; wanted = ci->nresults;

View File

@ -1,5 +1,5 @@
/* /*
** $Id: lstate.h,v 2.25 2006/07/11 15:53:29 roberto Exp $ ** $Id: lstate.h,v 2.26 2006/08/15 19:59:20 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -107,6 +107,7 @@ struct lua_State {
global_State *l_G; global_State *l_G;
CallInfo *ci; /* call info for current function */ CallInfo *ci; /* call info for current function */
const Instruction *savedpc; /* `savedpc' of current function */ const Instruction *savedpc; /* `savedpc' of current function */
const Instruction *oldpc; /* last pc traced */
StkId stack_last; /* last free slot in the stack */ StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */ StkId stack; /* stack base */
CallInfo *end_ci; /* points after end of ci array*/ CallInfo *end_ci; /* points after end of ci array*/

80
lvm.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 2.66 2006/08/07 19:14:30 roberto Exp roberto $ ** $Id: lvm.c,v 2.67 2006/09/11 14:07:24 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -57,25 +57,22 @@ int luaV_tostring (lua_State *L, StkId obj) {
} }
static void traceexec (lua_State *L, const Instruction *pc) { static void traceexec (lua_State *L) {
lu_byte mask = L->hookmask; lu_byte mask = L->hookmask;
const Instruction *oldpc = L->savedpc; if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
L->savedpc = pc;
if (mask > LUA_MASKLINE) { /* instruction-hook set? */
if (L->hookcount == 0) {
resethookcount(L); resethookcount(L);
luaD_callhook(L, LUA_HOOKCOUNT, -1); luaD_callhook(L, LUA_HOOKCOUNT, -1);
} }
}
if (mask & LUA_MASKLINE) { if (mask & LUA_MASKLINE) {
Proto *p = ci_func(L->ci)->l.p; Proto *p = ci_func(L->ci)->l.p;
int npc = pcRel(pc, p); int npc = pcRel(L->savedpc, p);
int newline = getline(p, npc); int newline = getline(p, npc);
/* call linehook when enter a new function, when jump back (loop), if (npc == 0 || /* call linehook when enter a new function, */
or when enter a new line */ L->savedpc <= L->oldpc || /* when jump back (loop), or when */
if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) newline != getline(p, pcRel(L->oldpc, p))) /* enter a new line */
luaD_callhook(L, LUA_HOOKLINE, newline); luaD_callhook(L, LUA_HOOKLINE, newline);
} }
L->oldpc = L->savedpc;
} }
@ -351,10 +348,10 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} #define dojump(L,i) { L->savedpc += (i); luai_threadyield(L);}
#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } #define Protect(x) { {x;}; base = L->base; }
#define arith_op(op,tm) { \ #define arith_op(op,tm) { \
@ -374,22 +371,20 @@ void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl; LClosure *cl;
StkId base; StkId base;
TValue *k; TValue *k;
const Instruction *pc;
reentry: /* entry point */ reentry: /* entry point */
lua_assert(isLua(L->ci)); lua_assert(isLua(L->ci));
pc = L->savedpc;
cl = &clvalue(L->ci->func)->l; cl = &clvalue(L->ci->func)->l;
base = L->base; base = L->base;
k = cl->p->k; k = cl->p->k;
/* main loop of interpreter */ /* main loop of interpreter */
for (;;) { for (;;) {
const Instruction i = *pc++; const Instruction i = *(L->savedpc++);
StkId ra; StkId ra;
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
traceexec(L, pc); traceexec(L);
if (L->status == LUA_YIELD) { /* did hook yield? */ if (L->status == LUA_YIELD) { /* did hook yield? */
L->savedpc = pc - 1; L->savedpc--; /* undo increment */
return; return;
} }
base = L->base; base = L->base;
@ -410,7 +405,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
} }
case OP_LOADBOOL: { case OP_LOADBOOL: {
setbvalue(ra, GETARG_B(i)); setbvalue(ra, GETARG_B(i));
if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ if (GETARG_C(i)) L->savedpc++; /* skip next instruction (if C) */
continue; continue;
} }
case OP_LOADNIL: { case OP_LOADNIL: {
@ -538,7 +533,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_JMP: { case OP_JMP: {
dojump(L, pc, GETARG_sBx(i)); dojump(L, GETARG_sBx(i));
continue; continue;
} }
case OP_EQ: { case OP_EQ: {
@ -546,47 +541,46 @@ void luaV_execute (lua_State *L, int nexeccalls) {
TValue *rc = RKC(i); TValue *rc = RKC(i);
Protect( Protect(
if (equalobj(L, rb, rc) == GETARG_A(i)) if (equalobj(L, rb, rc) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc)); dojump(L, GETARG_sBx(*L->savedpc));
) )
pc++; L->savedpc++;
continue; continue;
} }
case OP_LT: { case OP_LT: {
Protect( Protect(
if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc)); dojump(L, GETARG_sBx(*L->savedpc));
) )
pc++; L->savedpc++;
continue; continue;
} }
case OP_LE: { case OP_LE: {
Protect( Protect(
if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc)); dojump(L, GETARG_sBx(*L->savedpc));
) )
pc++; L->savedpc++;
continue; continue;
} }
case OP_TEST: { case OP_TEST: {
if (l_isfalse(ra) != GETARG_C(i)) if (l_isfalse(ra) != GETARG_C(i))
dojump(L, pc, GETARG_sBx(*pc)); dojump(L, GETARG_sBx(*L->savedpc));
pc++; L->savedpc++;
continue; continue;
} }
case OP_TESTSET: { case OP_TESTSET: {
TValue *rb = RB(i); TValue *rb = RB(i);
if (l_isfalse(rb) != GETARG_C(i)) { if (l_isfalse(rb) != GETARG_C(i)) {
setobjs2s(L, ra, rb); setobjs2s(L, ra, rb);
dojump(L, pc, GETARG_sBx(*pc)); dojump(L, GETARG_sBx(*L->savedpc));
} }
pc++; L->savedpc++;
continue; continue;
} }
case OP_CALL: { case OP_CALL: {
int b = GETARG_B(i); int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1; int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */ if (b != 0) L->top = ra+b; /* else previous instruction set top */
L->savedpc = pc;
switch (luaD_precall(L, ra, nresults)) { switch (luaD_precall(L, ra, nresults)) {
case PCRLUA: { case PCRLUA: {
nexeccalls++; nexeccalls++;
@ -606,7 +600,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
case OP_TAILCALL: { case OP_TAILCALL: {
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */ if (b != 0) L->top = ra+b; /* else previous instruction set top */
L->savedpc = pc;
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
switch (luaD_precall(L, ra, LUA_MULTRET)) { switch (luaD_precall(L, ra, LUA_MULTRET)) {
case PCRLUA: { case PCRLUA: {
@ -639,7 +632,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1; if (b != 0) L->top = ra+b-1;
if (L->openupval) luaF_close(L, base); if (L->openupval) luaF_close(L, base);
L->savedpc = pc;
b = luaD_poscall(L, ra); b = luaD_poscall(L, ra);
if (--nexeccalls == 0) /* was previous function running `here'? */ if (--nexeccalls == 0) /* was previous function running `here'? */
return; /* no: return */ return; /* no: return */
@ -656,7 +648,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
lua_Number limit = nvalue(ra+1); lua_Number limit = nvalue(ra+1);
if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
: luai_numle(L, limit, idx)) { : luai_numle(L, limit, idx)) {
dojump(L, pc, GETARG_sBx(i)); /* jump back */ dojump(L, GETARG_sBx(i)); /* jump back */
setnvalue(ra, idx); /* update internal index... */ setnvalue(ra, idx); /* update internal index... */
setnvalue(ra+3, idx); /* ...and external index */ setnvalue(ra+3, idx); /* ...and external index */
} }
@ -666,7 +658,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
const TValue *init = ra; const TValue *init = ra;
const TValue *plimit = ra+1; const TValue *plimit = ra+1;
const TValue *pstep = ra+2; const TValue *pstep = ra+2;
L->savedpc = pc; /* next steps may throw errors */
if (!tonumber(init, ra)) if (!tonumber(init, ra))
luaG_runerror(L, LUA_QL("for") " initial value must be a number"); luaG_runerror(L, LUA_QL("for") " initial value must be a number");
else if (!tonumber(plimit, ra+1)) else if (!tonumber(plimit, ra+1))
@ -674,7 +665,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
else if (!tonumber(pstep, ra+2)) else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL("for") " step must be a number"); luaG_runerror(L, LUA_QL("for") " step must be a number");
setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
dojump(L, pc, GETARG_sBx(i)); dojump(L, GETARG_sBx(i));
continue; continue;
} }
case OP_TFORLOOP: { case OP_TFORLOOP: {
@ -688,9 +679,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
cb = RA(i) + 3; /* previous call may change the stack */ cb = RA(i) + 3; /* previous call may change the stack */
if (!ttisnil(cb)) { /* continue loop? */ if (!ttisnil(cb)) { /* continue loop? */
setobjs2s(L, cb-1, cb); /* save control variable */ setobjs2s(L, cb-1, cb); /* save control variable */
dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ dojump(L, GETARG_sBx(*L->savedpc)); /* jump back */
} }
pc++; L->savedpc++;
continue; continue;
} }
case OP_SETLIST: { case OP_SETLIST: {
@ -699,7 +690,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
int last; int last;
Table *h; Table *h;
if (n == 0) n = cast_int(L->top - ra) - 1; if (n == 0) n = cast_int(L->top - ra) - 1;
if (c == 0) c = cast_int(*pc++); if (c == 0) c = cast_int(*L->savedpc++);
runtime_check(L, ttistable(ra)); runtime_check(L, ttistable(ra));
h = hvalue(ra); h = hvalue(ra);
last = ((c-1)*LFIELDS_PER_FLUSH) + n; last = ((c-1)*LFIELDS_PER_FLUSH) + n;
@ -726,12 +717,13 @@ void luaV_execute (lua_State *L, int nexeccalls) {
ncl = luaF_newLclosure(L, nup, cl->env); ncl = luaF_newLclosure(L, nup, cl->env);
ncl->l.p = p; ncl->l.p = p;
setclvalue(L, ra, ncl); setclvalue(L, ra, ncl);
for (j=0; j<nup; j++, pc++) { for (j=0; j<nup; j++, L->savedpc++) {
if (GET_OPCODE(*pc) == OP_GETUPVAL) Instruction u = *L->savedpc;
ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; if (GET_OPCODE(u) == OP_GETUPVAL)
ncl->l.upvals[j] = cl->upvals[GETARG_B(u)];
else { else {
lua_assert(GET_OPCODE(*pc) == OP_MOVE); lua_assert(GET_OPCODE(u) == OP_MOVE);
ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(u));
} }
} }
Protect(luaC_checkGC(L)); Protect(luaC_checkGC(L));