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 /src | |
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.
Diffstat (limited to 'src')
-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, |