more integer fast tracks (for OP_LT, OP_LE, OP_SETTABLE, and OP_GETTABLE)

This commit is contained in:
Roberto Ierusalimschy 2017-05-10 14:32:19 -03:00
parent b1b7790f7c
commit 7184f6343a
1 changed files with 51 additions and 17 deletions

68
lvm.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 2.277 2017/05/05 17:16:11 roberto Exp roberto $ ** $Id: lvm.c,v 2.278 2017/05/08 16:08:01 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -118,10 +118,9 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
/* /*
** Try to convert a 'for' limit to an integer, preserving the ** Try to convert a 'for' limit to an integer, preserving the semantics
** semantics of the loop. ** of the loop. (The following explanation assumes a non-negative step;
** (The following explanation assumes a non-negative step; it is valid ** it is valid for negative steps mutatis mutandis.)
** for negative steps mutatis mutandis.)
** If the limit can be converted to an integer, rounding down, that is ** If the limit can be converted to an integer, rounding down, that is
** it. ** it.
** Otherwise, check whether the limit can be converted to a number. If ** Otherwise, check whether the limit can be converted to a number. If
@ -807,6 +806,19 @@ void luaV_finishOp (lua_State *L) {
Protect(luaV_finishset(L,t,k,v,slot)); } Protect(luaV_finishset(L,t,k,v,slot)); }
/*
** Predicate for integer fast track in GET/SETTABLE.
** (Strings are usually constant and therefore coded with
** GET/SETFIELD). Check that index is an integer, "table" is
** a table, index is in the array part, and value is not nil
** (otherwise it will need metamethods). Use 'n' and 't' for
** for caching the integer and table values.
*/
#define fastintindex(tbl,idx,t,n) \
(ttisinteger(idx) && ttistable(tbl) && \
(n = l_castS2U(ivalue(idx)) - 1u, t = hvalue(tbl), \
n < t->sizearray) && !ttisnil(&t->array[n]))
void luaV_execute (lua_State *L) { void luaV_execute (lua_State *L) {
CallInfo *ci = L->ci; CallInfo *ci = L->ci;
@ -889,7 +901,12 @@ void luaV_execute (lua_State *L) {
vmcase(OP_GETTABLE) { vmcase(OP_GETTABLE) {
StkId rb = RB(i); StkId rb = RB(i);
TValue *rc = RC(i); TValue *rc = RC(i);
gettableProtected(L, rb, rc, ra); Table *t; lua_Unsigned n;
if (fastintindex(rb, rc, t, n)) {
setobj2s(L, ra, &t->array[n]);
}
else
gettableProtected(L, rb, rc, ra);
vmbreak; vmbreak;
} }
vmcase(OP_GETI) { vmcase(OP_GETI) {
@ -930,7 +947,12 @@ void luaV_execute (lua_State *L) {
vmcase(OP_SETTABLE) { vmcase(OP_SETTABLE) {
TValue *rb = RB(i); TValue *rb = RB(i);
TValue *rc = RKC(i); TValue *rc = RKC(i);
settableProtected(L, ra, rb, rc); Table *t; lua_Unsigned n;
if (fastintindex(ra, rb, t, n)) {
setobj2t(L, &t->array[n], rc);
}
else
settableProtected(L, ra, rb, rc);
vmbreak; vmbreak;
} }
vmcase(OP_SETI) { vmcase(OP_SETI) {
@ -1205,21 +1227,33 @@ void luaV_execute (lua_State *L) {
vmbreak; vmbreak;
} }
vmcase(OP_LT) { vmcase(OP_LT) {
Protect( TValue *rb = RKB(i);
if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) TValue *rc = RKC(i);
pc++; int res;
else if (ttisinteger(rb) && ttisinteger(rc))
donextjump(ci); res = (ivalue(rb) < ivalue(rc));
else Protect(
res = luaV_lessthan(L, rb, rc);
) )
if (res != GETARG_A(i))
pc++;
else
donextjump(ci);
vmbreak; vmbreak;
} }
vmcase(OP_LE) { vmcase(OP_LE) {
Protect( TValue *rb = RKB(i);
if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) TValue *rc = RKC(i);
pc++; int res;
else if (ttisinteger(rb) && ttisinteger(rc))
donextjump(ci); res = (ivalue(rb) <= ivalue(rc));
else Protect(
res = luaV_lessequal(L, rb, rc);
) )
if (res != GETARG_A(i))
pc++;
else
donextjump(ci);
vmbreak; vmbreak;
} }
vmcase(OP_TEST) { vmcase(OP_TEST) {