300-opcode_performance.patch 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. --- a/src/lvm.c
  2. +++ b/src/lvm.c
  3. @@ -31,6 +31,9 @@
  4. /* limit for table tag-method chains (to avoid loops) */
  5. #define MAXTAGLOOP 100
  6. +#ifdef __GNUC__
  7. +#define COMPUTED_GOTO 1
  8. +#endif
  9. /*
  10. * If 'obj' is a string, it is tried to be interpreted as a number.
  11. @@ -566,12 +569,63 @@ static inline int arith_mode( const TVal
  12. ARITH_OP1_END
  13. #endif
  14. +#ifdef COMPUTED_GOTO
  15. +#define OPCODE_TARGET(op) DO_OP_##op:
  16. +#define CALL_OPCODE(op) goto *opcodes[op];
  17. +#define OPCODE_PTR(op) [OP_##op] = &&DO_OP_##op
  18. +#else
  19. +#define OPCODE_TARGET(op) case OP_##op:
  20. +#define CALL_OPCODE(op) switch (op)
  21. +#endif
  22. +
  23. void luaV_execute (lua_State *L, int nexeccalls) {
  24. LClosure *cl;
  25. StkId base;
  26. TValue *k;
  27. const Instruction *pc;
  28. +#ifdef COMPUTED_GOTO
  29. + static const void *opcodes[] = {
  30. + OPCODE_PTR(MOVE),
  31. + OPCODE_PTR(LOADK),
  32. + OPCODE_PTR(LOADBOOL),
  33. + OPCODE_PTR(LOADNIL),
  34. + OPCODE_PTR(GETUPVAL),
  35. + OPCODE_PTR(GETGLOBAL),
  36. + OPCODE_PTR(GETTABLE),
  37. + OPCODE_PTR(SETGLOBAL),
  38. + OPCODE_PTR(SETUPVAL),
  39. + OPCODE_PTR(SETTABLE),
  40. + OPCODE_PTR(NEWTABLE),
  41. + OPCODE_PTR(SELF),
  42. + OPCODE_PTR(ADD),
  43. + OPCODE_PTR(SUB),
  44. + OPCODE_PTR(MUL),
  45. + OPCODE_PTR(DIV),
  46. + OPCODE_PTR(MOD),
  47. + OPCODE_PTR(POW),
  48. + OPCODE_PTR(UNM),
  49. + OPCODE_PTR(NOT),
  50. + OPCODE_PTR(LEN),
  51. + OPCODE_PTR(CONCAT),
  52. + OPCODE_PTR(JMP),
  53. + OPCODE_PTR(EQ),
  54. + OPCODE_PTR(LT),
  55. + OPCODE_PTR(LE),
  56. + OPCODE_PTR(TEST),
  57. + OPCODE_PTR(TESTSET),
  58. + OPCODE_PTR(CALL),
  59. + OPCODE_PTR(TAILCALL),
  60. + OPCODE_PTR(RETURN),
  61. + OPCODE_PTR(FORLOOP),
  62. + OPCODE_PTR(FORPREP),
  63. + OPCODE_PTR(TFORLOOP),
  64. + OPCODE_PTR(SETLIST),
  65. + OPCODE_PTR(CLOSE),
  66. + OPCODE_PTR(CLOSURE),
  67. + OPCODE_PTR(VARARG)
  68. + };
  69. +#endif
  70. reentry: /* entry point */
  71. lua_assert(isLua(L->ci));
  72. pc = L->savedpc;
  73. @@ -596,33 +650,33 @@ void luaV_execute (lua_State *L, int nex
  74. lua_assert(base == L->base && L->base == L->ci->base);
  75. lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
  76. lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
  77. - switch (GET_OPCODE(i)) {
  78. - case OP_MOVE: {
  79. + CALL_OPCODE(GET_OPCODE(i)) {
  80. + OPCODE_TARGET(MOVE) {
  81. setobjs2s(L, ra, RB(i));
  82. continue;
  83. }
  84. - case OP_LOADK: {
  85. + OPCODE_TARGET(LOADK) {
  86. setobj2s(L, ra, KBx(i));
  87. continue;
  88. }
  89. - case OP_LOADBOOL: {
  90. + OPCODE_TARGET(LOADBOOL) {
  91. setbvalue(ra, GETARG_B(i));
  92. if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
  93. continue;
  94. }
  95. - case OP_LOADNIL: {
  96. + OPCODE_TARGET(LOADNIL) {
  97. TValue *rb = RB(i);
  98. do {
  99. setnilvalue(rb--);
  100. } while (rb >= ra);
  101. continue;
  102. }
  103. - case OP_GETUPVAL: {
  104. + OPCODE_TARGET(GETUPVAL) {
  105. int b = GETARG_B(i);
  106. setobj2s(L, ra, cl->upvals[b]->v);
  107. continue;
  108. }
  109. - case OP_GETGLOBAL: {
  110. + OPCODE_TARGET(GETGLOBAL) {
  111. TValue g;
  112. TValue *rb = KBx(i);
  113. sethvalue(L, &g, cl->env);
  114. @@ -630,88 +684,88 @@ void luaV_execute (lua_State *L, int nex
  115. Protect(luaV_gettable(L, &g, rb, ra));
  116. continue;
  117. }
  118. - case OP_GETTABLE: {
  119. + OPCODE_TARGET(GETTABLE) {
  120. Protect(luaV_gettable(L, RB(i), RKC(i), ra));
  121. continue;
  122. }
  123. - case OP_SETGLOBAL: {
  124. + OPCODE_TARGET(SETGLOBAL) {
  125. TValue g;
  126. sethvalue(L, &g, cl->env);
  127. lua_assert(ttisstring(KBx(i)));
  128. Protect(luaV_settable(L, &g, KBx(i), ra));
  129. continue;
  130. }
  131. - case OP_SETUPVAL: {
  132. + OPCODE_TARGET(SETUPVAL) {
  133. UpVal *uv = cl->upvals[GETARG_B(i)];
  134. setobj(L, uv->v, ra);
  135. luaC_barrier(L, uv, ra);
  136. continue;
  137. }
  138. - case OP_SETTABLE: {
  139. + OPCODE_TARGET(SETTABLE) {
  140. Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
  141. continue;
  142. }
  143. - case OP_NEWTABLE: {
  144. + OPCODE_TARGET(NEWTABLE) {
  145. int b = GETARG_B(i);
  146. int c = GETARG_C(i);
  147. sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
  148. Protect(luaC_checkGC(L));
  149. continue;
  150. }
  151. - case OP_SELF: {
  152. + OPCODE_TARGET(SELF) {
  153. StkId rb = RB(i);
  154. setobjs2s(L, ra+1, rb);
  155. Protect(luaV_gettable(L, rb, RKC(i), ra));
  156. continue;
  157. }
  158. - case OP_ADD: {
  159. + OPCODE_TARGET(ADD) {
  160. TValue *rb = RKB(i), *rc= RKC(i);
  161. arith_op_continue( luai_numadd, try_addint, luai_vectadd );
  162. Protect(Arith(L, ra, rb, rc, TM_ADD)); \
  163. continue;
  164. }
  165. - case OP_SUB: {
  166. + OPCODE_TARGET(SUB) {
  167. TValue *rb = RKB(i), *rc= RKC(i);
  168. arith_op_continue( luai_numsub, try_subint, luai_vectsub );
  169. Protect(Arith(L, ra, rb, rc, TM_SUB));
  170. continue;
  171. }
  172. - case OP_MUL: {
  173. + OPCODE_TARGET(MUL) {
  174. TValue *rb = RKB(i), *rc= RKC(i);
  175. arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
  176. Protect(Arith(L, ra, rb, rc, TM_MUL));
  177. continue;
  178. }
  179. - case OP_DIV: {
  180. + OPCODE_TARGET(DIV) {
  181. TValue *rb = RKB(i), *rc= RKC(i);
  182. arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
  183. Protect(Arith(L, ra, rb, rc, TM_DIV));
  184. continue;
  185. }
  186. - case OP_MOD: {
  187. + OPCODE_TARGET(MOD) {
  188. TValue *rb = RKB(i), *rc= RKC(i);
  189. arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
  190. Protect(Arith(L, ra, rb, rc, TM_MOD));
  191. continue;
  192. }
  193. - case OP_POW: {
  194. + OPCODE_TARGET(POW) {
  195. TValue *rb = RKB(i), *rc= RKC(i);
  196. arith_op_continue(luai_numpow, try_powint, luai_vectpow);
  197. Protect(Arith(L, ra, rb, rc, TM_POW));
  198. continue;
  199. }
  200. - case OP_UNM: {
  201. + OPCODE_TARGET(UNM) {
  202. TValue *rb = RB(i);
  203. arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
  204. Protect(Arith(L, ra, rb, rb, TM_UNM));
  205. continue;
  206. }
  207. - case OP_NOT: {
  208. + OPCODE_TARGET(NOT) {
  209. int res = l_isfalse(RB(i)); /* next assignment may change this value */
  210. setbvalue(ra, res);
  211. continue;
  212. }
  213. - case OP_LEN: {
  214. + OPCODE_TARGET(LEN) {
  215. const TValue *rb = RB(i);
  216. switch (ttype(rb)) {
  217. case LUA_TTABLE: {
  218. @@ -731,18 +785,18 @@ void luaV_execute (lua_State *L, int nex
  219. }
  220. continue;
  221. }
  222. - case OP_CONCAT: {
  223. + OPCODE_TARGET(CONCAT) {
  224. int b = GETARG_B(i);
  225. int c = GETARG_C(i);
  226. Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
  227. setobjs2s(L, RA(i), base+b);
  228. continue;
  229. }
  230. - case OP_JMP: {
  231. + OPCODE_TARGET(JMP) {
  232. dojump(L, pc, GETARG_sBx(i));
  233. continue;
  234. }
  235. - case OP_EQ: {
  236. + OPCODE_TARGET(EQ) {
  237. TValue *rb = RKB(i);
  238. TValue *rc = RKC(i);
  239. Protect(
  240. @@ -752,7 +806,7 @@ void luaV_execute (lua_State *L, int nex
  241. pc++;
  242. continue;
  243. }
  244. - case OP_LT: {
  245. + OPCODE_TARGET(LT) {
  246. Protect(
  247. if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
  248. dojump(L, pc, GETARG_sBx(*pc));
  249. @@ -760,7 +814,7 @@ void luaV_execute (lua_State *L, int nex
  250. pc++;
  251. continue;
  252. }
  253. - case OP_LE: {
  254. + OPCODE_TARGET(LE) {
  255. Protect(
  256. if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
  257. dojump(L, pc, GETARG_sBx(*pc));
  258. @@ -768,13 +822,13 @@ void luaV_execute (lua_State *L, int nex
  259. pc++;
  260. continue;
  261. }
  262. - case OP_TEST: {
  263. + OPCODE_TARGET(TEST) {
  264. if (l_isfalse(ra) != GETARG_C(i))
  265. dojump(L, pc, GETARG_sBx(*pc));
  266. pc++;
  267. continue;
  268. }
  269. - case OP_TESTSET: {
  270. + OPCODE_TARGET(TESTSET) {
  271. TValue *rb = RB(i);
  272. if (l_isfalse(rb) != GETARG_C(i)) {
  273. setobjs2s(L, ra, rb);
  274. @@ -783,7 +837,7 @@ void luaV_execute (lua_State *L, int nex
  275. pc++;
  276. continue;
  277. }
  278. - case OP_CALL: {
  279. + OPCODE_TARGET(CALL) {
  280. int b = GETARG_B(i);
  281. int nresults = GETARG_C(i) - 1;
  282. if (b != 0) L->top = ra+b; /* else previous instruction set top */
  283. @@ -804,7 +858,7 @@ void luaV_execute (lua_State *L, int nex
  284. }
  285. }
  286. }
  287. - case OP_TAILCALL: {
  288. + OPCODE_TARGET(TAILCALL) {
  289. int b = GETARG_B(i);
  290. if (b != 0) L->top = ra+b; /* else previous instruction set top */
  291. L->savedpc = pc;
  292. @@ -836,7 +890,7 @@ void luaV_execute (lua_State *L, int nex
  293. }
  294. }
  295. }
  296. - case OP_RETURN: {
  297. + OPCODE_TARGET(RETURN) {
  298. int b = GETARG_B(i);
  299. if (b != 0) L->top = ra+b-1;
  300. if (L->openupval) luaF_close(L, base);
  301. @@ -851,7 +905,7 @@ void luaV_execute (lua_State *L, int nex
  302. goto reentry;
  303. }
  304. }
  305. - case OP_FORLOOP: {
  306. + OPCODE_TARGET(FORLOOP) {
  307. /* If start,step and limit are all integers, we don't need to check
  308. * against overflow in the looping.
  309. */
  310. @@ -879,7 +933,7 @@ void luaV_execute (lua_State *L, int nex
  311. }
  312. continue;
  313. }
  314. - case OP_FORPREP: {
  315. + OPCODE_TARGET(FORPREP) {
  316. const TValue *init = ra;
  317. const TValue *plimit = ra+1;
  318. const TValue *pstep = ra+2;
  319. @@ -902,7 +956,7 @@ void luaV_execute (lua_State *L, int nex
  320. dojump(L, pc, GETARG_sBx(i));
  321. continue;
  322. }
  323. - case OP_TFORLOOP: {
  324. + OPCODE_TARGET(TFORLOOP) {
  325. StkId cb = ra + 3; /* call base */
  326. setobjs2s(L, cb+2, ra+2);
  327. setobjs2s(L, cb+1, ra+1);
  328. @@ -918,7 +972,7 @@ void luaV_execute (lua_State *L, int nex
  329. pc++;
  330. continue;
  331. }
  332. - case OP_SETLIST: {
  333. + OPCODE_TARGET(SETLIST) {
  334. int n = GETARG_B(i);
  335. int c = GETARG_C(i);
  336. int last;
  337. @@ -940,11 +994,11 @@ void luaV_execute (lua_State *L, int nex
  338. }
  339. continue;
  340. }
  341. - case OP_CLOSE: {
  342. + OPCODE_TARGET(CLOSE) {
  343. luaF_close(L, ra);
  344. continue;
  345. }
  346. - case OP_CLOSURE: {
  347. + OPCODE_TARGET(CLOSURE) {
  348. Proto *p;
  349. Closure *ncl;
  350. int nup, j;
  351. @@ -964,7 +1018,7 @@ void luaV_execute (lua_State *L, int nex
  352. Protect(luaC_checkGC(L));
  353. continue;
  354. }
  355. - case OP_VARARG: {
  356. + OPCODE_TARGET(VARARG) {
  357. int b = GETARG_B(i) - 1;
  358. int j;
  359. CallInfo *ci = L->ci;