Root/package/lua/patches/300-opcode_performance.patch

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

Archive Download this file



interactive