Browse Source

small optimization for boolean constants + new format for SETLIST opcode

Roberto Ierusalimschy 21 years ago
parent
commit
5ee87acd6b
6 changed files with 50 additions and 29 deletions
  1. 26 3
      lcode.c
  2. 2 1
      lcode.h
  3. 2 4
      lopcodes.c
  4. 8 5
      lopcodes.h
  5. 4 6
      lparser.c
  6. 8 10
      lvm.c

+ 26 - 3
lcode.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lcode.c,v 2.5 2004/07/16 13:30:53 roberto Exp roberto $
+** $Id: lcode.c,v 2.6 2004/08/24 20:09:11 roberto Exp $
 ** Code generator for Lua
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -243,7 +243,14 @@ int luaK_numberK (FuncState *fs, lua_Number r) {
 }
 }
 
 
 
 
-static int nil_constant (FuncState *fs) {
+static int boolK (FuncState *fs, int b) {
+  TValue o;
+  setbvalue(&o, b);
+  return addk(fs, &o, &o);
+}
+
+
+static int nilK (FuncState *fs) {
   TValue k, v;
   TValue k, v;
   setnilvalue(&v);
   setnilvalue(&v);
   /* cannot use nil as key; instead use table itself to represent nil */
   /* cannot use nil as key; instead use table itself to represent nil */
@@ -417,9 +424,11 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
 int luaK_exp2RK (FuncState *fs, expdesc *e) {
 int luaK_exp2RK (FuncState *fs, expdesc *e) {
   luaK_exp2val(fs, e);
   luaK_exp2val(fs, e);
   switch (e->k) {
   switch (e->k) {
+    case VTRUE:
+    case VFALSE:
     case VNIL: {
     case VNIL: {
       if (fs->nk <= MAXINDEXRK) {  /* constant fit in RK operand? */
       if (fs->nk <= MAXINDEXRK) {  /* constant fit in RK operand? */
-        e->info = nil_constant(fs);
+        e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
         e->k = VK;
         e->k = VK;
         return RKASK(e->info);
         return RKASK(e->info);
       }
       }
@@ -735,3 +744,17 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
   return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
   return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
 }
 }
 
 
+
+void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
+  int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
+  int b = (tostore == LUA_MULTRET) ? 0 : tostore;
+  lua_assert(tostore != 0);
+  if (c <= MAXARG_C)
+    luaK_codeABC(fs, OP_SETLIST, base, b, c);
+  else {
+    luaK_codeABC(fs, OP_SETLIST, base, b, 0);
+    luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
+  }
+  fs->freereg = base + 1;  /* free registers with list values */
+}
+

+ 2 - 1
lcode.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 roberto Exp roberto $
+** $Id: lcode.h,v 1.39 2004/05/31 18:51:50 roberto Exp $
 ** Code generator for Lua
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -72,6 +72,7 @@ int luaK_getlabel (FuncState *fs);
 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
 void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
 void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
+void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
 
 
 
 
 #endif
 #endif

+ 2 - 4
lopcodes.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lopcodes.c,v 1.27 2004/05/31 18:51:50 roberto Exp roberto $
+** $Id: lopcodes.c,v 1.28 2004/07/16 13:15:32 roberto Exp $
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
 
 
@@ -49,7 +49,6 @@ const char *const luaP_opnames[NUM_OPCODES] = {
   "TFORLOOP",
   "TFORLOOP",
   "TFORPREP",
   "TFORPREP",
   "SETLIST",
   "SETLIST",
-  "SETLISTO",
   "CLOSE",
   "CLOSE",
   "CLOSURE",
   "CLOSURE",
   "VARARG"
   "VARARG"
@@ -92,8 +91,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
  ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORPREP */
  ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORPREP */
  ,opmode(1, 0, OpArgN, OpArgU, iABC)		/* OP_TFORLOOP */
  ,opmode(1, 0, OpArgN, OpArgU, iABC)		/* OP_TFORLOOP */
  ,opmode(0, 0, OpArgR, OpArgN, iAsBx)		/* OP_TFORPREP */
  ,opmode(0, 0, OpArgR, OpArgN, iAsBx)		/* OP_TFORPREP */
- ,opmode(0, 0, OpArgU, OpArgN, iABx)		/* OP_SETLIST */
- ,opmode(0, 0, OpArgU, OpArgN, iABx)		/* OP_SETLISTO */
+ ,opmode(0, 0, OpArgU, OpArgU, iABC)		/* OP_SETLIST */
  ,opmode(0, 0, OpArgN, OpArgN, iABC)		/* OP_CLOSE */
  ,opmode(0, 0, OpArgN, OpArgN, iABC)		/* OP_CLOSE */
  ,opmode(0, 1, OpArgU, OpArgN, iABx)		/* OP_CLOSURE */
  ,opmode(0, 1, OpArgU, OpArgN, iABx)		/* OP_CLOSURE */
  ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_VARARG */
  ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_VARARG */

+ 8 - 5
lopcodes.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lopcodes.h,v 1.110 2004/06/29 18:49:02 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.111 2004/08/04 20:18:13 roberto Exp $
 ** Opcodes for Lua virtual machine
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -198,8 +198,7 @@ OP_TFORLOOP,/*	A C	R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
 OP_TFORPREP,/*	A sBx	if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
 OP_TFORPREP,/*	A sBx	if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
 			pc+=sBx					*/
 			pc+=sBx					*/
 
 
-OP_SETLIST,/*	A Bx	R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1	*/
-OP_SETLISTO,/*	A Bx							*/
+OP_SETLIST,/*	A B C	R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B	*/
 
 
 OP_CLOSE,/*	A 	close all variables in the stack up to (>=) R(A)*/
 OP_CLOSE,/*	A 	close all variables in the stack up to (>=) R(A)*/
 OP_CLOSURE,/*	A Bx	R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
 OP_CLOSURE,/*	A Bx	R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
@@ -219,11 +218,15 @@ OP_VARARG/*	A B	R(A), R(A+1), ..., R(A+B-1) = vararg		*/
       next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
       next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
 
 
   (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
   (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
-      set top (like in OP_CALL).
+      set top (like in OP_CALL with C == 0).
 
 
   (*) In OP_RETURN, if (B == 0) then return up to `top'
   (*) In OP_RETURN, if (B == 0) then return up to `top'
 
 
-  (*) For comparisons, B specifies what conditions the test should accept.
+  (*) In OP_SETLIST, if (B == 0) then B = `top';
+      if (C == 0) then next `instruction' is real C
+
+  (*) For comparisons, A specifies what condition the test should accept
+      (true or false).
 
 
   (*) All `skips' (pc++) assume that next instruction is a jump
   (*) All `skips' (pc++) assume that next instruction is a jump
 ===========================================================================*/
 ===========================================================================*/

+ 4 - 6
lparser.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lparser.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $
+** $Id: lparser.c,v 2.5 2004/05/31 18:51:50 roberto Exp $
 ** Lua Parser
 ** Lua Parser
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -475,9 +475,8 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
   luaK_exp2nextreg(fs, &cc->v);
   luaK_exp2nextreg(fs, &cc->v);
   cc->v.k = VVOID;
   cc->v.k = VVOID;
   if (cc->tostore == LFIELDS_PER_FLUSH) {
   if (cc->tostore == LFIELDS_PER_FLUSH) {
-    luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1);  /* flush */
+    luaK_setlist(fs, cc->t->info, cc->na, cc->tostore);  /* flush */
     cc->tostore = 0;  /* no more items pending */
     cc->tostore = 0;  /* no more items pending */
-    fs->freereg = cc->t->info + 1;  /* free registers */
   }
   }
 }
 }
 
 
@@ -486,15 +485,14 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
   if (cc->tostore == 0) return;
   if (cc->tostore == 0) return;
   if (hasmultret(cc->v.k)) {
   if (hasmultret(cc->v.k)) {
     luaK_setmultret(fs, &cc->v);
     luaK_setmultret(fs, &cc->v);
-    luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);
+    luaK_setlist(fs, cc->t->info, cc->na, LUA_MULTRET);
     cc->na--;  /* do not count last expression (unknown number of elements) */
     cc->na--;  /* do not count last expression (unknown number of elements) */
   }
   }
   else {
   else {
     if (cc->v.k != VVOID)
     if (cc->v.k != VVOID)
       luaK_exp2nextreg(fs, &cc->v);
       luaK_exp2nextreg(fs, &cc->v);
-    luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1);
+    luaK_setlist(fs, cc->t->info, cc->na, cc->tostore);
   }
   }
-  fs->freereg = cc->t->info + 1;  /* free registers */
 }
 }
 
 
 
 

+ 8 - 10
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 2.13 2004/08/12 14:19:51 roberto Exp roberto $
+** $Id: lvm.c,v 2.14 2004/09/15 20:39:42 roberto Exp $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -710,21 +710,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         dojump(L, pc, GETARG_sBx(i));
         dojump(L, pc, GETARG_sBx(i));
         continue;
         continue;
       }
       }
