aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-16 15:44:37 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-16 15:44:37 -0300
commit4846f7e3bb1397142ab0de808ae59c08db9832a6 (patch)
treede10475ba2b2f0713edc91f5bff801bd7eaa0b3d
parentc220b0a5d099372e58e517b9f13eaa7bb0bec45c (diff)
downloadlua-4846f7e3bb1397142ab0de808ae59c08db9832a6.tar.gz
lua-4846f7e3bb1397142ab0de808ae59c08db9832a6.tar.bz2
lua-4846f7e3bb1397142ab0de808ae59c08db9832a6.zip
Micro optimization in OP_RETURN and OP_TAILCALL
Many functions are vararg but create no upvalues, so it is better to separate the tests for these two kinds of "extra work".
-rw-r--r--lcode.c8
-rw-r--r--lopcodes.h7
-rw-r--r--lvm.c13
3 files changed, 13 insertions, 15 deletions
diff --git a/lcode.c b/lcode.c
index a0d7757a..e57ad284 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1745,10 +1745,10 @@ void luaK_finish (FuncState *fs) {
1745 SET_OPCODE(*pc, OP_RETURN); 1745 SET_OPCODE(*pc, OP_RETURN);
1746 } /* FALLTHROUGH */ 1746 } /* FALLTHROUGH */
1747 case OP_RETURN: case OP_TAILCALL: { 1747 case OP_RETURN: case OP_TAILCALL: {
1748 if (fs->needclose || p->is_vararg) { 1748 if (fs->needclose)
1749 SETARG_C(*pc, p->is_vararg ? p->numparams + 1 : 0); 1749 SETARG_k(*pc, 1); /* signal that it needs to close */
1750 SETARG_k(*pc, 1); /* signal that there is extra work */ 1750 if (p->is_vararg)
1751 } 1751 SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */
1752 break; 1752 break;
1753 } 1753 }
1754 case OP_JMP: { 1754 case OP_JMP: {
diff --git a/lopcodes.h b/lopcodes.h
index 371cb3ae..26b1850d 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -338,10 +338,9 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
338 (*) All 'skips' (pc++) assume that next instruction is a jump. 338 (*) All 'skips' (pc++) assume that next instruction is a jump.
339 339
340 (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the 340 (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the
341 function either builds upvalues, which may need to be closed, or is 341 function builds upvalues, which may need to be closed. C > 0 means
342 vararg, which must be corrected before returning. When 'k' is true, 342 the function is vararg, so that its 'func' must be corrected before
343 C > 0 means the function is vararg and (C - 1) is its number of 343 returning; in this case, (C - 1) is its number of fixed parameters.
344 fixed parameters.
345 344
346 (*) In comparisons with an immediate operand, C signals whether the 345 (*) In comparisons with an immediate operand, C signals whether the
347 original operand was a float. 346 original operand was a float.
diff --git a/lvm.c b/lvm.c
index 9838500b..7e6f148d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1564,16 +1564,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1564 } 1564 }
1565 vmcase(OP_TAILCALL) { 1565 vmcase(OP_TAILCALL) {
1566 int b = GETARG_B(i); /* number of arguments + 1 (function) */ 1566 int b = GETARG_B(i); /* number of arguments + 1 (function) */
1567 int delta = 0; /* virtual 'func' - real 'func' (vararg functions) */ 1567 int nparams1 = GETARG_C(i);
1568 /* delat is virtual 'func' - real 'func' (vararg functions) */
1569 int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
1568 if (b != 0) 1570 if (b != 0)
1569 L->top = ra + b; 1571 L->top = ra + b;
1570 else /* previous instruction set top */ 1572 else /* previous instruction set top */
1571 b = cast_int(L->top - ra); 1573 b = cast_int(L->top - ra);
1572 savepc(ci); /* some calls here can raise errors */ 1574 savepc(ci); /* some calls here can raise errors */
1573 if (TESTARG_k(i)) { 1575 if (TESTARG_k(i)) {
1574 int nparams1 = GETARG_C(i);
1575 if (nparams1) /* vararg function? */
1576 delta = ci->u.l.nextraargs + nparams1;
1577 /* close upvalues from current call; the compiler ensures 1576 /* close upvalues from current call; the compiler ensures
1578 that there are no to-be-closed variables here */ 1577 that there are no to-be-closed variables here */
1579 luaF_close(L, base, NOCLOSINGMETH); 1578 luaF_close(L, base, NOCLOSINGMETH);
@@ -1599,18 +1598,18 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1599 } 1598 }
1600 vmcase(OP_RETURN) { 1599 vmcase(OP_RETURN) {
1601 int n = GETARG_B(i) - 1; /* number of results */ 1600 int n = GETARG_B(i) - 1; /* number of results */
1601 int nparams1 = GETARG_C(i);
1602 if (n < 0) /* not fixed? */ 1602 if (n < 0) /* not fixed? */
1603 n = cast_int(L->top - ra); /* get what is available */ 1603 n = cast_int(L->top - ra); /* get what is available */
1604 savepc(ci); 1604 savepc(ci);
1605 if (TESTARG_k(i)) { 1605 if (TESTARG_k(i)) {
1606 int nparams1 = GETARG_C(i);
1607 if (L->top < ci->top) 1606 if (L->top < ci->top)
1608 L->top = ci->top; 1607 L->top = ci->top;
1609 luaF_close(L, base, LUA_OK); /* there may be open upvalues */ 1608 luaF_close(L, base, LUA_OK); /* there may be open upvalues */
1610 updatestack(ci); 1609 updatestack(ci);
1611 if (nparams1) /* vararg function? */
1612 ci->func -= ci->u.l.nextraargs + nparams1;
1613 } 1610 }
1611 if (nparams1) /* vararg function? */
1612 ci->func -= ci->u.l.nextraargs + nparams1;
1614 L->top = ra + n; /* set call for 'luaD_poscall' */ 1613 L->top = ra + n; /* set call for 'luaD_poscall' */
1615 luaD_poscall(L, ci, n); 1614 luaD_poscall(L, ci, n);
1616 return; 1615 return;