aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-05-10 14:32:19 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-05-10 14:32:19 -0300
commit7184f6343a0074d02f6f0e35654cfa55427710d3 (patch)
treeaf61de861ce4095b82aade942b7878d15564d9af
parentb1b7790f7cf11708221aff37b4da816de97300fb (diff)
downloadlua-7184f6343a0074d02f6f0e35654cfa55427710d3.tar.gz
lua-7184f6343a0074d02f6f0e35654cfa55427710d3.tar.bz2
lua-7184f6343a0074d02f6f0e35654cfa55427710d3.zip
more integer fast tracks (for OP_LT, OP_LE, OP_SETTABLE, and OP_GETTABLE)
-rw-r--r--lvm.c68
1 files changed, 51 insertions, 17 deletions
diff --git a/lvm.c b/lvm.c
index 1a7531e1..27d467f3 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.277 2017/05/05 17:16:11 roberto Exp roberto $ 2** $Id: lvm.c,v 2.278 2017/05/08 16:08:01 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -118,10 +118,9 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
118 118
119 119
120/* 120/*
121** Try to convert a 'for' limit to an integer, preserving the 121** Try to convert a 'for' limit to an integer, preserving the semantics
122** semantics of the loop. 122** of the loop. (The following explanation assumes a non-negative step;
123** (The following explanation assumes a non-negative step; it is valid 123** it is valid for negative steps mutatis mutandis.)
124** for negative steps mutatis mutandis.)
125** If the limit can be converted to an integer, rounding down, that is 124** If the limit can be converted to an integer, rounding down, that is
126** it. 125** it.
127** Otherwise, check whether the limit can be converted to a number. If 126** Otherwise, check whether the limit can be converted to a number. If
@@ -807,6 +806,19 @@ void luaV_finishOp (lua_State *L) {
807 Protect(luaV_finishset(L,t,k,v,slot)); } 806 Protect(luaV_finishset(L,t,k,v,slot)); }
808 807
809 808
809/*
810** Predicate for integer fast track in GET/SETTABLE.
811** (Strings are usually constant and therefore coded with
812** GET/SETFIELD). Check that index is an integer, "table" is
813** a table, index is in the array part, and value is not nil
814** (otherwise it will need metamethods). Use 'n' and 't' for
815** for caching the integer and table values.
816*/
817#define fastintindex(tbl,idx,t,n) \
818 (ttisinteger(idx) && ttistable(tbl) && \
819 (n = l_castS2U(ivalue(idx)) - 1u, t = hvalue(tbl), \
820 n < t->sizearray) && !ttisnil(&t->array[n]))
821
810 822
811void luaV_execute (lua_State *L) { 823void luaV_execute (lua_State *L) {
812 CallInfo *ci = L->ci; 824 CallInfo *ci = L->ci;
@@ -889,7 +901,12 @@ void luaV_execute (lua_State *L) {
889 vmcase(OP_GETTABLE) { 901 vmcase(OP_GETTABLE) {
890 StkId rb = RB(i); 902 StkId rb = RB(i);
891 TValue *rc = RC(i); 903 TValue *rc = RC(i);
892 gettableProtected(L, rb, rc, ra); 904 Table *t; lua_Unsigned n;
905 if (fastintindex(rb, rc, t, n)) {
906 setobj2s(L, ra, &t->array[n]);
907 }
908 else
909 gettableProtected(L, rb, rc, ra);
893 vmbreak; 910 vmbreak;
894 } 911 }
895 vmcase(OP_GETI) { 912 vmcase(OP_GETI) {
@@ -930,7 +947,12 @@ void luaV_execute (lua_State *L) {
930 vmcase(OP_SETTABLE) { 947 vmcase(OP_SETTABLE) {
931 TValue *rb = RB(i); 948 TValue *rb = RB(i);
932 TValue *rc = RKC(i); 949 TValue *rc = RKC(i);
933 settableProtected(L, ra, rb, rc); 950 Table *t; lua_Unsigned n;
951 if (fastintindex(ra, rb, t, n)) {
952 setobj2t(L, &t->array[n], rc);
953 }
954 else
955 settableProtected(L, ra, rb, rc);
934 vmbreak; 956 vmbreak;
935 } 957 }
936 vmcase(OP_SETI) { 958 vmcase(OP_SETI) {
@@ -1205,21 +1227,33 @@ void luaV_execute (lua_State *L) {
1205 vmbreak; 1227 vmbreak;
1206 } 1228 }
1207 vmcase(OP_LT) { 1229 vmcase(OP_LT) {
1208 Protect( 1230 TValue *rb = RKB(i);
1209 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) 1231 TValue *rc = RKC(i);
1210 pc++; 1232 int res;
1211 else 1233 if (ttisinteger(rb) && ttisinteger(rc))
1212 donextjump(ci); 1234 res = (ivalue(rb) < ivalue(rc));
1235 else Protect(
1236 res = luaV_lessthan(L, rb, rc);
1213 ) 1237 )
1238 if (res != GETARG_A(i))
1239 pc++;
1240 else
1241 donextjump(ci);
1214 vmbreak; 1242 vmbreak;
1215 } 1243 }
1216 vmcase(OP_LE) { 1244 vmcase(OP_LE) {
1217 Protect( 1245 TValue *rb = RKB(i);
1218 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) 1246 TValue *rc = RKC(i);
1219 pc++; 1247 int res;
1220 else 1248 if (ttisinteger(rb) && ttisinteger(rc))
1221 donextjump(ci); 1249 res = (ivalue(rb) <= ivalue(rc));
1250 else Protect(
1251 res = luaV_lessequal(L, rb, rc);
1222 ) 1252 )
1253 if (res != GETARG_A(i))
1254 pc++;
1255 else
1256 donextjump(ci);
1223 vmbreak; 1257 vmbreak;
1224 } 1258 }
1225 vmcase(OP_TEST) { 1259 vmcase(OP_TEST) {