-      case OP_SETLIST:
-      case OP_SETLISTO: {
-        int bc = GETARG_Bx(i);
-        int n, last;
+      case OP_SETLIST: {
+        int n = GETARG_B(i);
+        int c = GETARG_C(i);
+        int last;
         Table *h;
         Table *h;
         runtime_check(L, ttistable(ra));
         runtime_check(L, ttistable(ra));
         h = hvalue(ra);
         h = hvalue(ra);
-        if (GET_OPCODE(i) == OP_SETLIST)
-          n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
-        else {
+        if (n == 0) {
           n = L->top - ra - 1;
           n = L->top - ra - 1;
           L->top = L->ci->top;
           L->top = L->ci->top;
         }
         }
-        bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */
-        last = bc + n + LUA_FIRSTINDEX - 1;
+        if (c == 0) c = cast(int, *pc++);
+        last = ((c-1)*LFIELDS_PER_FLUSH) + n + LUA_FIRSTINDEX - 1;
         if (last > h->sizearray)  /* needs more space? */
         if (last > h->sizearray)  /* needs more space? */
           luaH_resize(L, h,  last, h->lsizenode);  /* pre-alloc it at once */
           luaH_resize(L, h,  last, h->lsizenode);  /* pre-alloc it at once */
         for (; n > 0; n--) {
         for (; n > 0; n--) {