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.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c
index 4608f81f..a0ff8864 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -821,7 +821,7 @@ static void trace_exit_regs(lua_State *L, ExitState *ex)
821} 821}
822#endif 822#endif
823 823
824#ifdef EXITSTATE_PCREG 824#if defined(EXITSTATE_PCREG) || (LJ_UNWIND_JIT && !EXITTRACE_VMSTATE)
825/* Determine trace number from pc of exit instruction. */ 825/* Determine trace number from pc of exit instruction. */
826static TraceNo trace_exit_find(jit_State *J, MCode *pc) 826static TraceNo trace_exit_find(jit_State *J, MCode *pc)
827{ 827{
@@ -843,10 +843,18 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
843 lua_State *L = J->L; 843 lua_State *L = J->L;
844 ExitState *ex = (ExitState *)exptr; 844 ExitState *ex = (ExitState *)exptr;
845 ExitDataCP exd; 845 ExitDataCP exd;
846 int errcode; 846 int errcode, exitcode = J->exitcode;
847 TValue exiterr;
847 const BCIns *pc; 848 const BCIns *pc;
848 void *cf; 849 void *cf;
849 GCtrace *T; 850 GCtrace *T;
851
852 setnilV(&exiterr);
853 if (exitcode) { /* Trace unwound with error code. */
854 J->exitcode = 0;
855 copyTV(L, &exiterr, L->top-1);
856 }
857
850#ifdef EXITSTATE_PCREG 858#ifdef EXITSTATE_PCREG
851 J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]); 859 J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
852#endif 860#endif
@@ -866,6 +874,8 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
866 if (errcode) 874 if (errcode)
867 return -errcode; /* Return negated error code. */ 875 return -errcode; /* Return negated error code. */
868 876
877 if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */
878
869 if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE))) 879 if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)))
870 lj_vmevent_send(L, TEXIT, 880 lj_vmevent_send(L, TEXIT,
871 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); 881 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
@@ -877,7 +887,9 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
877 pc = exd.pc; 887 pc = exd.pc;
878 cf = cframe_raw(L->cframe); 888 cf = cframe_raw(L->cframe);
879 setcframe_pc(cf, pc); 889 setcframe_pc(cf, pc);
880 if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) { 890 if (exitcode) {
891 return -exitcode;
892 } else if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) {
881 /* Just exit to interpreter. */ 893 /* Just exit to interpreter. */
882 } else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) { 894 } else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
883 if (!(G(L)->hookmask & HOOK_GC)) 895 if (!(G(L)->hookmask & HOOK_GC))
@@ -915,4 +927,41 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
915 } 927 }
916} 928}
917 929
930#if LJ_UNWIND_JIT
931/* Given an mcode address determine trace exit address for unwinding. */
932uintptr_t LJ_FASTCALL lj_trace_unwind(jit_State *J, uintptr_t addr, ExitNo *ep)
933{
934#if EXITTRACE_VMSTATE
935 TraceNo traceno = J2G(J)->vmstate;
936#else
937 TraceNo traceno = trace_exit_find(J, (MCode *)addr);
938#endif
939 GCtrace *T = traceref(J, traceno);
940 if (T
941#if EXITTRACE_VMSTATE
942 && addr >= (uintptr_t)T->mcode && addr < (uintptr_t)T->mcode + T->szmcode
943#endif
944 ) {
945 SnapShot *snap = T->snap;
946 SnapNo lo = 0, exitno = T->nsnap;
947 uintptr_t ofs = (uintptr_t)((MCode *)addr - T->mcode); /* MCode units! */
948 /* Rightmost binary search for mcode offset to determine exit number. */
949 do {
950 SnapNo mid = (lo+exitno) >> 1;
951 if (ofs < snap[mid].mcofs) exitno = mid; else lo = mid + 1;
952 } while (lo < exitno);
953 exitno--;
954 *ep = exitno;
955#ifdef EXITSTUBS_PER_GROUP
956 return (uintptr_t)exitstub_addr(J, exitno);
957#else
958 return (uintptr_t)exitstub_trace_addr(T, exitno);
959#endif
960 }
961 /* Cannot correlate addr with trace/exit. This will be fatal. */
962 lj_assertJ(0, "bad exit pc");
963 return 0;
964}
965#endif
966
918#endif 967#endif