lj_dispatch.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*
  2. ** Instruction dispatch handling.
  3. ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
  4. */
  5. #define lj_dispatch_c
  6. #define LUA_CORE
  7. #include "lj_obj.h"
  8. #include "lj_err.h"
  9. #include "lj_func.h"
  10. #include "lj_str.h"
  11. #include "lj_tab.h"
  12. #include "lj_meta.h"
  13. #include "lj_debug.h"
  14. #include "lj_state.h"
  15. #include "lj_frame.h"
  16. #include "lj_bc.h"
  17. #include "lj_ff.h"
  18. #if LJ_HASJIT
  19. #include "lj_jit.h"
  20. #endif
  21. #if LJ_HASFFI
  22. #include "lj_ccallback.h"
  23. #endif
  24. #include "lj_trace.h"
  25. #include "lj_dispatch.h"
  26. #include "lj_vm.h"
  27. #include "luajit.h"
  28. /* Bump GG_NUM_ASMFF in lj_dispatch.h as needed. Ugly. */
  29. LJ_STATIC_ASSERT(GG_NUM_ASMFF == FF_NUM_ASMFUNC);
  30. /* -- Dispatch table management ------------------------------------------- */
  31. #if LJ_TARGET_MIPS
  32. #include <math.h>
  33. LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L,
  34. lua_State *co);
  35. #define GOTFUNC(name) (ASMFunction)name,
  36. static const ASMFunction dispatch_got[] = {
  37. GOTDEF(GOTFUNC)
  38. };
  39. #undef GOTFUNC
  40. #endif
  41. /* Initialize instruction dispatch table and hot counters. */
  42. void lj_dispatch_init(GG_State *GG)
  43. {
  44. uint32_t i;
  45. ASMFunction *disp = GG->dispatch;
  46. for (i = 0; i < GG_LEN_SDISP; i++)
  47. disp[GG_LEN_DDISP+i] = disp[i] = makeasmfunc(lj_bc_ofs[i]);
  48. for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
  49. disp[i] = makeasmfunc(lj_bc_ofs[i]);
  50. /* The JIT engine is off by default. luaopen_jit() turns it on. */
  51. disp[BC_FORL] = disp[BC_IFORL];
  52. disp[BC_ITERL] = disp[BC_IITERL];
  53. disp[BC_LOOP] = disp[BC_ILOOP];
  54. disp[BC_FUNCF] = disp[BC_IFUNCF];
  55. disp[BC_FUNCV] = disp[BC_IFUNCV];
  56. GG->g.bc_cfunc_ext = GG->g.bc_cfunc_int = BCINS_AD(BC_FUNCC, LUA_MINSTACK, 0);
  57. for (i = 0; i < GG_NUM_ASMFF; i++)
  58. GG->bcff[i] = BCINS_AD(BC__MAX+i, 0, 0);
  59. #if LJ_TARGET_MIPS
  60. memcpy(GG->got, dispatch_got, LJ_GOT__MAX*4);
  61. #endif
  62. }
  63. #if LJ_HASJIT
  64. /* Initialize hotcount table. */
  65. void lj_dispatch_init_hotcount(global_State *g)
  66. {
  67. int32_t hotloop = G2J(g)->param[JIT_P_hotloop];
  68. HotCount start = (HotCount)(hotloop*HOTCOUNT_LOOP - 1);
  69. HotCount *hotcount = G2GG(g)->hotcount;
  70. uint32_t i;
  71. for (i = 0; i < HOTCOUNT_SIZE; i++)
  72. hotcount[i] = start;
  73. }
  74. #endif
  75. /* Internal dispatch mode bits. */
  76. #define DISPMODE_JIT 0x01 /* JIT compiler on. */
  77. #define DISPMODE_REC 0x02 /* Recording active. */
  78. #define DISPMODE_INS 0x04 /* Override instruction dispatch. */
  79. #define DISPMODE_CALL 0x08 /* Override call dispatch. */
  80. #define DISPMODE_RET 0x10 /* Override return dispatch. */
  81. /* Update dispatch table depending on various flags. */
  82. void lj_dispatch_update(global_State *g)
  83. {
  84. uint8_t oldmode = g->dispatchmode;
  85. uint8_t mode = 0;
  86. #if LJ_HASJIT
  87. mode |= (G2J(g)->flags & JIT_F_ON) ? DISPMODE_JIT : 0;
  88. mode |= G2J(g)->state != LJ_TRACE_IDLE ?
  89. (DISPMODE_REC|DISPMODE_INS|DISPMODE_CALL) : 0;
  90. #endif
  91. mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? DISPMODE_INS : 0;
  92. mode |= (g->hookmask & LUA_MASKCALL) ? DISPMODE_CALL : 0;
  93. mode |= (g->hookmask & LUA_MASKRET) ? DISPMODE_RET : 0;
  94. if (oldmode != mode) { /* Mode changed? */
  95. ASMFunction *disp = G2GG(g)->dispatch;
  96. ASMFunction f_forl, f_iterl, f_loop, f_funcf, f_funcv;
  97. g->dispatchmode = mode;
  98. /* Hotcount if JIT is on, but not while recording. */
  99. if ((mode & (DISPMODE_JIT|DISPMODE_REC)) == DISPMODE_JIT) {
  100. f_forl = makeasmfunc(lj_bc_ofs[BC_FORL]);
  101. f_iterl = makeasmfunc(lj_bc_ofs[BC_ITERL]);
  102. f_loop = makeasmfunc(lj_bc_ofs[BC_LOOP]);
  103. f_funcf = makeasmfunc(lj_bc_ofs[BC_FUNCF]);
  104. f_funcv = makeasmfunc(lj_bc_ofs[BC_FUNCV]);
  105. } else { /* Otherwise use the non-hotcounting instructions. */
  106. f_forl = disp[GG_LEN_DDISP+BC_IFORL];
  107. f_iterl = disp[GG_LEN_DDISP+BC_IITERL];
  108. f_loop = disp[GG_LEN_DDISP+BC_ILOOP];
  109. f_funcf = makeasmfunc(lj_bc_ofs[BC_IFUNCF]);
  110. f_funcv = makeasmfunc(lj_bc_ofs[BC_IFUNCV]);
  111. }
  112. /* Init static counting instruction dispatch first (may be copied below). */
  113. disp[GG_LEN_DDISP+BC_FORL] = f_forl;
  114. disp[GG_LEN_DDISP+BC_ITERL] = f_iterl;
  115. disp[GG_LEN_DDISP+BC_LOOP] = f_loop;
  116. /* Set dynamic instruction dispatch. */
  117. if ((oldmode ^ mode) & (DISPMODE_REC|DISPMODE_INS)) {
  118. /* Need to update the whole table. */
  119. if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { /* No ins dispatch? */
  120. /* Copy static dispatch table to dynamic dispatch table. */
  121. memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction));
  122. /* Overwrite with dynamic return dispatch. */
  123. if ((mode & DISPMODE_RET)) {
  124. disp[BC_RETM] = lj_vm_rethook;
  125. disp[BC_RET] = lj_vm_rethook;
  126. disp[BC_RET0] = lj_vm_rethook;
  127. disp[BC_RET1] = lj_vm_rethook;
  128. }
  129. } else {
  130. /* The recording dispatch also checks for hooks. */
  131. ASMFunction f = (mode & DISPMODE_REC) ? lj_vm_record : lj_vm_inshook;
  132. uint32_t i;
  133. for (i = 0; i < GG_LEN_SDISP; i++)
  134. disp[i] = f;
  135. }
  136. } else if (!(mode & (DISPMODE_REC|DISPMODE_INS))) {
  137. /* Otherwise set dynamic counting ins. */
  138. disp[BC_FORL] = f_forl;
  139. disp[BC_ITERL] = f_iterl;
  140. disp[BC_LOOP] = f_loop;
  141. /* Set dynamic return dispatch. */
  142. if ((mode & DISPMODE_RET)) {
  143. disp[BC_RETM] = lj_vm_rethook;
  144. disp[BC_RET] = lj_vm_rethook;
  145. disp[BC_RET0] = lj_vm_rethook;
  146. disp[BC_RET1] = lj_vm_rethook;
  147. } else {
  148. disp[BC_RETM] = disp[GG_LEN_DDISP+BC_RETM];
  149. disp[BC_RET] = disp[GG_LEN_DDISP+BC_RET];
  150. disp[BC_RET0] = disp[GG_LEN_DDISP+BC_RET0];
  151. disp[BC_RET1] = disp[GG_LEN_DDISP+BC_RET1];
  152. }
  153. }
  154. /* Set dynamic call dispatch. */
  155. if ((oldmode ^ mode) & DISPMODE_CALL) { /* Update the whole table? */
  156. uint32_t i;
  157. if ((mode & DISPMODE_CALL) == 0) { /* No call hooks? */
  158. for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
  159. disp[i] = makeasmfunc(lj_bc_ofs[i]);
  160. } else {
  161. for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
  162. disp[i] = lj_vm_callhook;
  163. }
  164. }
  165. if (!(mode & DISPMODE_CALL)) { /* Overwrite dynamic counting ins. */
  166. disp[BC_FUNCF] = f_funcf;
  167. disp[BC_FUNCV] = f_funcv;
  168. }
  169. #if LJ_HASJIT
  170. /* Reset hotcounts for JIT off to on transition. */
  171. if ((mode & DISPMODE_JIT) && !(oldmode & DISPMODE_JIT))
  172. lj_dispatch_init_hotcount(g);
  173. #endif
  174. }
  175. }
  176. /* -- JIT mode setting ---------------------------------------------------- */
  177. #if LJ_HASJIT
  178. /* Set JIT mode for a single prototype. */
  179. static void setptmode(global_State *g, GCproto *pt, int mode)
  180. {
  181. if ((mode & LUAJIT_MODE_ON)) { /* (Re-)enable JIT compilation. */
  182. pt->flags &= ~PROTO_NOJIT;
  183. lj_trace_reenableproto(pt); /* Unpatch all ILOOP etc. bytecodes. */
  184. } else { /* Flush and/or disable JIT compilation. */
  185. if (!(mode & LUAJIT_MODE_FLUSH))
  186. pt->flags |= PROTO_NOJIT;
  187. lj_trace_flushproto(g, pt); /* Flush all traces of prototype. */
  188. }
  189. }
  190. /* Recursively set the JIT mode for all children of a prototype. */
  191. static void setptmode_all(global_State *g, GCproto *pt, int mode)
  192. {
  193. ptrdiff_t i;
  194. if (!(pt->flags & PROTO_CHILD)) return;
  195. for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) {
  196. GCobj *o = proto_kgc(pt, i);
  197. if (o->gch.gct == ~LJ_TPROTO) {
  198. setptmode(g, gco2pt(o), mode);
  199. setptmode_all(g, gco2pt(o), mode);
  200. }
  201. }
  202. }
  203. #endif
  204. /* Public API function: control the JIT engine. */
  205. int luaJIT_setmode(lua_State *L, int idx, int mode)
  206. {
  207. global_State *g = G(L);
  208. int mm = mode & LUAJIT_MODE_MASK;
  209. lj_trace_abort(g); /* Abort recording on any state change. */
  210. /* Avoid pulling the rug from under our own feet. */
  211. if ((g->hookmask & HOOK_GC))
  212. lj_err_caller(L, LJ_ERR_NOGCMM);
  213. switch (mm) {
  214. #if LJ_HASJIT
  215. case LUAJIT_MODE_ENGINE:
  216. if ((mode & LUAJIT_MODE_FLUSH)) {
  217. lj_trace_flushall(L);
  218. } else {
  219. if (!(mode & LUAJIT_MODE_ON))
  220. G2J(g)->flags &= ~(uint32_t)JIT_F_ON;
  221. #if LJ_TARGET_X86ORX64
  222. else if ((G2J(g)->flags & JIT_F_SSE2))
  223. G2J(g)->flags |= (uint32_t)JIT_F_ON;
  224. else
  225. return 0; /* Don't turn on JIT compiler without SSE2 support. */
  226. #else
  227. else
  228. G2J(g)->flags |= (uint32_t)JIT_F_ON;
  229. #endif
  230. lj_dispatch_update(g);
  231. }
  232. break;
  233. case LUAJIT_MODE_FUNC:
  234. case LUAJIT_MODE_ALLFUNC:
  235. case LUAJIT_MODE_ALLSUBFUNC: {
  236. cTValue *tv = idx == 0 ? frame_prev(L->base-1) :
  237. idx > 0 ? L->base + (idx-1) : L->top + idx;
  238. GCproto *pt;
  239. if ((idx == 0 || tvisfunc(tv)) && isluafunc(&gcval(tv)->fn))
  240. pt = funcproto(&gcval(tv)->fn); /* Cannot use funcV() for frame slot. */
  241. else if (tvisproto(tv))
  242. pt = protoV(tv);
  243. else
  244. return 0; /* Failed. */
  245. if (mm != LUAJIT_MODE_ALLSUBFUNC)
  246. setptmode(g, pt, mode);
  247. if (mm != LUAJIT_MODE_FUNC)
  248. setptmode_all(g, pt, mode);
  249. break;
  250. }
  251. case LUAJIT_MODE_TRACE:
  252. if (!(mode & LUAJIT_MODE_FLUSH))
  253. return 0; /* Failed. */
  254. lj_trace_flush(G2J(g), idx);
  255. break;
  256. #else
  257. case LUAJIT_MODE_ENGINE:
  258. case LUAJIT_MODE_FUNC:
  259. case LUAJIT_MODE_ALLFUNC:
  260. case LUAJIT_MODE_ALLSUBFUNC:
  261. UNUSED(idx);
  262. if ((mode & LUAJIT_MODE_ON))
  263. return 0; /* Failed. */
  264. break;
  265. #endif
  266. case LUAJIT_MODE_WRAPCFUNC:
  267. if ((mode & LUAJIT_MODE_ON)) {
  268. if (idx != 0) {
  269. cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx;
  270. if (tvislightud(tv))
  271. g->wrapf = (lua_CFunction)lightudV(tv);
  272. else
  273. return 0; /* Failed. */
  274. } else {
  275. return 0; /* Failed. */
  276. }
  277. g->bc_cfunc_ext = BCINS_AD(BC_FUNCCW, 0, 0);
  278. } else {
  279. g->bc_cfunc_ext = BCINS_AD(BC_FUNCC, 0, 0);
  280. }
  281. break;
  282. default:
  283. return 0; /* Failed. */
  284. }
  285. return 1; /* OK. */
  286. }
  287. /* Enforce (dynamic) linker error for version mismatches. See luajit.c. */
  288. LUA_API void LUAJIT_VERSION_SYM(void)
  289. {
  290. }
  291. /* -- Hooks --------------------------------------------------------------- */
  292. /* This function can be called asynchronously (e.g. during a signal). */
  293. LUA_API int lua_sethook(lua_State *L, lua_Hook func, int mask, int count)
  294. {
  295. global_State *g = G(L);
  296. mask &= HOOK_EVENTMASK;
  297. if (func == NULL || mask == 0) { mask = 0; func = NULL; } /* Consistency. */
  298. g->hookf = func;
  299. g->hookcount = g->hookcstart = (int32_t)count;
  300. g->hookmask = (uint8_t)((g->hookmask & ~HOOK_EVENTMASK) | mask);
  301. lj_trace_abort(g); /* Abort recording on any hook change. */
  302. lj_dispatch_update(g);
  303. return 1;
  304. }
  305. LUA_API lua_Hook lua_gethook(lua_State *L)
  306. {
  307. return G(L)->hookf;
  308. }
  309. LUA_API int lua_gethookmask(lua_State *L)
  310. {
  311. return G(L)->hookmask & HOOK_EVENTMASK;
  312. }
  313. LUA_API int lua_gethookcount(lua_State *L)
  314. {
  315. return (int)G(L)->hookcstart;
  316. }
  317. /* Call a hook. */
  318. static void callhook(lua_State *L, int event, BCLine line)
  319. {
  320. global_State *g = G(L);
  321. lua_Hook hookf = g->hookf;
  322. if (hookf && !hook_active(g)) {
  323. lua_Debug ar;
  324. lj_trace_abort(g); /* Abort recording on any hook call. */
  325. ar.event = event;
  326. ar.currentline = line;
  327. /* Top frame, nextframe = NULL. */
  328. ar.i_ci = (int)((L->base-1) - tvref(L->stack));
  329. lj_state_checkstack(L, 1+LUA_MINSTACK);
  330. hook_enter(g);
  331. hookf(L, &ar);
  332. lua_assert(hook_active(g));
  333. hook_leave(g);
  334. }
  335. }
  336. /* -- Dispatch callbacks -------------------------------------------------- */
  337. /* Calculate number of used stack slots in the current frame. */
  338. static BCReg cur_topslot(GCproto *pt, const BCIns *pc, uint32_t nres)
  339. {
  340. BCIns ins = pc[-1];
  341. if (bc_op(ins) == BC_UCLO)
  342. ins = pc[bc_j(ins)];
  343. switch (bc_op(ins)) {
  344. case BC_CALLM: case BC_CALLMT: return bc_a(ins) + bc_c(ins) + nres-1+1;
  345. case BC_RETM: return bc_a(ins) + bc_d(ins) + nres-1;
  346. case BC_TSETM: return bc_a(ins) + nres-1;
  347. default: return pt->framesize;
  348. }
  349. }
  350. /* Instruction dispatch. Used by instr/line/return hooks or when recording. */
  351. void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
  352. {
  353. ERRNO_SAVE
  354. GCfunc *fn = curr_func(L);
  355. GCproto *pt = funcproto(fn);
  356. void *cf = cframe_raw(L->cframe);
  357. const BCIns *oldpc = cframe_pc(cf);
  358. global_State *g = G(L);
  359. BCReg slots;
  360. setcframe_pc(cf, pc);
  361. slots = cur_topslot(pt, pc, cframe_multres_n(cf));
  362. L->top = L->base + slots; /* Fix top. */
  363. #if LJ_HASJIT
  364. {
  365. jit_State *J = G2J(g);
  366. if (J->state != LJ_TRACE_IDLE) {
  367. #ifdef LUA_USE_ASSERT
  368. ptrdiff_t delta = L->top - L->base;
  369. #endif
  370. J->L = L;
  371. lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
  372. lua_assert(L->top - L->base == delta);
  373. }
  374. }
  375. #endif
  376. if ((g->hookmask & LUA_MASKCOUNT) && g->hookcount == 0) {
  377. g->hookcount = g->hookcstart;
  378. callhook(L, LUA_HOOKCOUNT, -1);
  379. L->top = L->base + slots; /* Fix top again. */
  380. }
  381. if ((g->hookmask & LUA_MASKLINE)) {
  382. BCPos npc = proto_bcpos(pt, pc) - 1;
  383. BCPos opc = proto_bcpos(pt, oldpc) - 1;
  384. BCLine line = lj_debug_line(pt, npc);
  385. if (pc <= oldpc || opc >= pt->sizebc || line != lj_debug_line(pt, opc)) {
  386. callhook(L, LUA_HOOKLINE, line);
  387. L->top = L->base + slots; /* Fix top again. */
  388. }
  389. }
  390. if ((g->hookmask & LUA_MASKRET) && bc_isret(bc_op(pc[-1])))
  391. callhook(L, LUA_HOOKRET, -1);
  392. ERRNO_RESTORE
  393. }
  394. /* Initialize call. Ensure stack space and return # of missing parameters. */
  395. static int call_init(lua_State *L, GCfunc *fn)
  396. {
  397. if (isluafunc(fn)) {
  398. GCproto *pt = funcproto(fn);
  399. int numparams = pt->numparams;
  400. int gotparams = (int)(L->top - L->base);
  401. int need = pt->framesize;
  402. if ((pt->flags & PROTO_VARARG)) need += 1+gotparams;
  403. lj_state_checkstack(L, (MSize)need);
  404. numparams -= gotparams;
  405. return numparams >= 0 ? numparams : 0;
  406. } else {
  407. lj_state_checkstack(L, LUA_MINSTACK);
  408. return 0;
  409. }
  410. }
  411. /* Call dispatch. Used by call hooks, hot calls or when recording. */
  412. ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
  413. {
  414. ERRNO_SAVE
  415. GCfunc *fn = curr_func(L);
  416. BCOp op;
  417. global_State *g = G(L);
  418. #if LJ_HASJIT
  419. jit_State *J = G2J(g);
  420. #endif
  421. int missing = call_init(L, fn);
  422. #if LJ_HASJIT
  423. J->L = L;
  424. if ((uintptr_t)pc & 1) { /* Marker for hot call. */
  425. #ifdef LUA_USE_ASSERT
  426. ptrdiff_t delta = L->top - L->base;
  427. #endif
  428. pc = (const BCIns *)((uintptr_t)pc & ~(uintptr_t)1);
  429. lj_trace_hot(J, pc);
  430. lua_assert(L->top - L->base == delta);
  431. goto out;
  432. } else if (J->state != LJ_TRACE_IDLE &&
  433. !(g->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
  434. #ifdef LUA_USE_ASSERT
  435. ptrdiff_t delta = L->top - L->base;
  436. #endif
  437. /* Record the FUNC* bytecodes, too. */
  438. lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
  439. lua_assert(L->top - L->base == delta);
  440. }
  441. #endif
  442. if ((g->hookmask & LUA_MASKCALL)) {
  443. int i;
  444. for (i = 0; i < missing; i++) /* Add missing parameters. */
  445. setnilV(L->top++);
  446. callhook(L, LUA_HOOKCALL, -1);
  447. /* Preserve modifications of missing parameters by lua_setlocal(). */
  448. while (missing-- > 0 && tvisnil(L->top - 1))
  449. L->top--;
  450. }
  451. #if LJ_HASJIT
  452. out:
  453. #endif
  454. op = bc_op(pc[-1]); /* Get FUNC* op. */
  455. #if LJ_HASJIT
  456. /* Use the non-hotcounting variants if JIT is off or while recording. */
  457. if ((!(J->flags & JIT_F_ON) || J->state != LJ_TRACE_IDLE) &&
  458. (op == BC_FUNCF || op == BC_FUNCV))
  459. op = (BCOp)((int)op+(int)BC_IFUNCF-(int)BC_FUNCF);
  460. #endif
  461. ERRNO_RESTORE
  462. return makeasmfunc(lj_bc_ofs[op]); /* Return static dispatch target. */
  463. }