lj_trace.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  1. /*
  2. ** Trace management.
  3. ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
  4. */
  5. #define lj_trace_c
  6. #define LUA_CORE
  7. #include "lj_obj.h"
  8. #if LJ_HASJIT
  9. #include "lj_gc.h"
  10. #include "lj_err.h"
  11. #include "lj_debug.h"
  12. #include "lj_str.h"
  13. #include "lj_frame.h"
  14. #include "lj_state.h"
  15. #include "lj_bc.h"
  16. #include "lj_ir.h"
  17. #include "lj_jit.h"
  18. #include "lj_iropt.h"
  19. #include "lj_mcode.h"
  20. #include "lj_trace.h"
  21. #include "lj_snap.h"
  22. #include "lj_gdbjit.h"
  23. #include "lj_record.h"
  24. #include "lj_asm.h"
  25. #include "lj_dispatch.h"
  26. #include "lj_vm.h"
  27. #include "lj_vmevent.h"
  28. #include "lj_target.h"
  29. #include "lj_prng.h"
  30. /* -- Error handling ------------------------------------------------------ */
  31. /* Synchronous abort with error message. */
  32. void lj_trace_err(jit_State *J, TraceError e)
  33. {
  34. setnilV(&J->errinfo); /* No error info. */
  35. setintV(J->L->top++, (int32_t)e);
  36. lj_err_throw(J->L, LUA_ERRRUN);
  37. }
  38. /* Synchronous abort with error message and error info. */
  39. void lj_trace_err_info(jit_State *J, TraceError e)
  40. {
  41. setintV(J->L->top++, (int32_t)e);
  42. lj_err_throw(J->L, LUA_ERRRUN);
  43. }
  44. /* -- Trace management ---------------------------------------------------- */
  45. /* The current trace is first assembled in J->cur. The variable length
  46. ** arrays point to shared, growable buffers (J->irbuf etc.). When trace
  47. ** recording ends successfully, the current trace and its data structures
  48. ** are copied to a new (compact) GCtrace object.
  49. */
  50. /* Find a free trace number. */
  51. static TraceNo trace_findfree(jit_State *J)
  52. {
  53. MSize osz, lim;
  54. if (J->freetrace == 0)
  55. J->freetrace = 1;
  56. for (; J->freetrace < J->sizetrace; J->freetrace++)
  57. if (traceref(J, J->freetrace) == NULL)
  58. return J->freetrace++;
  59. /* Need to grow trace array. */
  60. lim = (MSize)J->param[JIT_P_maxtrace] + 1;
  61. if (lim < 2) lim = 2; else if (lim > 65535) lim = 65535;
  62. osz = J->sizetrace;
  63. if (osz >= lim)
  64. return 0; /* Too many traces. */
  65. lj_mem_growvec(J->L, J->trace, J->sizetrace, lim, GCRef);
  66. for (; osz < J->sizetrace; osz++)
  67. setgcrefnull(J->trace[osz]);
  68. return J->freetrace;
  69. }
  70. #define TRACE_APPENDVEC(field, szfield, tp) \
  71. T->field = (tp *)p; \
  72. memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \
  73. p += J->cur.szfield*sizeof(tp);
  74. #ifdef LUAJIT_USE_PERFTOOLS
  75. /*
  76. ** Create symbol table of JIT-compiled code. For use with Linux perf tools.
  77. ** Example usage:
  78. ** perf record -f -e cycles luajit test.lua
  79. ** perf report -s symbol
  80. ** rm perf.data /tmp/perf-*.map
  81. */
  82. #include <stdio.h>
  83. #include <unistd.h>
  84. static void perftools_addtrace(GCtrace *T)
  85. {
  86. static FILE *fp;
  87. GCproto *pt = &gcref(T->startpt)->pt;
  88. const BCIns *startpc = mref(T->startpc, const BCIns);
  89. const char *name = proto_chunknamestr(pt);
  90. BCLine lineno;
  91. if (name[0] == '@' || name[0] == '=')
  92. name++;
  93. else
  94. name = "(string)";
  95. lj_assertX(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc,
  96. "trace PC out of range");
  97. lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
  98. if (!fp) {
  99. char fname[40];
  100. sprintf(fname, "/tmp/perf-%d.map", getpid());
  101. if (!(fp = fopen(fname, "w"))) return;
  102. setlinebuf(fp);
  103. }
  104. fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
  105. (long)T->mcode, T->szmcode, T->traceno, name, lineno);
  106. }
  107. #endif
  108. /* Allocate space for copy of T. */
  109. GCtrace * LJ_FASTCALL lj_trace_alloc(lua_State *L, GCtrace *T)
  110. {
  111. size_t sztr = ((sizeof(GCtrace)+7)&~7);
  112. size_t szins = (T->nins-T->nk)*sizeof(IRIns);
  113. size_t sz = sztr + szins +
  114. T->nsnap*sizeof(SnapShot) +
  115. T->nsnapmap*sizeof(SnapEntry);
  116. GCtrace *T2 = lj_mem_newt(L, (MSize)sz, GCtrace);
  117. char *p = (char *)T2 + sztr;
  118. T2->gct = ~LJ_TTRACE;
  119. T2->marked = 0;
  120. T2->traceno = 0;
  121. T2->ir = (IRIns *)p - T->nk;
  122. T2->nins = T->nins;
  123. T2->nk = T->nk;
  124. T2->nsnap = T->nsnap;
  125. T2->nsnapmap = T->nsnapmap;
  126. memcpy(p, T->ir + T->nk, szins);
  127. return T2;
  128. }
  129. /* Save current trace by copying and compacting it. */
  130. static void trace_save(jit_State *J, GCtrace *T)
  131. {
  132. size_t sztr = ((sizeof(GCtrace)+7)&~7);
  133. size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
  134. char *p = (char *)T + sztr;
  135. memcpy(T, &J->cur, sizeof(GCtrace));
  136. setgcrefr(T->nextgc, J2G(J)->gc.root);
  137. setgcrefp(J2G(J)->gc.root, T);
  138. newwhite(J2G(J), T);
  139. T->gct = ~LJ_TTRACE;
  140. T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */
  141. #if LJ_ABI_PAUTH
  142. T->mcauth = lj_ptr_sign((ASMFunction)T->mcode, T);
  143. #endif
  144. p += szins;
  145. TRACE_APPENDVEC(snap, nsnap, SnapShot)
  146. TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
  147. J->cur.traceno = 0;
  148. J->curfinal = NULL;
  149. setgcrefp(J->trace[T->traceno], T);
  150. lj_gc_barriertrace(J2G(J), T->traceno);
  151. lj_gdbjit_addtrace(J, T);
  152. #ifdef LUAJIT_USE_PERFTOOLS
  153. perftools_addtrace(T);
  154. #endif
  155. }
  156. void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T)
  157. {
  158. jit_State *J = G2J(g);
  159. if (T->traceno) {
  160. lj_gdbjit_deltrace(J, T);
  161. if (T->traceno < J->freetrace)
  162. J->freetrace = T->traceno;
  163. setgcrefnull(J->trace[T->traceno]);
  164. }
  165. lj_mem_free(g, T,
  166. ((sizeof(GCtrace)+7)&~7) + (T->nins-T->nk)*sizeof(IRIns) +
  167. T->nsnap*sizeof(SnapShot) + T->nsnapmap*sizeof(SnapEntry));
  168. }
  169. /* Re-enable compiling a prototype by unpatching any modified bytecode. */
  170. void lj_trace_reenableproto(GCproto *pt)
  171. {
  172. if ((pt->flags & PROTO_ILOOP)) {
  173. BCIns *bc = proto_bc(pt);
  174. BCPos i, sizebc = pt->sizebc;
  175. pt->flags &= ~PROTO_ILOOP;
  176. if (bc_op(bc[0]) == BC_IFUNCF)
  177. setbc_op(&bc[0], BC_FUNCF);
  178. for (i = 1; i < sizebc; i++) {
  179. BCOp op = bc_op(bc[i]);
  180. if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP)
  181. setbc_op(&bc[i], (int)op+(int)BC_LOOP-(int)BC_ILOOP);
  182. }
  183. }
  184. }
  185. /* Unpatch the bytecode modified by a root trace. */
  186. static void trace_unpatch(jit_State *J, GCtrace *T)
  187. {
  188. BCOp op = bc_op(T->startins);
  189. BCIns *pc = mref(T->startpc, BCIns);
  190. UNUSED(J);
  191. if (op == BC_JMP)
  192. return; /* No need to unpatch branches in parent traces (yet). */
  193. switch (bc_op(*pc)) {
  194. case BC_JFORL:
  195. lj_assertJ(traceref(J, bc_d(*pc)) == T, "JFORL references other trace");
  196. *pc = T->startins;
  197. pc += bc_j(T->startins);
  198. lj_assertJ(bc_op(*pc) == BC_JFORI, "FORL does not point to JFORI");
  199. setbc_op(pc, BC_FORI);
  200. break;
  201. case BC_JITERL:
  202. case BC_JLOOP:
  203. lj_assertJ(op == BC_ITERL || op == BC_ITERN || op == BC_LOOP ||
  204. bc_isret(op), "bad original bytecode %d", op);
  205. *pc = T->startins;
  206. break;
  207. case BC_JMP:
  208. lj_assertJ(op == BC_ITERL, "bad original bytecode %d", op);
  209. pc += bc_j(*pc)+2;
  210. if (bc_op(*pc) == BC_JITERL) {
  211. lj_assertJ(traceref(J, bc_d(*pc)) == T, "JITERL references other trace");
  212. *pc = T->startins;
  213. }
  214. break;
  215. case BC_JFUNCF:
  216. lj_assertJ(op == BC_FUNCF, "bad original bytecode %d", op);
  217. *pc = T->startins;
  218. break;
  219. default: /* Already unpatched. */
  220. break;
  221. }
  222. }
  223. /* Flush a root trace. */
  224. static void trace_flushroot(jit_State *J, GCtrace *T)
  225. {
  226. GCproto *pt = &gcref(T->startpt)->pt;
  227. lj_assertJ(T->root == 0, "not a root trace");
  228. lj_assertJ(pt != NULL, "trace has no prototype");
  229. /* First unpatch any modified bytecode. */
  230. trace_unpatch(J, T);
  231. /* Unlink root trace from chain anchored in prototype. */
  232. if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */
  233. pt->trace = T->nextroot;
  234. } else if (pt->trace) { /* Otherwise search in chain of root traces. */
  235. GCtrace *T2 = traceref(J, pt->trace);
  236. if (T2) {
  237. for (; T2->nextroot; T2 = traceref(J, T2->nextroot))
  238. if (T2->nextroot == T->traceno) {
  239. T2->nextroot = T->nextroot; /* Unlink from chain. */
  240. break;
  241. }
  242. }
  243. }
  244. }
  245. /* Flush a trace. Only root traces are considered. */
  246. void lj_trace_flush(jit_State *J, TraceNo traceno)
  247. {
  248. if (traceno > 0 && traceno < J->sizetrace) {
  249. GCtrace *T = traceref(J, traceno);
  250. if (T && T->root == 0)
  251. trace_flushroot(J, T);
  252. }
  253. }
  254. /* Flush all traces associated with a prototype. */
  255. void lj_trace_flushproto(global_State *g, GCproto *pt)
  256. {
  257. while (pt->trace != 0)
  258. trace_flushroot(G2J(g), traceref(G2J(g), pt->trace));
  259. }
  260. /* Flush all traces. */
  261. int lj_trace_flushall(lua_State *L)
  262. {
  263. jit_State *J = L2J(L);
  264. ptrdiff_t i;
  265. if ((J2G(J)->hookmask & HOOK_GC))
  266. return 1;
  267. for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
  268. GCtrace *T = traceref(J, i);
  269. if (T) {
  270. if (T->root == 0)
  271. trace_flushroot(J, T);
  272. lj_gdbjit_deltrace(J, T);
  273. T->traceno = T->link = 0; /* Blacklist the link for cont_stitch. */
  274. setgcrefnull(J->trace[i]);
  275. }
  276. }
  277. J->cur.traceno = 0;
  278. J->freetrace = 0;
  279. /* Clear penalty cache. */
  280. memset(J->penalty, 0, sizeof(J->penalty));
  281. /* Free the whole machine code and invalidate all exit stub groups. */
  282. lj_mcode_free(J);
  283. memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
  284. lj_vmevent_send(L, TRACE,
  285. setstrV(L, L->top++, lj_str_newlit(L, "flush"));
  286. );
  287. return 0;
  288. }
  289. /* Initialize JIT compiler state. */
  290. void lj_trace_initstate(global_State *g)
  291. {
  292. jit_State *J = G2J(g);
  293. TValue *tv;
  294. /* Initialize aligned SIMD constants. */
  295. tv = LJ_KSIMD(J, LJ_KSIMD_ABS);
  296. tv[0].u64 = U64x(7fffffff,ffffffff);
  297. tv[1].u64 = U64x(7fffffff,ffffffff);
  298. tv = LJ_KSIMD(J, LJ_KSIMD_NEG);
  299. tv[0].u64 = U64x(80000000,00000000);
  300. tv[1].u64 = U64x(80000000,00000000);
  301. /* Initialize 32/64 bit constants. */
  302. #if LJ_TARGET_X86ORX64
  303. J->k64[LJ_K64_TOBIT].u64 = U64x(43380000,00000000);
  304. #if LJ_32
  305. J->k64[LJ_K64_M2P64_31].u64 = U64x(c1e00000,00000000);
  306. #endif
  307. J->k64[LJ_K64_2P64].u64 = U64x(43f00000,00000000);
  308. J->k32[LJ_K32_M2P64_31] = LJ_64 ? 0xdf800000 : 0xcf000000;
  309. #endif
  310. #if LJ_TARGET_X86ORX64 || LJ_TARGET_MIPS64
  311. J->k64[LJ_K64_M2P64].u64 = U64x(c3f00000,00000000);
  312. #endif
  313. #if LJ_TARGET_PPC
  314. J->k32[LJ_K32_2P52_2P31] = 0x59800004;
  315. J->k32[LJ_K32_2P52] = 0x59800000;
  316. #endif
  317. #if LJ_TARGET_PPC || LJ_TARGET_MIPS
  318. J->k32[LJ_K32_2P31] = 0x4f000000;
  319. #endif
  320. #if LJ_TARGET_MIPS
  321. J->k64[LJ_K64_2P31].u64 = U64x(41e00000,00000000);
  322. #if LJ_64
  323. J->k64[LJ_K64_2P63].u64 = U64x(43e00000,00000000);
  324. J->k32[LJ_K32_2P63] = 0x5f000000;
  325. J->k32[LJ_K32_M2P64] = 0xdf800000;
  326. #endif
  327. #endif
  328. }
  329. /* Free everything associated with the JIT compiler state. */
  330. void lj_trace_freestate(global_State *g)
  331. {
  332. jit_State *J = G2J(g);
  333. #ifdef LUA_USE_ASSERT
  334. { /* This assumes all traces have already been freed. */
  335. ptrdiff_t i;
  336. for (i = 1; i < (ptrdiff_t)J->sizetrace; i++)
  337. lj_assertG(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL,
  338. "trace still allocated");
  339. }
  340. #endif
  341. lj_mcode_free(J);
  342. lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry);
  343. lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot);
  344. lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns);
  345. lj_mem_freevec(g, J->trace, J->sizetrace, GCRef);
  346. }
  347. /* -- Penalties and blacklisting ------------------------------------------ */
  348. /* Blacklist a bytecode instruction. */
  349. static void blacklist_pc(GCproto *pt, BCIns *pc)
  350. {
  351. if (bc_op(*pc) == BC_ITERN) {
  352. setbc_op(pc, BC_ITERC);
  353. setbc_op(pc+1+bc_j(pc[1]), BC_JMP);
  354. } else {
  355. setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP);
  356. pt->flags |= PROTO_ILOOP;
  357. }
  358. }
  359. /* Penalize a bytecode instruction. */
  360. static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e)
  361. {
  362. uint32_t i, val = PENALTY_MIN;
  363. for (i = 0; i < PENALTY_SLOTS; i++)
  364. if (mref(J->penalty[i].pc, const BCIns) == pc) { /* Cache slot found? */
  365. /* First try to bump its hotcount several times. */
  366. val = ((uint32_t)J->penalty[i].val << 1) +
  367. (lj_prng_u64(&J2G(J)->prng) & ((1u<<PENALTY_RNDBITS)-1));
  368. if (val > PENALTY_MAX) {
  369. blacklist_pc(pt, pc); /* Blacklist it, if that didn't help. */
  370. return;
  371. }
  372. goto setpenalty;
  373. }
  374. /* Assign a new penalty cache slot. */
  375. i = J->penaltyslot;
  376. J->penaltyslot = (J->penaltyslot + 1) & (PENALTY_SLOTS-1);
  377. setmref(J->penalty[i].pc, pc);
  378. setpenalty:
  379. J->penalty[i].val = (uint16_t)val;
  380. J->penalty[i].reason = e;
  381. hotcount_set(J2GG(J), pc+1, val);
  382. }
  383. /* -- Trace compiler state machine ---------------------------------------- */
  384. /* Start tracing. */
  385. static void trace_start(jit_State *J)
  386. {
  387. lua_State *L;
  388. TraceNo traceno;
  389. if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
  390. if (J->parent == 0 && J->exitno == 0 && bc_op(*J->pc) != BC_ITERN) {
  391. /* Lazy bytecode patching to disable hotcount events. */
  392. lj_assertJ(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
  393. bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF,
  394. "bad hot bytecode %d", bc_op(*J->pc));
  395. setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP);
  396. J->pt->flags |= PROTO_ILOOP;
  397. }
  398. J->state = LJ_TRACE_IDLE; /* Silently ignored. */
  399. return;
  400. }
  401. /* Ensuring forward progress for BC_ITERN can trigger hotcount again. */
  402. if (!J->parent && bc_op(*J->pc) == BC_JLOOP) { /* Already compiled. */
  403. J->state = LJ_TRACE_IDLE; /* Silently ignored. */
  404. return;
  405. }
  406. /* Get a new trace number. */
  407. traceno = trace_findfree(J);
  408. if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */
  409. lj_assertJ((J2G(J)->hookmask & HOOK_GC) == 0,
  410. "recorder called from GC hook");
  411. lj_trace_flushall(J->L);
  412. J->state = LJ_TRACE_IDLE; /* Silently ignored. */
  413. return;
  414. }
  415. setgcrefp(J->trace[traceno], &J->cur);
  416. /* Setup enough of the current trace to be able to send the vmevent. */
  417. memset(&J->cur, 0, sizeof(GCtrace));
  418. J->cur.traceno = traceno;
  419. J->cur.nins = J->cur.nk = REF_BASE;
  420. J->cur.ir = J->irbuf;
  421. J->cur.snap = J->snapbuf;
  422. J->cur.snapmap = J->snapmapbuf;
  423. J->mergesnap = 0;
  424. J->needsnap = 0;
  425. J->bcskip = 0;
  426. J->guardemit.irt = 0;
  427. J->postproc = LJ_POST_NONE;
  428. lj_resetsplit(J);
  429. J->retryrec = 0;
  430. J->ktrace = 0;
  431. setgcref(J->cur.startpt, obj2gco(J->pt));
  432. L = J->L;
  433. lj_vmevent_send(L, TRACE,
  434. setstrV(L, L->top++, lj_str_newlit(L, "start"));
  435. setintV(L->top++, traceno);
  436. setfuncV(L, L->top++, J->fn);
  437. setintV(L->top++, proto_bcpos(J->pt, J->pc));
  438. if (J->parent) {
  439. setintV(L->top++, J->parent);
  440. setintV(L->top++, J->exitno);
  441. } else {
  442. BCOp op = bc_op(*J->pc);
  443. if (op == BC_CALLM || op == BC_CALL || op == BC_ITERC) {
  444. setintV(L->top++, J->exitno); /* Parent of stitched trace. */
  445. setintV(L->top++, -1);
  446. }
  447. }
  448. );
  449. lj_record_setup(J);
  450. }
  451. /* Stop tracing. */
  452. static void trace_stop(jit_State *J)
  453. {
  454. BCIns *pc = mref(J->cur.startpc, BCIns);
  455. BCOp op = bc_op(J->cur.startins);
  456. GCproto *pt = &gcref(J->cur.startpt)->pt;
  457. TraceNo traceno = J->cur.traceno;
  458. GCtrace *T = J->curfinal;
  459. lua_State *L;
  460. switch (op) {
  461. case BC_FORL:
  462. setbc_op(pc+bc_j(J->cur.startins), BC_JFORI); /* Patch FORI, too. */
  463. /* fallthrough */
  464. case BC_LOOP:
  465. case BC_ITERL:
  466. case BC_FUNCF:
  467. /* Patch bytecode of starting instruction in root trace. */
  468. setbc_op(pc, (int)op+(int)BC_JLOOP-(int)BC_LOOP);
  469. setbc_d(pc, traceno);
  470. addroot:
  471. /* Add to root trace chain in prototype. */
  472. J->cur.nextroot = pt->trace;
  473. pt->trace = (TraceNo1)traceno;
  474. break;
  475. case BC_ITERN:
  476. case BC_RET:
  477. case BC_RET0:
  478. case BC_RET1:
  479. *pc = BCINS_AD(BC_JLOOP, J->cur.snap[0].nslots, traceno);
  480. goto addroot;
  481. case BC_JMP:
  482. /* Patch exit branch in parent to side trace entry. */
  483. lj_assertJ(J->parent != 0 && J->cur.root != 0, "not a side trace");
  484. lj_asm_patchexit(J, traceref(J, J->parent), J->exitno, J->cur.mcode);
  485. /* Avoid compiling a side trace twice (stack resizing uses parent exit). */
  486. {
  487. SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno];
  488. snap->count = SNAPCOUNT_DONE;
  489. if (J->cur.topslot > snap->topslot) snap->topslot = J->cur.topslot;
  490. }
  491. /* Add to side trace chain in root trace. */
  492. {
  493. GCtrace *root = traceref(J, J->cur.root);
  494. root->nchild++;
  495. J->cur.nextside = root->nextside;
  496. root->nextside = (TraceNo1)traceno;
  497. }
  498. break;
  499. case BC_CALLM:
  500. case BC_CALL:
  501. case BC_ITERC:
  502. /* Trace stitching: patch link of previous trace. */
  503. traceref(J, J->exitno)->link = traceno;
  504. break;
  505. default:
  506. lj_assertJ(0, "bad stop bytecode %d", op);
  507. break;
  508. }
  509. /* Commit new mcode only after all patching is done. */
  510. lj_mcode_commit(J, J->cur.mcode);
  511. J->postproc = LJ_POST_NONE;
  512. trace_save(J, T);
  513. L = J->L;
  514. lj_vmevent_send(L, TRACE,
  515. setstrV(L, L->top++, lj_str_newlit(L, "stop"));
  516. setintV(L->top++, traceno);
  517. setfuncV(L, L->top++, J->fn);
  518. );
  519. }
  520. /* Start a new root trace for down-recursion. */
  521. static int trace_downrec(jit_State *J)
  522. {
  523. /* Restart recording at the return instruction. */
  524. lj_assertJ(J->pt != NULL, "no active prototype");
  525. lj_assertJ(bc_isret(bc_op(*J->pc)), "not at a return bytecode");
  526. if (bc_op(*J->pc) == BC_RETM)
  527. return 0; /* NYI: down-recursion with RETM. */
  528. J->parent = 0;
  529. J->exitno = 0;
  530. J->state = LJ_TRACE_RECORD;
  531. trace_start(J);
  532. return 1;
  533. }
  534. /* Abort tracing. */
  535. static int trace_abort(jit_State *J)
  536. {
  537. lua_State *L = J->L;
  538. TraceError e = LJ_TRERR_RECERR;
  539. TraceNo traceno;
  540. J->postproc = LJ_POST_NONE;
  541. lj_mcode_abort(J);
  542. if (J->curfinal) {
  543. lj_trace_free(J2G(J), J->curfinal);
  544. J->curfinal = NULL;
  545. }
  546. if (tvisnumber(L->top-1))
  547. e = (TraceError)numberVint(L->top-1);
  548. if (e == LJ_TRERR_MCODELM) {
  549. L->top--; /* Remove error object */
  550. J->state = LJ_TRACE_ASM;
  551. return 1; /* Retry ASM with new MCode area. */
  552. }
  553. /* Penalize or blacklist starting bytecode instruction. */
  554. if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) {
  555. if (J->exitno == 0) {
  556. BCIns *startpc = mref(J->cur.startpc, BCIns);
  557. if (e == LJ_TRERR_RETRY)
  558. hotcount_set(J2GG(J), startpc+1, 1); /* Immediate retry. */
  559. else
  560. penalty_pc(J, &gcref(J->cur.startpt)->pt, startpc, e);
  561. } else {
  562. traceref(J, J->exitno)->link = J->exitno; /* Self-link is blacklisted. */
  563. }
  564. }
  565. /* Is there anything to abort? */
  566. traceno = J->cur.traceno;
  567. if (traceno) {
  568. ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
  569. J->cur.link = 0;
  570. J->cur.linktype = LJ_TRLINK_NONE;
  571. lj_vmevent_send(L, TRACE,
  572. cTValue *bot = tvref(L->stack)+LJ_FR2;
  573. cTValue *frame;
  574. const BCIns *pc;
  575. BCPos pos = 0;
  576. setstrV(L, L->top++, lj_str_newlit(L, "abort"));
  577. setintV(L->top++, traceno);
  578. /* Find original Lua function call to generate a better error message. */
  579. for (frame = J->L->base-1, pc = J->pc; ; frame = frame_prev(frame)) {
  580. if (isluafunc(frame_func(frame))) {
  581. pos = proto_bcpos(funcproto(frame_func(frame)), pc);
  582. break;
  583. } else if (frame_prev(frame) <= bot) {
  584. break;
  585. } else if (frame_iscont(frame)) {
  586. pc = frame_contpc(frame) - 1;
  587. } else {
  588. pc = frame_pc(frame) - 1;
  589. }
  590. }
  591. setfuncV(L, L->top++, frame_func(frame));
  592. setintV(L->top++, pos);
  593. copyTV(L, L->top++, restorestack(L, errobj));
  594. copyTV(L, L->top++, &J->errinfo);
  595. );
  596. /* Drop aborted trace after the vmevent (which may still access it). */
  597. setgcrefnull(J->trace[traceno]);
  598. if (traceno < J->freetrace)
  599. J->freetrace = traceno;
  600. J->cur.traceno = 0;
  601. }
  602. L->top--; /* Remove error object */
  603. if (e == LJ_TRERR_DOWNREC)
  604. return trace_downrec(J);
  605. else if (e == LJ_TRERR_MCODEAL)
  606. lj_trace_flushall(L);
  607. return 0;
  608. }
  609. /* Perform pending re-patch of a bytecode instruction. */
  610. static LJ_AINLINE void trace_pendpatch(jit_State *J, int force)
  611. {
  612. if (LJ_UNLIKELY(J->patchpc)) {
  613. if (force || J->bcskip == 0) {
  614. *J->patchpc = J->patchins;
  615. J->patchpc = NULL;
  616. } else {
  617. J->bcskip = 0;
  618. }
  619. }
  620. }
  621. /* State machine for the trace compiler. Protected callback. */
  622. static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
  623. {
  624. jit_State *J = (jit_State *)ud;
  625. UNUSED(dummy);
  626. do {
  627. retry:
  628. switch (J->state) {
  629. case LJ_TRACE_START:
  630. J->state = LJ_TRACE_RECORD; /* trace_start() may change state. */
  631. trace_start(J);
  632. lj_dispatch_update(J2G(J));
  633. if (J->state != LJ_TRACE_RECORD_1ST)
  634. break;
  635. /* fallthrough */
  636. case LJ_TRACE_RECORD_1ST:
  637. J->state = LJ_TRACE_RECORD;
  638. /* fallthrough */
  639. case LJ_TRACE_RECORD:
  640. trace_pendpatch(J, 0);
  641. setvmstate(J2G(J), RECORD);
  642. lj_vmevent_send_(L, RECORD,
  643. /* Save/restore state for trace recorder. */
  644. TValue savetv = J2G(J)->tmptv;
  645. TValue savetv2 = J2G(J)->tmptv2;
  646. TraceNo parent = J->parent;
  647. ExitNo exitno = J->exitno;
  648. setintV(L->top++, J->cur.traceno);
  649. setfuncV(L, L->top++, J->fn);
  650. setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1);
  651. setintV(L->top++, J->framedepth);
  652. ,
  653. J2G(J)->tmptv = savetv;
  654. J2G(J)->tmptv2 = savetv2;
  655. J->parent = parent;
  656. J->exitno = exitno;
  657. );
  658. lj_record_ins(J);
  659. break;
  660. case LJ_TRACE_END:
  661. trace_pendpatch(J, 1);
  662. J->loopref = 0;
  663. if ((J->flags & JIT_F_OPT_LOOP) &&
  664. J->cur.link == J->cur.traceno && J->framedepth + J->retdepth == 0) {
  665. setvmstate(J2G(J), OPT);
  666. lj_opt_dce(J);
  667. if (lj_opt_loop(J)) { /* Loop optimization failed? */
  668. J->cur.link = 0;
  669. J->cur.linktype = LJ_TRLINK_NONE;
  670. J->loopref = J->cur.nins;
  671. J->state = LJ_TRACE_RECORD; /* Try to continue recording. */
  672. break;
  673. }
  674. J->loopref = J->chain[IR_LOOP]; /* Needed by assembler. */
  675. }
  676. lj_opt_split(J);
  677. lj_opt_sink(J);
  678. if (!J->loopref) J->cur.snap[J->cur.nsnap-1].count = SNAPCOUNT_DONE;
  679. J->state = LJ_TRACE_ASM;
  680. break;
  681. case LJ_TRACE_ASM:
  682. setvmstate(J2G(J), ASM);
  683. lj_asm_trace(J, &J->cur);
  684. trace_stop(J);
  685. setvmstate(J2G(J), INTERP);
  686. J->state = LJ_TRACE_IDLE;
  687. lj_dispatch_update(J2G(J));
  688. return NULL;
  689. default: /* Trace aborted asynchronously. */
  690. setintV(L->top++, (int32_t)LJ_TRERR_RECERR);
  691. /* fallthrough */
  692. case LJ_TRACE_ERR:
  693. trace_pendpatch(J, 1);
  694. if (trace_abort(J))
  695. goto retry;
  696. setvmstate(J2G(J), INTERP);
  697. J->state = LJ_TRACE_IDLE;
  698. lj_dispatch_update(J2G(J));
  699. return NULL;
  700. }
  701. } while (J->state > LJ_TRACE_RECORD);
  702. return NULL;
  703. }
  704. /* -- Event handling ------------------------------------------------------ */
  705. /* A bytecode instruction is about to be executed. Record it. */
  706. void lj_trace_ins(jit_State *J, const BCIns *pc)
  707. {
  708. /* Note: J->L must already be set. pc is the true bytecode PC here. */
  709. J->pc = pc;
  710. J->fn = curr_func(J->L);
  711. J->pt = isluafunc(J->fn) ? funcproto(J->fn) : NULL;
  712. while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0)
  713. J->state = LJ_TRACE_ERR;
  714. }
  715. /* A hotcount triggered. Start recording a root trace. */
  716. void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc)
  717. {
  718. /* Note: pc is the interpreter bytecode PC here. It's offset by 1. */
  719. ERRNO_SAVE
  720. /* Reset hotcount. */
  721. hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]*HOTCOUNT_LOOP);
  722. /* Only start a new trace if not recording or inside __gc call or vmevent. */
  723. if (J->state == LJ_TRACE_IDLE &&
  724. !(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
  725. J->parent = 0; /* Root trace. */
  726. J->exitno = 0;
  727. J->state = LJ_TRACE_START;
  728. lj_trace_ins(J, pc-1);
  729. }
  730. ERRNO_RESTORE
  731. }
  732. /* Check for a hot side exit. If yes, start recording a side trace. */
  733. static void trace_hotside(jit_State *J, const BCIns *pc)
  734. {
  735. SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno];
  736. if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) &&
  737. isluafunc(curr_func(J->L)) &&
  738. snap->count != SNAPCOUNT_DONE &&
  739. ++snap->count >= J->param[JIT_P_hotexit]) {
  740. lj_assertJ(J->state == LJ_TRACE_IDLE, "hot side exit while recording");
  741. /* J->parent is non-zero for a side trace. */
  742. J->state = LJ_TRACE_START;
  743. lj_trace_ins(J, pc);
  744. }
  745. }
  746. /* Stitch a new trace to the previous trace. */
  747. void LJ_FASTCALL lj_trace_stitch(jit_State *J, const BCIns *pc)
  748. {
  749. /* Only start a new trace if not recording or inside __gc call or vmevent. */
  750. if (J->state == LJ_TRACE_IDLE &&
  751. !(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
  752. J->parent = 0; /* Have to treat it like a root trace. */
  753. /* J->exitno is set to the invoking trace. */
  754. J->state = LJ_TRACE_START;
  755. lj_trace_ins(J, pc);
  756. }
  757. }
  758. /* Tiny struct to pass data to protected call. */
  759. typedef struct ExitDataCP {
  760. jit_State *J;
  761. void *exptr; /* Pointer to exit state. */
  762. const BCIns *pc; /* Restart interpreter at this PC. */
  763. } ExitDataCP;
  764. /* Need to protect lj_snap_restore because it may throw. */
  765. static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud)
  766. {
  767. ExitDataCP *exd = (ExitDataCP *)ud;
  768. /* Always catch error here and don't call error function. */
  769. cframe_errfunc(L->cframe) = 0;
  770. cframe_nres(L->cframe) = -2*LUAI_MAXSTACK*(int)sizeof(TValue);
  771. exd->pc = lj_snap_restore(exd->J, exd->exptr);
  772. UNUSED(dummy);
  773. return NULL;
  774. }
  775. #ifndef LUAJIT_DISABLE_VMEVENT
  776. /* Push all registers from exit state. */
  777. static void trace_exit_regs(lua_State *L, ExitState *ex)
  778. {
  779. int32_t i;
  780. setintV(L->top++, RID_NUM_GPR);
  781. setintV(L->top++, RID_NUM_FPR);
  782. for (i = 0; i < RID_NUM_GPR; i++) {
  783. if (sizeof(ex->gpr[i]) == sizeof(int32_t))
  784. setintV(L->top++, (int32_t)ex->gpr[i]);
  785. else
  786. setnumV(L->top++, (lua_Number)ex->gpr[i]);
  787. }
  788. #if !LJ_SOFTFP
  789. for (i = 0; i < RID_NUM_FPR; i++) {
  790. setnumV(L->top, ex->fpr[i]);
  791. if (LJ_UNLIKELY(tvisnan(L->top)))
  792. setnanV(L->top);
  793. L->top++;
  794. }
  795. #endif
  796. }
  797. #endif
  798. #if defined(EXITSTATE_PCREG) || (LJ_UNWIND_JIT && !EXITTRACE_VMSTATE)
  799. /* Determine trace number from pc of exit instruction. */
  800. static TraceNo trace_exit_find(jit_State *J, MCode *pc)
  801. {
  802. TraceNo traceno;
  803. for (traceno = 1; traceno < J->sizetrace; traceno++) {
  804. GCtrace *T = traceref(J, traceno);
  805. if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode))
  806. return traceno;
  807. }
  808. lj_assertJ(0, "bad exit pc");
  809. return 0;
  810. }
  811. #endif
  812. /* A trace exited. Restore interpreter state. */
  813. int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
  814. {
  815. ERRNO_SAVE
  816. lua_State *L = J->L;
  817. ExitState *ex = (ExitState *)exptr;
  818. ExitDataCP exd;
  819. int errcode, exitcode = J->exitcode;
  820. TValue exiterr;
  821. const BCIns *pc, *retpc;
  822. void *cf;
  823. GCtrace *T;
  824. setnilV(&exiterr);
  825. if (exitcode) { /* Trace unwound with error code. */
  826. J->exitcode = 0;
  827. copyTV(L, &exiterr, L->top-1);
  828. }
  829. #ifdef EXITSTATE_PCREG
  830. J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
  831. #endif
  832. T = traceref(J, J->parent); UNUSED(T);
  833. #ifdef EXITSTATE_CHECKEXIT
  834. if (J->exitno == T->nsnap) { /* Treat stack check like a parent exit. */
  835. lj_assertJ(T->root != 0, "stack check in root trace");
  836. J->exitno = T->ir[REF_BASE].op2;
  837. J->parent = T->ir[REF_BASE].op1;
  838. T = traceref(J, J->parent);
  839. }
  840. #endif
  841. lj_assertJ(T != NULL && J->exitno < T->nsnap, "bad trace or exit number");
  842. exd.J = J;
  843. exd.exptr = exptr;
  844. errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
  845. if (errcode)
  846. return -errcode; /* Return negated error code. */
  847. if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */
  848. if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)))
  849. lj_vmevent_send(L, TEXIT,
  850. lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
  851. setintV(L->top++, J->parent);
  852. setintV(L->top++, J->exitno);
  853. trace_exit_regs(L, ex);
  854. );
  855. pc = exd.pc;
  856. cf = cframe_raw(L->cframe);
  857. setcframe_pc(cf, pc);
  858. if (exitcode) {
  859. return -exitcode;
  860. } else if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) {
  861. /* Just exit to interpreter. */
  862. } else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
  863. if (!(G(L)->hookmask & HOOK_GC))
  864. lj_gc_step(L); /* Exited because of GC: drive GC forward. */
  865. } else if ((J->flags & JIT_F_ON)) {
  866. trace_hotside(J, pc);
  867. }
  868. /* Return MULTRES or 0 or -17. */
  869. ERRNO_RESTORE
  870. switch (bc_op(*pc)) {
  871. case BC_CALLM: case BC_CALLMT:
  872. return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc) - LJ_FR2);
  873. case BC_RETM:
  874. return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
  875. case BC_TSETM:
  876. return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
  877. case BC_JLOOP:
  878. retpc = &traceref(J, bc_d(*pc))->startins;
  879. if (bc_isret(bc_op(*retpc)) || bc_op(*retpc) == BC_ITERN) {
  880. /* Dispatch to original ins to ensure forward progress. */
  881. if (J->state != LJ_TRACE_RECORD) return -17;
  882. /* Unpatch bytecode when recording. */
  883. J->patchins = *pc;
  884. J->patchpc = (BCIns *)pc;
  885. *J->patchpc = *retpc;
  886. J->bcskip = 1;
  887. }
  888. return 0;
  889. default:
  890. if (bc_op(*pc) >= BC_FUNCF)
  891. return (int)((BCReg)(L->top - L->base) + 1);
  892. return 0;
  893. }
  894. }
  895. #if LJ_UNWIND_JIT
  896. /* Given an mcode address determine trace exit address for unwinding. */
  897. uintptr_t LJ_FASTCALL lj_trace_unwind(jit_State *J, uintptr_t addr, ExitNo *ep)
  898. {
  899. #if EXITTRACE_VMSTATE
  900. TraceNo traceno = J2G(J)->vmstate;
  901. #else
  902. TraceNo traceno = trace_exit_find(J, (MCode *)addr);
  903. #endif
  904. GCtrace *T = traceref(J, traceno);
  905. if (T
  906. #if EXITTRACE_VMSTATE
  907. && addr >= (uintptr_t)T->mcode && addr < (uintptr_t)T->mcode + T->szmcode
  908. #endif
  909. ) {
  910. SnapShot *snap = T->snap;
  911. SnapNo lo = 0, exitno = T->nsnap;
  912. uintptr_t ofs = (uintptr_t)((MCode *)addr - T->mcode); /* MCode units! */
  913. /* Rightmost binary search for mcode offset to determine exit number. */
  914. do {
  915. SnapNo mid = (lo+exitno) >> 1;
  916. if (ofs < snap[mid].mcofs) exitno = mid; else lo = mid + 1;
  917. } while (lo < exitno);
  918. exitno--;
  919. *ep = exitno;
  920. #ifdef EXITSTUBS_PER_GROUP
  921. return (uintptr_t)exitstub_addr(J, exitno);
  922. #else
  923. return (uintptr_t)exitstub_trace_addr(T, exitno);
  924. #endif
  925. }
  926. /* Cannot correlate addr with trace/exit. This will be fatal. */
  927. lj_assertJ(0, "bad exit pc");
  928. return 0;
  929. }
  930. #endif
  931. #endif