aboutsummaryrefslogtreecommitdiff
path: root/src/lj_dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_dispatch.c')
-rw-r--r--src/lj_dispatch.c55
1 files changed, 47 insertions, 8 deletions
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index d76dda41..01bc4239 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -27,6 +27,9 @@
27#endif 27#endif
28#include "lj_trace.h" 28#include "lj_trace.h"
29#include "lj_dispatch.h" 29#include "lj_dispatch.h"
30#if LJ_HASPROFILE
31#include "lj_profile.h"
32#endif
30#include "lj_vm.h" 33#include "lj_vm.h"
31#include "luajit.h" 34#include "luajit.h"
32 35
@@ -84,11 +87,12 @@ void lj_dispatch_init_hotcount(global_State *g)
84#endif 87#endif
85 88
86/* Internal dispatch mode bits. */ 89/* Internal dispatch mode bits. */
87#define DISPMODE_JIT 0x01 /* JIT compiler on. */ 90#define DISPMODE_CALL 0x01 /* Override call dispatch. */
88#define DISPMODE_REC 0x02 /* Recording active. */ 91#define DISPMODE_RET 0x02 /* Override return dispatch. */
89#define DISPMODE_INS 0x04 /* Override instruction dispatch. */ 92#define DISPMODE_INS 0x04 /* Override instruction dispatch. */
90#define DISPMODE_CALL 0x08 /* Override call dispatch. */ 93#define DISPMODE_JIT 0x10 /* JIT compiler on. */
91#define DISPMODE_RET 0x10 /* Override return dispatch. */ 94#define DISPMODE_REC 0x20 /* Recording active. */
95#define DISPMODE_PROF 0x40 /* Profiling active. */
92 96
93/* Update dispatch table depending on various flags. */ 97/* Update dispatch table depending on various flags. */
94void lj_dispatch_update(global_State *g) 98void lj_dispatch_update(global_State *g)
@@ -100,6 +104,9 @@ void lj_dispatch_update(global_State *g)
100 mode |= G2J(g)->state != LJ_TRACE_IDLE ? 104 mode |= G2J(g)->state != LJ_TRACE_IDLE ?
101 (DISPMODE_REC|DISPMODE_INS|DISPMODE_CALL) : 0; 105 (DISPMODE_REC|DISPMODE_INS|DISPMODE_CALL) : 0;
102#endif 106#endif
107#if LJ_HASPROFILE
108 mode |= (g->hookmask & HOOK_PROFILE) ? (DISPMODE_PROF|DISPMODE_INS) : 0;
109#endif
103 mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? DISPMODE_INS : 0; 110 mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? DISPMODE_INS : 0;
104 mode |= (g->hookmask & LUA_MASKCALL) ? DISPMODE_CALL : 0; 111 mode |= (g->hookmask & LUA_MASKCALL) ? DISPMODE_CALL : 0;
105 mode |= (g->hookmask & LUA_MASKRET) ? DISPMODE_RET : 0; 112 mode |= (g->hookmask & LUA_MASKRET) ? DISPMODE_RET : 0;
@@ -128,9 +135,9 @@ void lj_dispatch_update(global_State *g)
128 disp[GG_LEN_DDISP+BC_LOOP] = f_loop; 135 disp[GG_LEN_DDISP+BC_LOOP] = f_loop;
129 136
130 /* Set dynamic instruction dispatch. */ 137 /* Set dynamic instruction dispatch. */
131 if ((oldmode ^ mode) & (DISPMODE_REC|DISPMODE_INS)) { 138 if ((oldmode ^ mode) & (DISPMODE_PROF|DISPMODE_REC|DISPMODE_INS)) {
132 /* Need to update the whole table. */ 139 /* Need to update the whole table. */
133 if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { /* No ins dispatch? */ 140 if (!(mode & DISPMODE_INS)) { /* No ins dispatch? */
134 /* Copy static dispatch table to dynamic dispatch table. */ 141 /* Copy static dispatch table to dynamic dispatch table. */
135 memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction)); 142 memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction));
136 /* Overwrite with dynamic return dispatch. */ 143 /* Overwrite with dynamic return dispatch. */
@@ -142,12 +149,13 @@ void lj_dispatch_update(global_State *g)
142 } 149 }
143 } else { 150 } else {
144 /* The recording dispatch also checks for hooks. */ 151 /* The recording dispatch also checks for hooks. */
145 ASMFunction f = (mode & DISPMODE_REC) ? lj_vm_record : lj_vm_inshook; 152 ASMFunction f = (mode & DISPMODE_PROF) ? lj_vm_profhook :
153 (mode & DISPMODE_REC) ? lj_vm_record : lj_vm_inshook;
146 uint32_t i; 154 uint32_t i;
147 for (i = 0; i < GG_LEN_SDISP; i++) 155 for (i = 0; i < GG_LEN_SDISP; i++)
148 disp[i] = f; 156 disp[i] = f;
149 } 157 }
150 } else if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { 158 } else if (!(mode & DISPMODE_INS)) {
151 /* Otherwise set dynamic counting ins. */ 159 /* Otherwise set dynamic counting ins. */
152 disp[BC_FORL] = f_forl; 160 disp[BC_FORL] = f_forl;
153 disp[BC_ITERL] = f_iterl; 161 disp[BC_ITERL] = f_iterl;
@@ -495,3 +503,34 @@ out:
495 return makeasmfunc(lj_bc_ofs[op]); /* Return static dispatch target. */ 503 return makeasmfunc(lj_bc_ofs[op]); /* Return static dispatch target. */
496} 504}
497 505
506#if LJ_HASPROFILE
507/* Profile dispatch. */
508void LJ_FASTCALL lj_dispatch_profile(lua_State *L, const BCIns *pc)
509{
510 ERRNO_SAVE
511 global_State *g = G(L);
512 uint8_t mask = g->hookmask;
513 g->hookmask = (mask & ~HOOK_PROFILE);
514 lj_dispatch_update(g);
515 if (!(mask & HOOK_VMEVENT)) {
516 GCfunc *fn = curr_func(L);
517 GCproto *pt = funcproto(fn);
518 void *cf = cframe_raw(L->cframe);
519 const BCIns *oldpc = cframe_pc(cf);
520 uint8_t oldh = hook_save(g);
521 BCReg slots;
522 hook_vmevent(g);
523 setcframe_pc(cf, pc);
524 slots = cur_topslot(pt, pc, cframe_multres_n(cf));
525 L->top = L->base + slots; /* Fix top. */
526 lj_profile_interpreter(L);
527 setgcref(g->cur_L, obj2gco(L));
528 setcframe_pc(cf, oldpc);
529 hook_restore(g, oldh);
530 lj_trace_abort(g);
531 setvmstate(g, INTERP);
532 }
533 ERRNO_RESTORE
534}
535#endif
536