diff options
| author | Mike Pall <mike> | 2015-08-20 01:10:30 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2015-08-20 01:10:30 +0200 |
| commit | 8715ae65c1f70f2402b89a004b88ab04ca103625 (patch) | |
| tree | 39fac0803294ff5c45e9ba51c71e016efc42fb5a | |
| parent | 424940ffc3fbc0b158cb95875a70accd49c04d30 (diff) | |
| download | luajit-8715ae65c1f70f2402b89a004b88ab04ca103625.tar.gz luajit-8715ae65c1f70f2402b89a004b88ab04ca103625.tar.bz2 luajit-8715ae65c1f70f2402b89a004b88ab04ca103625.zip | |
Properly handle OOM in trace_save().
Thanks to Vyacheslav Egorov.
| -rw-r--r-- | src/lj_trace.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c index e51ec546..7d1b0936 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -117,15 +117,22 @@ static void perftools_addtrace(GCtrace *T) | |||
| 117 | } | 117 | } |
| 118 | #endif | 118 | #endif |
| 119 | 119 | ||
| 120 | /* Save current trace by copying and compacting it. */ | 120 | /* Allocate space for copy of trace. */ |
| 121 | static void trace_save(jit_State *J) | 121 | static GCtrace *trace_save_alloc(jit_State *J) |
| 122 | { | 122 | { |
| 123 | size_t sztr = ((sizeof(GCtrace)+7)&~7); | 123 | size_t sztr = ((sizeof(GCtrace)+7)&~7); |
| 124 | size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); | 124 | size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); |
| 125 | size_t sz = sztr + szins + | 125 | size_t sz = sztr + szins + |
| 126 | J->cur.nsnap*sizeof(SnapShot) + | 126 | J->cur.nsnap*sizeof(SnapShot) + |
| 127 | J->cur.nsnapmap*sizeof(SnapEntry); | 127 | J->cur.nsnapmap*sizeof(SnapEntry); |
| 128 | GCtrace *T = lj_mem_newt(J->L, (MSize)sz, GCtrace); | 128 | return lj_mem_newt(J->L, (MSize)sz, GCtrace); |
| 129 | } | ||
| 130 | |||
| 131 | /* Save current trace by copying and compacting it. */ | ||
| 132 | static void trace_save(jit_State *J, GCtrace *T) | ||
| 133 | { | ||
| 134 | size_t sztr = ((sizeof(GCtrace)+7)&~7); | ||
| 135 | size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); | ||
| 129 | char *p = (char *)T + sztr; | 136 | char *p = (char *)T + sztr; |
| 130 | memcpy(T, &J->cur, sizeof(GCtrace)); | 137 | memcpy(T, &J->cur, sizeof(GCtrace)); |
| 131 | setgcrefr(T->nextgc, J2G(J)->gc.root); | 138 | setgcrefr(T->nextgc, J2G(J)->gc.root); |
| @@ -417,6 +424,7 @@ static void trace_stop(jit_State *J) | |||
| 417 | BCOp op = bc_op(J->cur.startins); | 424 | BCOp op = bc_op(J->cur.startins); |
| 418 | GCproto *pt = &gcref(J->cur.startpt)->pt; | 425 | GCproto *pt = &gcref(J->cur.startpt)->pt; |
| 419 | TraceNo traceno = J->cur.traceno; | 426 | TraceNo traceno = J->cur.traceno; |
| 427 | GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */ | ||
| 420 | lua_State *L; | 428 | lua_State *L; |
| 421 | 429 | ||
| 422 | switch (op) { | 430 | switch (op) { |
| @@ -461,7 +469,7 @@ static void trace_stop(jit_State *J) | |||
| 461 | /* Commit new mcode only after all patching is done. */ | 469 | /* Commit new mcode only after all patching is done. */ |
| 462 | lj_mcode_commit(J, J->cur.mcode); | 470 | lj_mcode_commit(J, J->cur.mcode); |
| 463 | J->postproc = LJ_POST_NONE; | 471 | J->postproc = LJ_POST_NONE; |
| 464 | trace_save(J); | 472 | trace_save(J, T); |
| 465 | 473 | ||
| 466 | L = J->L; | 474 | L = J->L; |
| 467 | lj_vmevent_send(L, TRACE, | 475 | lj_vmevent_send(L, TRACE, |
