Browse Source

small optimization for boolean constants + new format for SETLIST opcode

v5-2
Roberto Ierusalimschy 20 years ago
parent
commit
5ee87acd6b
  1. 29
      lcode.c
  2. 3
      lcode.h
  3. 6
      lopcodes.c
  4. 13
      lopcodes.h
  5. 10
      lparser.c
  6. 18
      lvm.c

29
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 */
}

3
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

6
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, OpArgU, iABC) /* OP_SETLIST */
,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */
,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 */

13
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_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_SETLISTO,/* A Bx */
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
===========================================================================*/ ===========================================================================*/

10
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 */
} }

18
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_SETLIST: {
case OP_SETLISTO: { int n = GETARG_B(i);
int bc = GETARG_Bx(i); int c = GETARG_C(i);
int n, last; 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) if (n == 0) {
n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
else {
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 */ if (c == 0) c = cast(int, *pc++);
last = bc + n + LUA_FIRSTINDEX - 1; 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--) {

Loading…
Cancel
Save