Pārlūkot izejas kodu

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

Roberto Ierusalimschy 19 gadi atpakaļ
vecāks
revīzija
d1ef7e0ec6
4 mainītis faili ar 48 papildinājumiem un 51 dzēšanām
  1. 2 1
      ldebug.c
  2. 6 3
      ldo.c
  3. 2 1
      lstate.h
  4. 38 46
      lvm.c

+ 2 - 1
ldebug.c

@@ -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);

+ 6 - 3
ldo.c

@@ -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)
-    firstResult = callrethooks(L, firstResult);
+  if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
+    if (L->hookmask & LUA_MASKRET)
+      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;

+ 2 - 1
lstate.h

@@ -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*/

+ 38 - 46
lvm.c

@@ -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;
-  L->savedpc = pc;
-  if (mask > LUA_MASKLINE) {  /* instruction-hook set? */
-    if (L->hookcount == 0) {
-      resethookcount(L);
-      luaD_callhook(L, LUA_HOOKCOUNT, -1);
-    }
+  if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
+    resethookcount(L);
+    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),
-       or when enter a new line */
-    if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
+    if (npc == 0 ||  /* call linehook when enter a new function, */
+        L->savedpc <= L->oldpc ||  /* when jump back (loop), or when */
+        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));
-        pc++;
+          dojump(L, GETARG_sBx(*L->savedpc));
+        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++) {
-          if (GET_OPCODE(*pc) == OP_GETUPVAL)
-            ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
+        for (j=0; j<nup; j++, L->savedpc++) {
+          Instruction u = *L->savedpc;
+          if (GET_OPCODE(u) == OP_GETUPVAL)
+            ncl->l.upvals[j] = cl->upvals[GETARG_B(u)];
           else {
           else {
-            lua_assert(GET_OPCODE(*pc) == OP_MOVE);
-            ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
+            lua_assert(GET_OPCODE(u) == OP_MOVE);
+            ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(u));
           }
           }
         }
         }
         Protect(luaC_checkGC(L));
         Protect(luaC_checkGC(L));