summaryrefslogtreecommitdiff
path: root/src/lj_trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_trace.c')
-rw-r--r--src/lj_trace.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c
index ecfbfed6..7141de46 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -278,9 +278,7 @@ int lj_trace_flushall(lua_State *L)
278 memset(J->penalty, 0, sizeof(J->penalty)); 278 memset(J->penalty, 0, sizeof(J->penalty));
279 /* Free the whole machine code and invalidate all exit stub groups. */ 279 /* Free the whole machine code and invalidate all exit stub groups. */
280 lj_mcode_free(J); 280 lj_mcode_free(J);
281#ifdef EXITSTUBS_PER_GROUP
282 memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); 281 memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
283#endif
284 lj_vmevent_send(L, TRACE, 282 lj_vmevent_send(L, TRACE,
285 setstrV(L, L->top++, lj_str_newlit(L, "flush")); 283 setstrV(L, L->top++, lj_str_newlit(L, "flush"));
286 ); 284 );
@@ -685,15 +683,58 @@ static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud)
685 return NULL; 683 return NULL;
686} 684}
687 685
686#ifndef LUAJIT_DISABLE_VMEVENT
687/* Push all registers from exit state. */
688static void trace_exit_regs(lua_State *L, ExitState *ex)
689{
690 int32_t i;
691 setintV(L->top++, RID_NUM_GPR);
692 setintV(L->top++, RID_NUM_FPR);
693 for (i = 0; i < RID_NUM_GPR; i++) {
694 if (sizeof(ex->gpr[i]) == sizeof(int32_t))
695 setintV(L->top++, (int32_t)ex->gpr[i]);
696 else
697 setnumV(L->top++, (lua_Number)ex->gpr[i]);
698 }
699#if !LJ_SOFTFP
700 for (i = 0; i < RID_NUM_FPR; i++) {
701 setnumV(L->top, ex->fpr[i]);
702 if (LJ_UNLIKELY(tvisnan(L->top)))
703 setnanV(L->top);
704 L->top++;
705 }
706#endif
707}
708#endif
709
710#ifdef EXITSTATE_PCREG
711/* Determine trace number from pc of exit instruction. */
712static TraceNo trace_exit_find(jit_State *J, MCode *pc)
713{
714 TraceNo traceno;
715 for (traceno = 1; traceno < J->sizetrace; traceno++) {
716 GCtrace *T = traceref(J, traceno);
717 if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode))
718 return traceno;
719 }
720 lua_assert(0);
721 return 0;
722}
723#endif
724
688/* A trace exited. Restore interpreter state. */ 725/* A trace exited. Restore interpreter state. */
689int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) 726int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
690{ 727{
691 ERRNO_SAVE 728 ERRNO_SAVE
692 lua_State *L = J->L; 729 lua_State *L = J->L;
730 ExitState *ex = (ExitState *)exptr;
693 ExitDataCP exd; 731 ExitDataCP exd;
694 int errcode; 732 int errcode;
695 const BCIns *pc; 733 const BCIns *pc;
696 void *cf; 734 void *cf;
735#ifdef EXITSTATE_PCREG
736 J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
737#endif
697 exd.J = J; 738 exd.J = J;
698 exd.exptr = exptr; 739 exd.exptr = exptr;
699 errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp); 740 errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
@@ -701,25 +742,10 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
701 return -errcode; /* Return negated error code. */ 742 return -errcode; /* Return negated error code. */
702 743
703 lj_vmevent_send(L, TEXIT, 744 lj_vmevent_send(L, TEXIT,
704 ExitState *ex = (ExitState *)exptr;
705 int32_t i;
706 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); 745 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
707 setintV(L->top++, J->parent); 746 setintV(L->top++, J->parent);
708 setintV(L->top++, J->exitno); 747 setintV(L->top++, J->exitno);
709 setintV(L->top++, RID_NUM_GPR); 748 trace_exit_regs(L, ex);
710 setintV(L->top++, RID_NUM_FPR);
711 for (i = 0; i < RID_NUM_GPR; i++) {
712 if (sizeof(ex->gpr[i]) == sizeof(int32_t))
713 setintV(L->top++, (int32_t)ex->gpr[i]);
714 else
715 setnumV(L->top++, (lua_Number)ex->gpr[i]);
716 }
717 for (i = 0; i < RID_NUM_FPR; i++) {
718 setnumV(L->top, ex->fpr[i]);
719 if (LJ_UNLIKELY(tvisnan(L->top)))
720 setnanV(L->top);
721 L->top++;
722 }
723 ); 749 );
724 750
725 pc = exd.pc; 751 pc = exd.pc;