diff options
Diffstat (limited to 'src/lj_trace.c')
-rw-r--r-- | src/lj_trace.c | 62 |
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. */ | ||
688 | static 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. */ | ||
712 | static 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. */ |
689 | int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | 726 | int 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; |