diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-16 15:44:37 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-16 15:44:37 -0300 |
commit | 4846f7e3bb1397142ab0de808ae59c08db9832a6 (patch) | |
tree | de10475ba2b2f0713edc91f5bff801bd7eaa0b3d | |
parent | c220b0a5d099372e58e517b9f13eaa7bb0bec45c (diff) | |
download | lua-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.c | 8 | ||||
-rw-r--r-- | lopcodes.h | 7 | ||||
-rw-r--r-- | lvm.c | 13 |
3 files changed, 13 insertions, 15 deletions
@@ -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: { |
@@ -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. |
@@ -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; |