Handle on-trace OOM errors from helper functions.

This commit is contained in:
Mike Pall
2021-03-23 00:35:46 +01:00
parent ddd0fd8f37
commit a32aeadc68
24 changed files with 421 additions and 51 deletions

View File

@@ -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