Skip to content

Commit

Permalink
Micro optimization in OP_RETURN and OP_TAILCALL
Browse files Browse the repository at this point in the history
Many functions are vararg but create no upvalues, so it is better
to separate the tests for these two kinds of "extra work".
  • Loading branch information
roberto-ieru committed Jul 16, 2019
1 parent c220b0a commit 4846f7e
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 15 deletions.
8 changes: 4 additions & 4 deletions lcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1745,10 +1745,10 @@ void luaK_finish (FuncState *fs) {
SET_OPCODE(*pc, OP_RETURN);
} /* FALLTHROUGH */
case OP_RETURN: case OP_TAILCALL: {
if (fs->needclose || p->is_vararg) {
SETARG_C(*pc, p->is_vararg ? p->numparams + 1 : 0);
SETARG_k(*pc, 1); /* signal that there is extra work */
}
if (fs->needclose)
SETARG_k(*pc, 1); /* signal that it needs to close */
if (p->is_vararg)
SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */
break;
}
case OP_JMP: {
Expand Down
7 changes: 3 additions & 4 deletions lopcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,9 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
(*) All 'skips' (pc++) assume that next instruction is a jump.
(*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the
function either builds upvalues, which may need to be closed, or is
vararg, which must be corrected before returning. When 'k' is true,
C > 0 means the function is vararg and (C - 1) is its number of
fixed parameters.
function builds upvalues, which may need to be closed. C > 0 means
the function is vararg, so that its 'func' must be corrected before
returning; in this case, (C - 1) is its number of fixed parameters.
(*) In comparisons with an immediate operand, C signals whether the
original operand was a float.
Expand Down
13 changes: 6 additions & 7 deletions lvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1564,16 +1564,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
}
vmcase(OP_TAILCALL) {
int b = GETARG_B(i); /* number of arguments + 1 (function) */
int delta = 0; /* virtual 'func' - real 'func' (vararg functions) */
int nparams1 = GETARG_C(i);
/* delat is virtual 'func' - real 'func' (vararg functions) */
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
if (b != 0)
L->top = ra + b;
else /* previous instruction set top */
b = cast_int(L->top - ra);
savepc(ci); /* some calls here can raise errors */
if (TESTARG_k(i)) {
int nparams1 = GETARG_C(i);
if (nparams1) /* vararg function? */
delta = ci->u.l.nextraargs + nparams1;
/* close upvalues from current call; the compiler ensures
that there are no to-be-closed variables here */
luaF_close(L, base, NOCLOSINGMETH);
Expand All @@ -1599,18 +1598,18 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
}
vmcase(OP_RETURN) {
int n = GETARG_B(i) - 1; /* number of results */
int nparams1 = GETARG_C(i);
if (n < 0) /* not fixed? */
n = cast_int(L->top - ra); /* get what is available */
savepc(ci);
if (TESTARG_k(i)) {
int nparams1 = GETARG_C(i);
if (L->top < ci->top)
L->top = ci->top;
luaF_close(L, base, LUA_OK); /* there may be open upvalues */
updatestack(ci);
if (nparams1) /* vararg function? */
ci->func -= ci->u.l.nextraargs + nparams1;
}
if (nparams1) /* vararg function? */
ci->func -= ci->u.l.nextraargs + nparams1;
L->top = ra + n; /* set call for 'luaD_poscall' */
luaD_poscall(L, ci, n);
return;
Expand Down

0 comments on commit 4846f7e

Please sign in to comment.