diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_dispatch.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index 42ffd2b8..b83912c5 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c | |||
@@ -62,6 +62,7 @@ void lj_dispatch_init_hotcount(global_State *g) | |||
62 | #define DISPMODE_REC 0x02 /* Recording active. */ | 62 | #define DISPMODE_REC 0x02 /* Recording active. */ |
63 | #define DISPMODE_INS 0x04 /* Override instruction dispatch. */ | 63 | #define DISPMODE_INS 0x04 /* Override instruction dispatch. */ |
64 | #define DISPMODE_CALL 0x08 /* Override call dispatch. */ | 64 | #define DISPMODE_CALL 0x08 /* Override call dispatch. */ |
65 | #define DISPMODE_RET 0x08 /* Override return dispatch. */ | ||
65 | 66 | ||
66 | /* Update dispatch table depending on various flags. */ | 67 | /* Update dispatch table depending on various flags. */ |
67 | void lj_dispatch_update(global_State *g) | 68 | void lj_dispatch_update(global_State *g) |
@@ -74,6 +75,7 @@ void lj_dispatch_update(global_State *g) | |||
74 | #endif | 75 | #endif |
75 | mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? DISPMODE_INS : 0; | 76 | mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? DISPMODE_INS : 0; |
76 | mode |= (g->hookmask & LUA_MASKCALL) ? DISPMODE_CALL : 0; | 77 | mode |= (g->hookmask & LUA_MASKCALL) ? DISPMODE_CALL : 0; |
78 | mode |= (g->hookmask & LUA_MASKRET) ? DISPMODE_RET : 0; | ||
77 | if (oldmode != mode) { /* Mode changed? */ | 79 | if (oldmode != mode) { /* Mode changed? */ |
78 | ASMFunction *disp = G2GG(g)->dispatch; | 80 | ASMFunction *disp = G2GG(g)->dispatch; |
79 | ASMFunction f_forl, f_iterl, f_loop, f_funcf, f_funcv; | 81 | ASMFunction f_forl, f_iterl, f_loop, f_funcf, f_funcv; |
@@ -104,18 +106,37 @@ void lj_dispatch_update(global_State *g) | |||
104 | if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { /* No ins dispatch? */ | 106 | if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { /* No ins dispatch? */ |
105 | /* Copy static dispatch table to dynamic dispatch table. */ | 107 | /* Copy static dispatch table to dynamic dispatch table. */ |
106 | memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction)); | 108 | memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction)); |
109 | /* Overwrite with dynamic return dispatch. */ | ||
110 | if ((mode & DISPMODE_RET)) { | ||
111 | disp[BC_RETM] = lj_vm_rethook; | ||
112 | disp[BC_RET] = lj_vm_rethook; | ||
113 | disp[BC_RET0] = lj_vm_rethook; | ||
114 | disp[BC_RET1] = lj_vm_rethook; | ||
115 | } | ||
107 | } else { | 116 | } else { |
108 | /* The recording dispatch also checks for hooks. */ | 117 | /* The recording dispatch also checks for hooks. */ |
109 | ASMFunction f = (mode & DISPMODE_REC) ? lj_vm_record : lj_vm_hook; | 118 | ASMFunction f = (mode & DISPMODE_REC) ? lj_vm_record : lj_vm_inshook; |
110 | uint32_t i; | 119 | uint32_t i; |
111 | for (i = 0; i < GG_LEN_SDISP; i++) | 120 | for (i = 0; i < GG_LEN_SDISP; i++) |
112 | disp[i] = f; | 121 | disp[i] = f; |
113 | } | 122 | } |
114 | } else if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { | 123 | } else if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { |
115 | /* Otherwise only set dynamic counting ins. */ | 124 | /* Otherwise set dynamic counting ins. */ |
116 | disp[BC_FORL] = f_forl; | 125 | disp[BC_FORL] = f_forl; |
117 | disp[BC_ITERL] = f_iterl; | 126 | disp[BC_ITERL] = f_iterl; |
118 | disp[BC_LOOP] = f_loop; | 127 | disp[BC_LOOP] = f_loop; |
128 | /* Set dynamic return dispatch. */ | ||
129 | if ((mode & DISPMODE_RET)) { | ||
130 | disp[BC_RETM] = lj_vm_rethook; | ||
131 | disp[BC_RET] = lj_vm_rethook; | ||
132 | disp[BC_RET0] = lj_vm_rethook; | ||
133 | disp[BC_RET1] = lj_vm_rethook; | ||
134 | } else { | ||
135 | disp[BC_RETM] = disp[GG_LEN_DDISP+BC_RETM]; | ||
136 | disp[BC_RET] = disp[GG_LEN_DDISP+BC_RET]; | ||
137 | disp[BC_RET0] = disp[GG_LEN_DDISP+BC_RET0]; | ||
138 | disp[BC_RET1] = disp[GG_LEN_DDISP+BC_RET1]; | ||
139 | } | ||
119 | } | 140 | } |
120 | 141 | ||
121 | /* Set dynamic call dispatch. */ | 142 | /* Set dynamic call dispatch. */ |
@@ -321,7 +342,7 @@ static BCReg cur_topslot(GCproto *pt, const BCIns *pc, uint32_t nres) | |||
321 | } | 342 | } |
322 | } | 343 | } |
323 | 344 | ||
324 | /* Instruction dispatch. Used by instr/line hooks or when recording. */ | 345 | /* Instruction dispatch. Used by instr/line/return hooks or when recording. */ |
325 | void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc) | 346 | void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc) |
326 | { | 347 | { |
327 | GCfunc *fn = curr_func(L); | 348 | GCfunc *fn = curr_func(L); |
@@ -348,17 +369,22 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc) | |||
348 | if ((g->hookmask & LUA_MASKCOUNT) && g->hookcount == 0) { | 369 | if ((g->hookmask & LUA_MASKCOUNT) && g->hookcount == 0) { |
349 | g->hookcount = g->hookcstart; | 370 | g->hookcount = g->hookcstart; |
350 | callhook(L, LUA_HOOKCOUNT, -1); | 371 | callhook(L, LUA_HOOKCOUNT, -1); |
372 | L->top = L->base + slots; /* Fix top again. */ | ||
351 | } | 373 | } |
352 | if ((g->hookmask & LUA_MASKLINE)) { | 374 | if ((g->hookmask & LUA_MASKLINE)) { |
353 | BCPos npc = proto_bcpos(pt, pc) - 1; | 375 | BCPos npc = proto_bcpos(pt, pc) - 1; |
354 | BCPos opc = proto_bcpos(pt, oldpc) - 1; | 376 | BCPos opc = proto_bcpos(pt, oldpc) - 1; |
355 | BCLine line = proto_line(pt, npc); | 377 | BCLine line = proto_line(pt, npc); |
356 | if (npc == 0 || pc <= oldpc || | 378 | if (pc <= oldpc || opc >= pt->sizebc || line != proto_line(pt, opc)) { |
357 | opc >= pt->sizebc || line != proto_line(pt, opc)) { | ||
358 | L->top = L->base + slots; /* Fix top again after instruction hook. */ | ||
359 | callhook(L, LUA_HOOKLINE, line); | 379 | callhook(L, LUA_HOOKLINE, line); |
380 | L->top = L->base + slots; /* Fix top again. */ | ||
360 | } | 381 | } |
361 | } | 382 | } |
383 | if ((g->hookmask & LUA_MASKRET)) { | ||
384 | BCOp op = bc_op(pc[-1]); | ||
385 | if (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1) | ||
386 | callhook(L, LUA_HOOKRET, -1); | ||
387 | } | ||
362 | } | 388 | } |
363 | 389 | ||
364 | /* Initialize call. Ensure stack space and clear missing parameters. */ | 390 | /* Initialize call. Ensure stack space and clear missing parameters. */ |