Properly handle OOM in trace_save().

Thanks to Vyacheslav Egorov.
This commit is contained in:
Mike Pall 2015-08-20 01:10:30 +02:00
parent 424940ffc3
commit 8715ae65c1

View File

@ -117,15 +117,22 @@ static void perftools_addtrace(GCtrace *T)
} }
#endif #endif
/* Save current trace by copying and compacting it. */ /* Allocate space for copy of trace. */
static void trace_save(jit_State *J) static GCtrace *trace_save_alloc(jit_State *J)
{ {
size_t sztr = ((sizeof(GCtrace)+7)&~7); size_t sztr = ((sizeof(GCtrace)+7)&~7);
size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
size_t sz = sztr + szins + size_t sz = sztr + szins +
J->cur.nsnap*sizeof(SnapShot) + J->cur.nsnap*sizeof(SnapShot) +
J->cur.nsnapmap*sizeof(SnapEntry); J->cur.nsnapmap*sizeof(SnapEntry);
GCtrace *T = lj_mem_newt(J->L, (MSize)sz, GCtrace); return lj_mem_newt(J->L, (MSize)sz, GCtrace);
}
/* Save current trace by copying and compacting it. */
static void trace_save(jit_State *J, GCtrace *T)
{
size_t sztr = ((sizeof(GCtrace)+7)&~7);
size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
char *p = (char *)T + sztr; char *p = (char *)T + sztr;
memcpy(T, &J->cur, sizeof(GCtrace)); memcpy(T, &J->cur, sizeof(GCtrace));
setgcrefr(T->nextgc, J2G(J)->gc.root); setgcrefr(T->nextgc, J2G(J)->gc.root);
@ -417,6 +424,7 @@ static void trace_stop(jit_State *J)
BCOp op = bc_op(J->cur.startins); BCOp op = bc_op(J->cur.startins);
GCproto *pt = &gcref(J->cur.startpt)->pt; GCproto *pt = &gcref(J->cur.startpt)->pt;
TraceNo traceno = J->cur.traceno; TraceNo traceno = J->cur.traceno;
GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */
lua_State *L; lua_State *L;
switch (op) { switch (op) {
@ -461,7 +469,7 @@ static void trace_stop(jit_State *J)
/* Commit new mcode only after all patching is done. */ /* Commit new mcode only after all patching is done. */
lj_mcode_commit(J, J->cur.mcode); lj_mcode_commit(J, J->cur.mcode);
J->postproc = LJ_POST_NONE; J->postproc = LJ_POST_NONE;
trace_save(J); trace_save(J, T);
L = J->L; L = J->L;
lj_vmevent_send(L, TRACE, lj_vmevent_send(L, TRACE,