Handle on-trace OOM errors from helper functions.
This commit is contained in:
@@ -821,7 +821,7 @@ static void trace_exit_regs(lua_State *L, ExitState *ex)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EXITSTATE_PCREG
|
||||
#if defined(EXITSTATE_PCREG) || (LJ_UNWIND_JIT && !EXITTRACE_VMSTATE)
|
||||
/* Determine trace number from pc of exit instruction. */
|
||||
static TraceNo trace_exit_find(jit_State *J, MCode *pc)
|
||||
{
|
||||
@@ -843,10 +843,18 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
||||
lua_State *L = J->L;
|
||||
ExitState *ex = (ExitState *)exptr;
|
||||
ExitDataCP exd;
|
||||
int errcode;
|
||||
int errcode, exitcode = J->exitcode;
|
||||
TValue exiterr;
|
||||
const BCIns *pc;
|
||||
void *cf;
|
||||
GCtrace *T;
|
||||
|
||||
setnilV(&exiterr);
|
||||
if (exitcode) { /* Trace unwound with error code. */
|
||||
J->exitcode = 0;
|
||||
copyTV(L, &exiterr, L->top-1);
|
||||
}
|
||||
|
||||
#ifdef EXITSTATE_PCREG
|
||||
J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
|
||||
#endif
|
||||
@@ -866,6 +874,8 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
||||
if (errcode)
|
||||
return -errcode; /* Return negated error code. */
|
||||
|
||||
if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */
|
||||
|
||||
if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)))
|
||||
lj_vmevent_send(L, TEXIT,
|
||||
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)
|
||||
pc = exd.pc;
|
||||
cf = cframe_raw(L->cframe);
|
||||
setcframe_pc(cf, pc);
|
||||
if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) {
|
||||
if (exitcode) {
|
||||
return -exitcode;
|
||||
} else if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) {
|
||||
/* Just exit to interpreter. */
|
||||
} else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
|
||||
if (!(G(L)->hookmask & HOOK_GC))
|
||||
@@ -915,4 +927,41 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
||||
}
|
||||
}
|
||||
|
||||
#if LJ_UNWIND_JIT
|
||||
/* Given an mcode address determine trace exit address for unwinding. */
|
||||
uintptr_t LJ_FASTCALL lj_trace_unwind(jit_State *J, uintptr_t addr, ExitNo *ep)
|
||||
{
|
||||
#if EXITTRACE_VMSTATE
|
||||
TraceNo traceno = J2G(J)->vmstate;
|
||||
#else
|
||||
TraceNo traceno = trace_exit_find(J, (MCode *)addr);
|
||||
#endif
|
||||
GCtrace *T = traceref(J, traceno);
|
||||
if (T
|
||||
#if EXITTRACE_VMSTATE
|
||||
&& addr >= (uintptr_t)T->mcode && addr < (uintptr_t)T->mcode + T->szmcode
|
||||
#endif
|
||||
) {
|
||||
SnapShot *snap = T->snap;
|
||||
SnapNo lo = 0, exitno = T->nsnap;
|
||||
uintptr_t ofs = (uintptr_t)((MCode *)addr - T->mcode); /* MCode units! */
|
||||
/* Rightmost binary search for mcode offset to determine exit number. */
|
||||
do {
|
||||
SnapNo mid = (lo+exitno) >> 1;
|
||||
if (ofs < snap[mid].mcofs) exitno = mid; else lo = mid + 1;
|
||||
} while (lo < exitno);
|
||||
exitno--;
|
||||
*ep = exitno;
|
||||
#ifdef EXITSTUBS_PER_GROUP
|
||||
return (uintptr_t)exitstub_addr(J, exitno);
|
||||
#else
|
||||
return (uintptr_t)exitstub_trace_addr(T, exitno);
|
||||
#endif
|
||||
}
|
||||
/* Cannot correlate addr with trace/exit. This will be fatal. */
|
||||
lj_assertJ(0, "bad exit pc");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user