summaryrefslogtreecommitdiff
path: root/src/lj_dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_dispatch.c')
-rw-r--r--src/lj_dispatch.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index 54cc9006..72211dca 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -11,6 +11,7 @@
11#include "lj_state.h" 11#include "lj_state.h"
12#include "lj_frame.h" 12#include "lj_frame.h"
13#include "lj_bc.h" 13#include "lj_bc.h"
14#include "lj_ff.h"
14#if LJ_HASJIT 15#if LJ_HASJIT
15#include "lj_jit.h" 16#include "lj_jit.h"
16#endif 17#endif
@@ -19,7 +20,8 @@
19#include "lj_vm.h" 20#include "lj_vm.h"
20#include "luajit.h" 21#include "luajit.h"
21 22
22#define GG_DISP_STATIC BC__MAX 23/* Bump GG_NUM_ASMFF in lj_dispatch.h as needed. Ugly. */
24LJ_STATIC_ASSERT(GG_NUM_ASMFF == FF_NUM_ASMFUNC);
23 25
24/* -- Dispatch table management ------------------------------------------- */ 26/* -- Dispatch table management ------------------------------------------- */
25 27
@@ -27,13 +29,20 @@
27void lj_dispatch_init(GG_State *GG) 29void lj_dispatch_init(GG_State *GG)
28{ 30{
29 uint32_t i; 31 uint32_t i;
30 ASMFunction *disp = GG2DISP(GG); 32 ASMFunction *disp = GG->dispatch;
31 for (i = 0; i < BC__MAX; i++) 33 for (i = 0; i < GG_LEN_SDISP; i++)
32 disp[GG_DISP_STATIC+i] = disp[i] = makeasmfunc(lj_bc_ofs[i]); 34 disp[GG_LEN_DDISP+i] = disp[i] = makeasmfunc(lj_bc_ofs[i]);
35 for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
36 disp[i] = makeasmfunc(lj_bc_ofs[i]);
33 /* The JIT engine is off by default. luaopen_jit() turns it on. */ 37 /* The JIT engine is off by default. luaopen_jit() turns it on. */
34 disp[BC_FORL] = disp[BC_IFORL]; 38 disp[BC_FORL] = disp[BC_IFORL];
35 disp[BC_ITERL] = disp[BC_IITERL]; 39 disp[BC_ITERL] = disp[BC_IITERL];
36 disp[BC_LOOP] = disp[BC_ILOOP]; 40 disp[BC_LOOP] = disp[BC_ILOOP];
41 disp[BC_FUNCF] = disp[BC_IFUNCF];
42 disp[BC_FUNCV] = disp[BC_IFUNCV];
43 GG->g.bc_cfunc_ext = GG->g.bc_cfunc_int = BCINS_AD(BC_FUNCC, 0, 0);
44 for (i = 0; i < GG_NUM_ASMFF; i++)
45 GG->bcff[i] = BCINS_AD(BC__MAX+i, 0, 0);
37} 46}
38 47
39#if LJ_HASJIT 48#if LJ_HASJIT
@@ -57,39 +66,50 @@ void lj_dispatch_update(global_State *g)
57 mode |= (G2J(g)->flags & JIT_F_ON) ? 1 : 0; 66 mode |= (G2J(g)->flags & JIT_F_ON) ? 1 : 0;
58 mode |= G2J(g)->state != LJ_TRACE_IDLE ? 6 : 0; 67 mode |= G2J(g)->state != LJ_TRACE_IDLE ? 6 : 0;
59#endif 68#endif
60 mode |= (g->hookmask & HOOK_EVENTMASK) ? 2 : 0; 69 mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? 2 : 0;
61 if (oldmode != mode) { /* Mode changed? */ 70 if (oldmode != mode) { /* Mode changed? */
62 ASMFunction *disp = GG2DISP(G2GG(g)); 71 ASMFunction *disp = G2GG(g)->dispatch;
63 ASMFunction f_forl, f_iterl, f_loop; 72 ASMFunction f_forl, f_iterl, f_loop, f_funcf, f_funcv;
64 g->dispatchmode = mode; 73 g->dispatchmode = mode;
65 if ((mode & 5) == 1) { /* Hotcount if JIT is on, but not when recording. */ 74 if ((mode & 5) == 1) { /* Hotcount if JIT is on, but not when recording. */
66 f_forl = makeasmfunc(lj_bc_ofs[BC_FORL]); 75 f_forl = makeasmfunc(lj_bc_ofs[BC_FORL]);
67 f_iterl = makeasmfunc(lj_bc_ofs[BC_ITERL]); 76 f_iterl = makeasmfunc(lj_bc_ofs[BC_ITERL]);
68 f_loop = makeasmfunc(lj_bc_ofs[BC_LOOP]); 77 f_loop = makeasmfunc(lj_bc_ofs[BC_LOOP]);
78 f_funcf = makeasmfunc(lj_bc_ofs[BC_FUNCF]);
79 f_funcv = makeasmfunc(lj_bc_ofs[BC_FUNCV]);
69 } else { /* Otherwise use the non-hotcounting instructions. */ 80 } else { /* Otherwise use the non-hotcounting instructions. */
70 f_forl = disp[GG_DISP_STATIC+BC_IFORL]; 81 f_forl = disp[GG_LEN_DDISP+BC_IFORL];
71 f_iterl = disp[GG_DISP_STATIC+BC_IITERL]; 82 f_iterl = disp[GG_LEN_DDISP+BC_IITERL];
72 f_loop = disp[GG_DISP_STATIC+BC_ILOOP]; 83 f_loop = disp[GG_LEN_DDISP+BC_ILOOP];
84 f_funcf = disp[GG_LEN_DDISP+BC_IFUNCF];
85 f_funcv = disp[GG_LEN_DDISP+BC_IFUNCV];
73 } 86 }
74 /* Set static loop ins first (may be copied below). */ 87 /* Set static counting ins first (may be copied below). */
75 disp[GG_DISP_STATIC+BC_FORL] = f_forl; 88 disp[GG_LEN_DDISP+BC_FORL] = f_forl;
76 disp[GG_DISP_STATIC+BC_ITERL] = f_iterl; 89 disp[GG_LEN_DDISP+BC_ITERL] = f_iterl;
77 disp[GG_DISP_STATIC+BC_LOOP] = f_loop; 90 disp[GG_LEN_DDISP+BC_LOOP] = f_loop;
91 disp[GG_LEN_DDISP+BC_FUNCF] = f_funcf;
92 disp[GG_LEN_DDISP+BC_FUNCV] = f_funcv;
78 if ((oldmode & 6) != (mode & 6)) { /* Need to change whole table? */ 93 if ((oldmode & 6) != (mode & 6)) { /* Need to change whole table? */
79 if ((mode & 6) == 0) { /* No hooks and no recording? */ 94 if ((mode & 6) == 0) { /* No hooks and no recording? */
80 /* Copy static dispatch table to dynamic dispatch table. */ 95 /* Copy static dispatch table to dynamic dispatch table. */
81 memcpy(&disp[0], &disp[GG_DISP_STATIC], sizeof(ASMFunction)*BC__MAX); 96 memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction));
82 } else { 97 } else {
83 /* The recording dispatch also checks for hooks. */ 98 /* The recording dispatch also checks for hooks. */
84 ASMFunction f = (mode & 6) == 6 ? lj_vm_record : lj_vm_hook; 99 ASMFunction f = (mode & 6) == 6 ? lj_vm_record : lj_vm_hook;
85 uint32_t i; 100 uint32_t i;
86 for (i = 0; i < BC__MAX; i++) 101 for (i = 0; i < BC_FUNCF; i++)
87 disp[i] = f; 102 disp[i] = f;
103 /* NYI: call hooks for function headers. */
104 memcpy(&disp[BC_FUNCF], &disp[GG_LEN_DDISP+BC_FUNCF],
105 (GG_LEN_SDISP-BC_FUNCF)*sizeof(ASMFunction));
88 } 106 }
89 } else if ((mode & 6) == 0) { /* Fix dynamic loop ins unless overriden. */ 107 } else if ((mode & 6) == 0) { /* Set dynamic counting ins. */
90 disp[BC_FORL] = f_forl; 108 disp[BC_FORL] = f_forl;
91 disp[BC_ITERL] = f_iterl; 109 disp[BC_ITERL] = f_iterl;
92 disp[BC_LOOP] = f_loop; 110 disp[BC_LOOP] = f_loop;
111 disp[BC_FUNCF] = f_funcf;
112 disp[BC_FUNCV] = f_funcv;
93 } 113 }
94#if LJ_HASJIT 114#if LJ_HASJIT
95 if ((mode & 1) && !(oldmode & 1)) /* JIT off to on transition. */ 115 if ((mode & 1) && !(oldmode & 1)) /* JIT off to on transition. */
@@ -186,14 +206,16 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
186 if ((mode & LUAJIT_MODE_ON)) { 206 if ((mode & LUAJIT_MODE_ON)) {
187 if (idx != 0) { 207 if (idx != 0) {
188 cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx; 208 cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx;
189 if (tvislightud(tv) && lightudV(tv) != NULL) 209 if (tvislightud(tv))
190 g->wrapf = (lua_CFunction)lightudV(tv); 210 g->wrapf = (lua_CFunction)lightudV(tv);
191 else 211 else
192 return 0; /* Failed. */ 212 return 0; /* Failed. */
213 } else {
214 return 0; /* Failed. */
193 } 215 }
194 g->wrapmode = 1; 216 g->bc_cfunc_ext = BCINS_AD(BC_FUNCCW, 0, 0);
195 } else { 217 } else {
196 g->wrapmode = 0; 218 g->bc_cfunc_ext = BCINS_AD(BC_FUNCC, 0, 0);
197 } 219 }
198 break; 220 break;
199 default: 221 default: