diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-21 16:43:44 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-21 16:43:44 -0300 |
commit | c72ac048b989bea0f66f8532ab00a598da71e46d (patch) | |
tree | 5cbb6792669c5dc2bff71db6bcfce40b26eec46d /lvm.c | |
parent | b03dddf9e406f29e5d8bfa06ccb6db1dfad6e405 (diff) | |
download | lua-c72ac048b989bea0f66f8532ab00a598da71e46d.tar.gz lua-c72ac048b989bea0f66f8532ab00a598da71e46d.tar.bz2 lua-c72ac048b989bea0f66f8532ab00a598da71e46d.zip |
conditional jumps "deunified"
(if a jump table is used, the unification may harm jump prediction.)
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 43 |
1 files changed, 28 insertions, 15 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.344 2018/02/21 13:47:03 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.345 2018/02/21 15:49:32 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 | */ |
@@ -805,6 +805,14 @@ void luaV_finishOp (lua_State *L) { | |||
805 | #define donextjump(ci) { i = *pc; dojump(ci, i, 1); } | 805 | #define donextjump(ci) { i = *pc; dojump(ci, i, 1); } |
806 | 806 | ||
807 | /* | 807 | /* |
808 | ** do a conditional jump: skip next instruction if 'cond' is not what | ||
809 | ** was expected (parameter 'k'), else do next instruction, which must | ||
810 | ** be a jump. | ||
811 | */ | ||
812 | #define docondjump() if (cond != GETARG_k(i)) pc++; else donextjump(ci); | ||
813 | |||
814 | |||
815 | /* | ||
808 | ** Correct global 'pc'. | 816 | ** Correct global 'pc'. |
809 | */ | 817 | */ |
810 | #define savepc(L) (ci->u.l.savedpc = pc) | 818 | #define savepc(L) (ci->u.l.savedpc = pc) |
@@ -1428,7 +1436,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1428 | vmcase(OP_EQ) { | 1436 | vmcase(OP_EQ) { |
1429 | TValue *rb = vRB(i); | 1437 | TValue *rb = vRB(i); |
1430 | Protect(cond = luaV_equalobj(L, vra, rb)); | 1438 | Protect(cond = luaV_equalobj(L, vra, rb)); |
1431 | goto condjump; | 1439 | docondjump(); |
1440 | vmbreak; | ||
1432 | } | 1441 | } |
1433 | vmcase(OP_LT) { | 1442 | vmcase(OP_LT) { |
1434 | TValue *rb = vRB(i); | 1443 | TValue *rb = vRB(i); |
@@ -1438,7 +1447,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1438 | cond = LTnum(vra, rb); | 1447 | cond = LTnum(vra, rb); |
1439 | else | 1448 | else |
1440 | Protect(cond = lessthanothers(L, vra, rb)); | 1449 | Protect(cond = lessthanothers(L, vra, rb)); |
1441 | goto condjump; | 1450 | docondjump(); |
1451 | vmbreak; | ||
1442 | } | 1452 | } |
1443 | vmcase(OP_LE) { | 1453 | vmcase(OP_LE) { |
1444 | TValue *rb = vRB(i); | 1454 | TValue *rb = vRB(i); |
@@ -1448,13 +1458,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1448 | cond = LEnum(vra, rb); | 1458 | cond = LEnum(vra, rb); |
1449 | else | 1459 | else |
1450 | Protect(cond = lessequalothers(L, vra, rb)); | 1460 | Protect(cond = lessequalothers(L, vra, rb)); |
1451 | goto condjump; | 1461 | docondjump(); |
1462 | vmbreak; | ||
1452 | } | 1463 | } |
1453 | vmcase(OP_EQK) { | 1464 | vmcase(OP_EQK) { |
1454 | TValue *rb = KB(i); | 1465 | TValue *rb = KB(i); |
1455 | /* basic types do not use '__eq'; we can use raw equality */ | 1466 | /* basic types do not use '__eq'; we can use raw equality */ |
1456 | cond = luaV_equalobj(NULL, vra, rb); | 1467 | cond = luaV_equalobj(NULL, vra, rb); |
1457 | goto condjump; | 1468 | docondjump(); |
1469 | vmbreak; | ||
1458 | } | 1470 | } |
1459 | vmcase(OP_EQI) { | 1471 | vmcase(OP_EQI) { |
1460 | int im = GETARG_sB(i); | 1472 | int im = GETARG_sB(i); |
@@ -1464,7 +1476,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1464 | cond = luai_numeq(fltvalue(vra), cast_num(im)); | 1476 | cond = luai_numeq(fltvalue(vra), cast_num(im)); |
1465 | else | 1477 | else |
1466 | cond = 0; /* other types cannot be equal to a number */ | 1478 | cond = 0; /* other types cannot be equal to a number */ |
1467 | goto condjump; | 1479 | docondjump(); |
1480 | vmbreak; | ||
1468 | } | 1481 | } |
1469 | vmcase(OP_LTI) { | 1482 | vmcase(OP_LTI) { |
1470 | int im = GETARG_sB(i); | 1483 | int im = GETARG_sB(i); |
@@ -1474,7 +1487,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1474 | cond = luai_numlt(fltvalue(vra), cast_num(im)); | 1487 | cond = luai_numlt(fltvalue(vra), cast_num(im)); |
1475 | else | 1488 | else |
1476 | Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LT)); | 1489 | Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LT)); |
1477 | goto condjump; | 1490 | docondjump(); |
1491 | vmbreak; | ||
1478 | } | 1492 | } |
1479 | vmcase(OP_LEI) { | 1493 | vmcase(OP_LEI) { |
1480 | int im = GETARG_sB(i); | 1494 | int im = GETARG_sB(i); |
@@ -1484,7 +1498,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1484 | cond = luai_numle(fltvalue(vra), cast_num(im)); | 1498 | cond = luai_numle(fltvalue(vra), cast_num(im)); |
1485 | else | 1499 | else |
1486 | Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LE)); | 1500 | Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LE)); |
1487 | goto condjump; | 1501 | docondjump(); |
1502 | vmbreak; | ||
1488 | } | 1503 | } |
1489 | vmcase(OP_GTI) { | 1504 | vmcase(OP_GTI) { |
1490 | int im = GETARG_sB(i); | 1505 | int im = GETARG_sB(i); |
@@ -1494,7 +1509,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1494 | cond = luai_numlt(cast_num(im), fltvalue(vra)); | 1509 | cond = luai_numlt(cast_num(im), fltvalue(vra)); |
1495 | else | 1510 | else |
1496 | Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LT)); | 1511 | Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LT)); |
1497 | goto condjump; | 1512 | docondjump(); |
1513 | vmbreak; | ||
1498 | } | 1514 | } |
1499 | vmcase(OP_GEI) { | 1515 | vmcase(OP_GEI) { |
1500 | int im = GETARG_sB(i); | 1516 | int im = GETARG_sB(i); |
@@ -1504,15 +1520,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1504 | cond = luai_numle(cast_num(im), fltvalue(vra)); | 1520 | cond = luai_numle(cast_num(im), fltvalue(vra)); |
1505 | else | 1521 | else |
1506 | Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LE)); | 1522 | Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LE)); |
1507 | goto condjump; | 1523 | docondjump(); |
1524 | vmbreak; | ||
1508 | } | 1525 | } |
1509 | vmcase(OP_TEST) { | 1526 | vmcase(OP_TEST) { |
1510 | cond = !l_isfalse(vra); | 1527 | cond = !l_isfalse(vra); |
1511 | condjump: | 1528 | docondjump(); |
1512 | if (cond != GETARG_k(i)) | ||
1513 | pc++; /* skip next jump */ | ||
1514 | else | ||
1515 | donextjump(ci); | ||
1516 | vmbreak; | 1529 | vmbreak; |
1517 | } | 1530 | } |
1518 | vmcase(OP_TESTSET) { | 1531 | vmcase(OP_TESTSET) { |