aboutsummaryrefslogtreecommitdiff
path: root/src/lj_trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_trace.c')
-rw-r--r--src/lj_trace.c131
1 files changed, 108 insertions, 23 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c
index 311baa73..a43c8c4e 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -117,15 +117,26 @@ static void perftools_addtrace(GCtrace *T)
117} 117}
118#endif 118#endif
119 119
120/* Allocate space for copy of trace. */ 120/* Allocate space for copy of T. */
121static GCtrace *trace_save_alloc(jit_State *J) 121GCtrace * LJ_FASTCALL lj_trace_alloc(lua_State *L, GCtrace *T)
122{ 122{
123 size_t sztr = ((sizeof(GCtrace)+7)&~7); 123 size_t sztr = ((sizeof(GCtrace)+7)&~7);
124 size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); 124 size_t szins = (T->nins-T->nk)*sizeof(IRIns);
125 size_t sz = sztr + szins + 125 size_t sz = sztr + szins +
126 J->cur.nsnap*sizeof(SnapShot) + 126 T->nsnap*sizeof(SnapShot) +
127 J->cur.nsnapmap*sizeof(SnapEntry); 127 T->nsnapmap*sizeof(SnapEntry);
128 return lj_mem_newt(J->L, (MSize)sz, GCtrace); 128 GCtrace *T2 = lj_mem_newt(L, (MSize)sz, GCtrace);
129 char *p = (char *)T2 + sztr;
130 T2->gct = ~LJ_TTRACE;
131 T2->marked = 0;
132 T2->traceno = 0;
133 T2->ir = (IRIns *)p - T->nk;
134 T2->nins = T->nins;
135 T2->nk = T->nk;
136 T2->nsnap = T->nsnap;
137 T2->nsnapmap = T->nsnapmap;
138 memcpy(p, T->ir + T->nk, szins);
139 return T2;
129} 140}
130 141
131/* Save current trace by copying and compacting it. */ 142/* Save current trace by copying and compacting it. */
@@ -139,12 +150,12 @@ static void trace_save(jit_State *J, GCtrace *T)
139 setgcrefp(J2G(J)->gc.root, T); 150 setgcrefp(J2G(J)->gc.root, T);
140 newwhite(J2G(J), T); 151 newwhite(J2G(J), T);
141 T->gct = ~LJ_TTRACE; 152 T->gct = ~LJ_TTRACE;
142 T->ir = (IRIns *)p - J->cur.nk; 153 T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */
143 memcpy(p, J->cur.ir+J->cur.nk, szins);
144 p += szins; 154 p += szins;
145 TRACE_APPENDVEC(snap, nsnap, SnapShot) 155 TRACE_APPENDVEC(snap, nsnap, SnapShot)
146 TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) 156 TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
147 J->cur.traceno = 0; 157 J->cur.traceno = 0;
158 J->curfinal = NULL;
148 setgcrefp(J->trace[T->traceno], T); 159 setgcrefp(J->trace[T->traceno], T);
149 lj_gc_barriertrace(J2G(J), T->traceno); 160 lj_gc_barriertrace(J2G(J), T->traceno);
150 lj_gdbjit_addtrace(J, T); 161 lj_gdbjit_addtrace(J, T);
@@ -274,7 +285,7 @@ int lj_trace_flushall(lua_State *L)
274 if (T->root == 0) 285 if (T->root == 0)
275 trace_flushroot(J, T); 286 trace_flushroot(J, T);
276 lj_gdbjit_deltrace(J, T); 287 lj_gdbjit_deltrace(J, T);
277 T->traceno = 0; 288 T->traceno = T->link = 0; /* Blacklist the link for cont_stitch. */
278 setgcrefnull(J->trace[i]); 289 setgcrefnull(J->trace[i]);
279 } 290 }
280 } 291 }
@@ -296,13 +307,42 @@ void lj_trace_initstate(global_State *g)
296{ 307{
297 jit_State *J = G2J(g); 308 jit_State *J = G2J(g);
298 TValue *tv; 309 TValue *tv;
299 /* Initialize SIMD constants. */ 310
311 /* Initialize aligned SIMD constants. */
300 tv = LJ_KSIMD(J, LJ_KSIMD_ABS); 312 tv = LJ_KSIMD(J, LJ_KSIMD_ABS);
301 tv[0].u64 = U64x(7fffffff,ffffffff); 313 tv[0].u64 = U64x(7fffffff,ffffffff);
302 tv[1].u64 = U64x(7fffffff,ffffffff); 314 tv[1].u64 = U64x(7fffffff,ffffffff);
303 tv = LJ_KSIMD(J, LJ_KSIMD_NEG); 315 tv = LJ_KSIMD(J, LJ_KSIMD_NEG);
304 tv[0].u64 = U64x(80000000,00000000); 316 tv[0].u64 = U64x(80000000,00000000);
305 tv[1].u64 = U64x(80000000,00000000); 317 tv[1].u64 = U64x(80000000,00000000);
318
319 /* Initialize 32/64 bit constants. */
320#if LJ_TARGET_X86ORX64
321 J->k64[LJ_K64_TOBIT].u64 = U64x(43380000,00000000);
322#if LJ_32
323 J->k64[LJ_K64_M2P64_31].u64 = U64x(c1e00000,00000000);
324#endif
325 J->k64[LJ_K64_2P64].u64 = U64x(43f00000,00000000);
326 J->k32[LJ_K32_M2P64_31] = LJ_64 ? 0xdf800000 : 0xcf000000;
327#endif
328#if LJ_TARGET_X86ORX64 || LJ_TARGET_MIPS64
329 J->k64[LJ_K64_M2P64].u64 = U64x(c3f00000,00000000);
330#endif
331#if LJ_TARGET_PPC
332 J->k32[LJ_K32_2P52_2P31] = 0x59800004;
333 J->k32[LJ_K32_2P52] = 0x59800000;
334#endif
335#if LJ_TARGET_PPC || LJ_TARGET_MIPS
336 J->k32[LJ_K32_2P31] = 0x4f000000;
337#endif
338#if LJ_TARGET_MIPS
339 J->k64[LJ_K64_2P31].u64 = U64x(41e00000,00000000);
340#if LJ_64
341 J->k64[LJ_K64_2P63].u64 = U64x(43e00000,00000000);
342 J->k32[LJ_K32_2P63] = 0x5f000000;
343 J->k32[LJ_K32_M2P64] = 0xdf800000;
344#endif
345#endif
306} 346}
307 347
308/* Free everything associated with the JIT compiler state. */ 348/* Free everything associated with the JIT compiler state. */
@@ -317,7 +357,6 @@ void lj_trace_freestate(global_State *g)
317 } 357 }
318#endif 358#endif
319 lj_mcode_free(J); 359 lj_mcode_free(J);
320 lj_ir_k64_freeall(J);
321 lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry); 360 lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry);
322 lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot); 361 lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot);
323 lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns); 362 lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns);
@@ -367,7 +406,7 @@ static void trace_start(jit_State *J)
367 TraceNo traceno; 406 TraceNo traceno;
368 407
369 if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */ 408 if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
370 if (J->parent == 0) { 409 if (J->parent == 0 && J->exitno == 0) {
371 /* Lazy bytecode patching to disable hotcount events. */ 410 /* Lazy bytecode patching to disable hotcount events. */
372 lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL || 411 lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
373 bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF); 412 bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF);
@@ -401,6 +440,8 @@ static void trace_start(jit_State *J)
401 J->guardemit.irt = 0; 440 J->guardemit.irt = 0;
402 J->postproc = LJ_POST_NONE; 441 J->postproc = LJ_POST_NONE;
403 lj_resetsplit(J); 442 lj_resetsplit(J);
443 J->retryrec = 0;
444 J->ktrace = 0;
404 setgcref(J->cur.startpt, obj2gco(J->pt)); 445 setgcref(J->cur.startpt, obj2gco(J->pt));
405 446
406 L = J->L; 447 L = J->L;
@@ -412,6 +453,12 @@ static void trace_start(jit_State *J)
412 if (J->parent) { 453 if (J->parent) {
413 setintV(L->top++, J->parent); 454 setintV(L->top++, J->parent);
414 setintV(L->top++, J->exitno); 455 setintV(L->top++, J->exitno);
456 } else {
457 BCOp op = bc_op(*J->pc);
458 if (op == BC_CALLM || op == BC_CALL || op == BC_ITERC) {
459 setintV(L->top++, J->exitno); /* Parent of stitched trace. */
460 setintV(L->top++, -1);
461 }
415 } 462 }
416 ); 463 );
417 lj_record_setup(J); 464 lj_record_setup(J);
@@ -424,7 +471,7 @@ static void trace_stop(jit_State *J)
424 BCOp op = bc_op(J->cur.startins); 471 BCOp op = bc_op(J->cur.startins);
425 GCproto *pt = &gcref(J->cur.startpt)->pt; 472 GCproto *pt = &gcref(J->cur.startpt)->pt;
426 TraceNo traceno = J->cur.traceno; 473 TraceNo traceno = J->cur.traceno;
427 GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */ 474 GCtrace *T = J->curfinal;
428 lua_State *L; 475 lua_State *L;
429 476
430 switch (op) { 477 switch (op) {
@@ -461,6 +508,12 @@ static void trace_stop(jit_State *J)
461 root->nextside = (TraceNo1)traceno; 508 root->nextside = (TraceNo1)traceno;
462 } 509 }
463 break; 510 break;
511 case BC_CALLM:
512 case BC_CALL:
513 case BC_ITERC:
514 /* Trace stitching: patch link of previous trace. */
515 traceref(J, J->exitno)->link = traceno;
516 break;
464 default: 517 default:
465 lua_assert(0); 518 lua_assert(0);
466 break; 519 break;
@@ -475,6 +528,7 @@ static void trace_stop(jit_State *J)
475 lj_vmevent_send(L, TRACE, 528 lj_vmevent_send(L, TRACE,
476 setstrV(L, L->top++, lj_str_newlit(L, "stop")); 529 setstrV(L, L->top++, lj_str_newlit(L, "stop"));
477 setintV(L->top++, traceno); 530 setintV(L->top++, traceno);
531 setfuncV(L, L->top++, J->fn);
478 ); 532 );
479} 533}
480 534
@@ -502,6 +556,10 @@ static int trace_abort(jit_State *J)
502 556
503 J->postproc = LJ_POST_NONE; 557 J->postproc = LJ_POST_NONE;
504 lj_mcode_abort(J); 558 lj_mcode_abort(J);
559 if (J->curfinal) {
560 lj_trace_free(J2G(J), J->curfinal);
561 J->curfinal = NULL;
562 }
505 if (tvisnumber(L->top-1)) 563 if (tvisnumber(L->top-1))
506 e = (TraceError)numberVint(L->top-1); 564 e = (TraceError)numberVint(L->top-1);
507 if (e == LJ_TRERR_MCODELM) { 565 if (e == LJ_TRERR_MCODELM) {
@@ -510,8 +568,17 @@ static int trace_abort(jit_State *J)
510 return 1; /* Retry ASM with new MCode area. */ 568 return 1; /* Retry ASM with new MCode area. */
511 } 569 }
512 /* Penalize or blacklist starting bytecode instruction. */ 570 /* Penalize or blacklist starting bytecode instruction. */
513 if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) 571 if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) {
514 penalty_pc(J, &gcref(J->cur.startpt)->pt, mref(J->cur.startpc, BCIns), e); 572 if (J->exitno == 0) {
573 BCIns *startpc = mref(J->cur.startpc, BCIns);
574 if (e == LJ_TRERR_RETRY)
575 hotcount_set(J2GG(J), startpc+1, 1); /* Immediate retry. */
576 else
577 penalty_pc(J, &gcref(J->cur.startpt)->pt, startpc, e);
578 } else {
579 traceref(J, J->exitno)->link = J->exitno; /* Self-link is blacklisted. */
580 }
581 }
515 582
516 /* Is there anything to abort? */ 583 /* Is there anything to abort? */
517 traceno = J->cur.traceno; 584 traceno = J->cur.traceno;
@@ -680,6 +747,7 @@ static void trace_hotside(jit_State *J, const BCIns *pc)
680{ 747{
681 SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno]; 748 SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno];
682 if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) && 749 if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) &&
750 isluafunc(curr_func(J->L)) &&
683 snap->count != SNAPCOUNT_DONE && 751 snap->count != SNAPCOUNT_DONE &&
684 ++snap->count >= J->param[JIT_P_hotexit]) { 752 ++snap->count >= J->param[JIT_P_hotexit]) {
685 lua_assert(J->state == LJ_TRACE_IDLE); 753 lua_assert(J->state == LJ_TRACE_IDLE);
@@ -689,6 +757,20 @@ static void trace_hotside(jit_State *J, const BCIns *pc)
689 } 757 }
690} 758}
691 759
760/* Stitch a new trace to the previous trace. */
761void LJ_FASTCALL lj_trace_stitch(jit_State *J, const BCIns *pc)
762{
763 /* Only start a new trace if not recording or inside __gc call or vmevent. */
764 if (J->state == LJ_TRACE_IDLE &&
765 !(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
766 J->parent = 0; /* Have to treat it like a root trace. */
767 /* J->exitno is set to the invoking trace. */
768 J->state = LJ_TRACE_START;
769 lj_trace_ins(J, pc);
770 }
771}
772
773
692/* Tiny struct to pass data to protected call. */ 774/* Tiny struct to pass data to protected call. */
693typedef struct ExitDataCP { 775typedef struct ExitDataCP {
694 jit_State *J; 776 jit_State *J;
@@ -775,17 +857,20 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
775 if (errcode) 857 if (errcode)
776 return -errcode; /* Return negated error code. */ 858 return -errcode; /* Return negated error code. */
777 859
778 lj_vmevent_send(L, TEXIT, 860 if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)))
779 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); 861 lj_vmevent_send(L, TEXIT,
780 setintV(L->top++, J->parent); 862 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
781 setintV(L->top++, J->exitno); 863 setintV(L->top++, J->parent);
782 trace_exit_regs(L, ex); 864 setintV(L->top++, J->exitno);
783 ); 865 trace_exit_regs(L, ex);
866 );
784 867
785 pc = exd.pc; 868 pc = exd.pc;
786 cf = cframe_raw(L->cframe); 869 cf = cframe_raw(L->cframe);
787 setcframe_pc(cf, pc); 870 setcframe_pc(cf, pc);
788 if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) { 871 if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) {
872 /* Just exit to interpreter. */
873 } else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
789 if (!(G(L)->hookmask & HOOK_GC)) 874 if (!(G(L)->hookmask & HOOK_GC))
790 lj_gc_step(L); /* Exited because of GC: drive GC forward. */ 875 lj_gc_step(L); /* Exited because of GC: drive GC forward. */
791 } else { 876 } else {
@@ -809,7 +894,7 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
809 ERRNO_RESTORE 894 ERRNO_RESTORE
810 switch (bc_op(*pc)) { 895 switch (bc_op(*pc)) {
811 case BC_CALLM: case BC_CALLMT: 896 case BC_CALLM: case BC_CALLMT:
812 return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc)); 897 return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc) - LJ_FR2);
813 case BC_RETM: 898 case BC_RETM:
814 return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc)); 899 return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
815 case BC_TSETM: 900 case BC_TSETM: