diff options
Diffstat (limited to 'src/lj_dispatch.c')
-rw-r--r-- | src/lj_dispatch.c | 62 |
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. */ |
24 | LJ_STATIC_ASSERT(GG_NUM_ASMFF == FF_NUM_ASMFUNC); | ||
23 | 25 | ||
24 | /* -- Dispatch table management ------------------------------------------- */ | 26 | /* -- Dispatch table management ------------------------------------------- */ |
25 | 27 | ||
@@ -27,13 +29,20 @@ | |||
27 | void lj_dispatch_init(GG_State *GG) | 29 | void 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: |