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 | |
| 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.)
| -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) { |
