diff options
| author | Mike Pall <mike> | 2010-04-25 13:53:33 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-04-25 13:53:33 +0200 |
| commit | 2e24770ed3241342a6a5896e05629a382d35262b (patch) | |
| tree | fc990e0c403375fe16e8a017da1d2c277ffa2436 /src | |
| parent | 721b73fecbbeda5b5cb76628511c5b3fac41eb4d (diff) | |
| download | luajit-2e24770ed3241342a6a5896e05629a382d35262b.tar.gz luajit-2e24770ed3241342a6a5896e05629a382d35262b.tar.bz2 luajit-2e24770ed3241342a6a5896e05629a382d35262b.zip | |
Simplify management of current trace. Drop lazy save.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_asm.c | 4 | ||||
| -rw-r--r-- | src/lj_gc.c | 23 | ||||
| -rw-r--r-- | src/lj_gdbjit.c | 4 | ||||
| -rw-r--r-- | src/lj_gdbjit.h | 4 | ||||
| -rw-r--r-- | src/lj_jit.h | 1 | ||||
| -rw-r--r-- | src/lj_record.c | 12 | ||||
| -rw-r--r-- | src/lj_trace.c | 111 |
7 files changed, 80 insertions, 79 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 5c564748..985f0cef 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
| @@ -3029,7 +3029,7 @@ static void asm_head_root(ASMState *as) | |||
| 3029 | { | 3029 | { |
| 3030 | int32_t spadj; | 3030 | int32_t spadj; |
| 3031 | asm_head_root_base(as); | 3031 | asm_head_root_base(as); |
| 3032 | emit_setgli(as, vmstate, (int32_t)as->J->curtrace); | 3032 | emit_setgli(as, vmstate, (int32_t)as->T->traceno); |
| 3033 | spadj = asm_stack_adjust(as); | 3033 | spadj = asm_stack_adjust(as); |
| 3034 | as->T->spadjust = (uint16_t)spadj; | 3034 | as->T->spadjust = (uint16_t)spadj; |
| 3035 | emit_addptr(as, RID_ESP|REX_64, -spadj); | 3035 | emit_addptr(as, RID_ESP|REX_64, -spadj); |
| @@ -3145,7 +3145,7 @@ static void asm_head_side(ASMState *as) | |||
| 3145 | } | 3145 | } |
| 3146 | 3146 | ||
| 3147 | /* Store trace number and adjust stack frame relative to the parent. */ | 3147 | /* Store trace number and adjust stack frame relative to the parent. */ |
| 3148 | emit_setgli(as, vmstate, (int32_t)as->J->curtrace); | 3148 | emit_setgli(as, vmstate, (int32_t)as->T->traceno); |
| 3149 | emit_addptr(as, RID_ESP|REX_64, -spdelta); | 3149 | emit_addptr(as, RID_ESP|REX_64, -spdelta); |
| 3150 | 3150 | ||
| 3151 | /* Restore target registers from parent spill slots. */ | 3151 | /* Restore target registers from parent spill slots. */ |
diff --git a/src/lj_gc.c b/src/lj_gc.c index 7c224759..bd31eabf 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c | |||
| @@ -217,13 +217,12 @@ static void gc_traverse_func(global_State *g, GCfunc *fn) | |||
| 217 | /* Mark a trace. */ | 217 | /* Mark a trace. */ |
| 218 | static void gc_marktrace(global_State *g, TraceNo traceno) | 218 | static void gc_marktrace(global_State *g, TraceNo traceno) |
| 219 | { | 219 | { |
| 220 | if (traceno && traceno != G2J(g)->curtrace) { | 220 | GCobj *o = obj2gco(traceref(G2J(g), traceno)); |
| 221 | GCobj *o = obj2gco(traceref(G2J(g), traceno)); | 221 | lua_assert(traceno != G2J(g)->cur.traceno); |
| 222 | if (iswhite(o)) { | 222 | if (iswhite(o)) { |
| 223 | white2gray(o); | 223 | white2gray(o); |
| 224 | setgcrefr(o->gch.gclist, g->gc.gray); | 224 | setgcrefr(o->gch.gclist, g->gc.gray); |
| 225 | setgcref(g->gc.gray, o); | 225 | setgcref(g->gc.gray, o); |
| 226 | } | ||
| 227 | } | 226 | } |
| 228 | } | 227 | } |
| 229 | 228 | ||
| @@ -236,15 +235,15 @@ static void gc_traverse_trace(global_State *g, GCtrace *T) | |||
| 236 | if (ir->o == IR_KGC) | 235 | if (ir->o == IR_KGC) |
| 237 | gc_markobj(g, ir_kgc(ir)); | 236 | gc_markobj(g, ir_kgc(ir)); |
| 238 | } | 237 | } |
| 239 | gc_marktrace(g, T->link); | 238 | if (T->link) gc_marktrace(g, T->link); |
| 240 | gc_marktrace(g, T->nextroot); | 239 | if (T->nextroot) gc_marktrace(g, T->nextroot); |
| 241 | gc_marktrace(g, T->nextside); | 240 | if (T->nextside) gc_marktrace(g, T->nextside); |
| 242 | gc_markobj(g, gcref(T->startpt)); | 241 | gc_markobj(g, gcref(T->startpt)); |
| 243 | } | 242 | } |
| 244 | 243 | ||
| 245 | /* The current trace is a GC root while not anchored in the prototype (yet). */ | 244 | /* The current trace is a GC root while not anchored in the prototype (yet). */ |
| 246 | #define gc_traverse_curtrace(g) \ | 245 | #define gc_traverse_curtrace(g) \ |
| 247 | { if (G2J(g)->curtrace != 0) gc_traverse_trace(g, &G2J(g)->cur); } | 246 | { if (G2J(g)->cur.traceno != 0) gc_traverse_trace(g, &G2J(g)->cur); } |
| 248 | #else | 247 | #else |
| 249 | #define gc_traverse_curtrace(g) UNUSED(g) | 248 | #define gc_traverse_curtrace(g) UNUSED(g) |
| 250 | #endif | 249 | #endif |
| @@ -261,7 +260,7 @@ static void gc_traverse_proto(global_State *g, GCproto *pt) | |||
| 261 | for (i = 0; i < (ptrdiff_t)pt->sizevarinfo; i++) /* Mark names of locals. */ | 260 | for (i = 0; i < (ptrdiff_t)pt->sizevarinfo; i++) /* Mark names of locals. */ |
| 262 | gc_mark_str(gco2str(gcref(proto_varinfo(pt)[i].name))); | 261 | gc_mark_str(gco2str(gcref(proto_varinfo(pt)[i].name))); |
| 263 | #if LJ_HASJIT | 262 | #if LJ_HASJIT |
| 264 | gc_marktrace(g, pt->trace); | 263 | if (pt->trace) gc_marktrace(g, pt->trace); |
| 265 | #endif | 264 | #endif |
| 266 | } | 265 | } |
| 267 | 266 | ||
diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c index d66ef455..dc85c076 100644 --- a/src/lj_gdbjit.c +++ b/src/lj_gdbjit.c | |||
| @@ -698,7 +698,7 @@ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) | |||
| 698 | } | 698 | } |
| 699 | 699 | ||
| 700 | /* Add debug info for newly compiled trace and notify GDB. */ | 700 | /* Add debug info for newly compiled trace and notify GDB. */ |
| 701 | void lj_gdbjit_addtrace(jit_State *J, GCtrace *T, TraceNo traceno) | 701 | void lj_gdbjit_addtrace(jit_State *J, GCtrace *T) |
| 702 | { | 702 | { |
| 703 | GDBJITctx ctx; | 703 | GDBJITctx ctx; |
| 704 | lua_State *L = J->L; | 704 | lua_State *L = J->L; |
| @@ -721,7 +721,7 @@ void lj_gdbjit_addtrace(jit_State *J, GCtrace *T, TraceNo traceno) | |||
| 721 | ctx.filename++; | 721 | ctx.filename++; |
| 722 | else | 722 | else |
| 723 | ctx.filename = "(string)"; | 723 | ctx.filename = "(string)"; |
| 724 | ctx.trname = lj_str_pushf(L, "TRACE_%d", traceno); | 724 | ctx.trname = lj_str_pushf(L, "TRACE_%d", T->traceno); |
| 725 | L->top--; | 725 | L->top--; |
| 726 | gdbjit_buildobj(&ctx); | 726 | gdbjit_buildobj(&ctx); |
| 727 | gdbjit_newentry(L, &ctx); | 727 | gdbjit_newentry(L, &ctx); |
diff --git a/src/lj_gdbjit.h b/src/lj_gdbjit.h index 037d3344..7824885b 100644 --- a/src/lj_gdbjit.h +++ b/src/lj_gdbjit.h | |||
| @@ -11,11 +11,11 @@ | |||
| 11 | 11 | ||
| 12 | #if LJ_HASJIT && defined(LUAJIT_USE_GDBJIT) | 12 | #if LJ_HASJIT && defined(LUAJIT_USE_GDBJIT) |
| 13 | 13 | ||
| 14 | LJ_FUNC void lj_gdbjit_addtrace(jit_State *J, GCtrace *T, TraceNo traceno); | 14 | LJ_FUNC void lj_gdbjit_addtrace(jit_State *J, GCtrace *T); |
| 15 | LJ_FUNC void lj_gdbjit_deltrace(jit_State *J, GCtrace *T); | 15 | LJ_FUNC void lj_gdbjit_deltrace(jit_State *J, GCtrace *T); |
| 16 | 16 | ||
| 17 | #else | 17 | #else |
| 18 | #define lj_gdbjit_addtrace(J, T, tn) UNUSED(T) | 18 | #define lj_gdbjit_addtrace(J, T) UNUSED(T) |
| 19 | #define lj_gdbjit_deltrace(J, T) UNUSED(T) | 19 | #define lj_gdbjit_deltrace(J, T) UNUSED(T) |
| 20 | #endif | 20 | #endif |
| 21 | 21 | ||
diff --git a/src/lj_jit.h b/src/lj_jit.h index 332596f0..be85ecfe 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
| @@ -284,7 +284,6 @@ typedef struct jit_State { | |||
| 284 | SnapEntry *snapmapbuf; /* Temp. snapshot map buffer. */ | 284 | SnapEntry *snapmapbuf; /* Temp. snapshot map buffer. */ |
| 285 | MSize sizesnapmap; /* Size of temp. snapshot map buffer. */ | 285 | MSize sizesnapmap; /* Size of temp. snapshot map buffer. */ |
| 286 | 286 | ||
| 287 | TraceNo curtrace; /* Current trace number (if not 0). Kept in J->cur. */ | ||
| 288 | GCRef *trace; /* Array of traces. */ | 287 | GCRef *trace; /* Array of traces. */ |
| 289 | TraceNo freetrace; /* Start of scan for next free trace. */ | 288 | TraceNo freetrace; /* Start of scan for next free trace. */ |
| 290 | MSize sizetrace; /* Size of trace array. */ | 289 | MSize sizetrace; /* Size of trace array. */ |
diff --git a/src/lj_record.c b/src/lj_record.c index a3f5b9c0..c71aa1a4 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -232,7 +232,7 @@ static void rec_stop(jit_State *J, TraceNo lnk) | |||
| 232 | lj_trace_end(J); | 232 | lj_trace_end(J); |
| 233 | J->cur.link = (uint16_t)lnk; | 233 | J->cur.link = (uint16_t)lnk; |
| 234 | /* Looping back at the same stack level? */ | 234 | /* Looping back at the same stack level? */ |
| 235 | if (lnk == J->curtrace && J->framedepth + J->retdepth == 0) { | 235 | if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) { |
| 236 | if ((J->flags & JIT_F_OPT_LOOP)) /* Shall we try to create a loop? */ | 236 | if ((J->flags & JIT_F_OPT_LOOP)) /* Shall we try to create a loop? */ |
| 237 | goto nocanon; /* Do not canonicalize or we lose the narrowing. */ | 237 | goto nocanon; /* Do not canonicalize or we lose the narrowing. */ |
| 238 | if (J->cur.root) /* Otherwise ensure we always link to the root trace. */ | 238 | if (J->cur.root) /* Otherwise ensure we always link to the root trace. */ |
| @@ -442,7 +442,7 @@ static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev) | |||
| 442 | /* Same loop? */ | 442 | /* Same loop? */ |
| 443 | if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */ | 443 | if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */ |
| 444 | lj_trace_err(J, LJ_TRERR_LLEAVE); | 444 | lj_trace_err(J, LJ_TRERR_LLEAVE); |
| 445 | rec_stop(J, J->curtrace); /* Root trace forms a loop. */ | 445 | rec_stop(J, J->cur.traceno); /* Root trace forms a loop. */ |
| 446 | } else if (ev != LOOPEV_LEAVE) { /* Entering inner loop? */ | 446 | } else if (ev != LOOPEV_LEAVE) { /* Entering inner loop? */ |
| 447 | /* It's usually better to abort here and wait until the inner loop | 447 | /* It's usually better to abort here and wait until the inner loop |
| 448 | ** is traced. But if the inner loop repeatedly didn't loop back, | 448 | ** is traced. But if the inner loop repeatedly didn't loop back, |
| @@ -472,7 +472,7 @@ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev) | |||
| 472 | } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */ | 472 | } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */ |
| 473 | J->instunroll = 0; /* Cannot continue across a compiled loop op. */ | 473 | J->instunroll = 0; /* Cannot continue across a compiled loop op. */ |
| 474 | if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) | 474 | if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) |
| 475 | lnk = J->curtrace; /* Can form an extra loop. */ | 475 | lnk = J->cur.traceno; /* Can form an extra loop. */ |
| 476 | rec_stop(J, lnk); /* Link to the loop. */ | 476 | rec_stop(J, lnk); /* Link to the loop. */ |
| 477 | } /* Side trace continues across a loop that's left or not entered. */ | 477 | } /* Side trace continues across a loop that's left or not entered. */ |
| 478 | } | 478 | } |
| @@ -578,7 +578,7 @@ static void rec_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
| 578 | if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) { | 578 | if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) { |
| 579 | if (check_downrec_unroll(J, pt)) { | 579 | if (check_downrec_unroll(J, pt)) { |
| 580 | J->maxslot = (BCReg)(rbase + nresults); | 580 | J->maxslot = (BCReg)(rbase + nresults); |
| 581 | rec_stop(J, J->curtrace); /* Down-recursion. */ | 581 | rec_stop(J, J->cur.traceno); /* Down-recursion. */ |
| 582 | return; | 582 | return; |
| 583 | } | 583 | } |
| 584 | lj_snap_add(J); | 584 | lj_snap_add(J); |
| @@ -1836,7 +1836,7 @@ static void check_call_unroll(jit_State *J) | |||
| 1836 | if (J->pc == J->startpc) { | 1836 | if (J->pc == J->startpc) { |
| 1837 | if (count + J->tailcalled > J->param[JIT_P_recunroll]) { | 1837 | if (count + J->tailcalled > J->param[JIT_P_recunroll]) { |
| 1838 | J->pc++; | 1838 | J->pc++; |
| 1839 | rec_stop(J, J->curtrace); /* Up-recursion or tail-recursion. */ | 1839 | rec_stop(J, J->cur.traceno); /* Up-recursion or tail-recursion. */ |
| 1840 | } | 1840 | } |
| 1841 | } else { | 1841 | } else { |
| 1842 | if (count > J->param[JIT_P_callunroll]) | 1842 | if (count > J->param[JIT_P_callunroll]) |
| @@ -1874,7 +1874,7 @@ static void rec_func_jit(jit_State *J, TraceNo lnk) | |||
| 1874 | rec_func_setup(J); | 1874 | rec_func_setup(J); |
| 1875 | J->instunroll = 0; /* Cannot continue across a compiled function. */ | 1875 | J->instunroll = 0; /* Cannot continue across a compiled function. */ |
| 1876 | if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) | 1876 | if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) |
| 1877 | lnk = J->curtrace; /* Can form an extra tail-recursive loop. */ | 1877 | lnk = J->cur.traceno; /* Can form an extra tail-recursive loop. */ |
| 1878 | rec_stop(J, lnk); /* Link to the function. */ | 1878 | rec_stop(J, lnk); /* Link to the function. */ |
| 1879 | } | 1879 | } |
| 1880 | 1880 | ||
diff --git a/src/lj_trace.c b/src/lj_trace.c index 4c9c4669..8419c9bb 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -50,9 +50,9 @@ void lj_trace_err_info(jit_State *J, TraceError e) | |||
| 50 | /* -- Trace management ---------------------------------------------------- */ | 50 | /* -- Trace management ---------------------------------------------------- */ |
| 51 | 51 | ||
| 52 | /* The current trace is first assembled in J->cur. The variable length | 52 | /* The current trace is first assembled in J->cur. The variable length |
| 53 | ** arrays point to shared, growable buffers (J->irbuf etc.). The trace is | 53 | ** arrays point to shared, growable buffers (J->irbuf etc.). When trace |
| 54 | ** kept in this state until a new trace needs to be created. Then the current | 54 | ** recording ends successfully, the current trace and its data structures |
| 55 | ** trace and its data structures are copied to a new (compact) GCtrace object. | 55 | ** are copied to a new (compact) GCtrace object. |
| 56 | */ | 56 | */ |
| 57 | 57 | ||
| 58 | /* Find a free trace number. */ | 58 | /* Find a free trace number. */ |
| @@ -76,32 +76,35 @@ static TraceNo trace_findfree(jit_State *J) | |||
| 76 | return J->freetrace; | 76 | return J->freetrace; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | #define TRACE_COPYELEM(field, szfield, tp) \ | 79 | #define TRACE_APPENDVEC(field, szfield, tp) \ |
| 80 | T2->field = (tp *)p; \ | 80 | T->field = (tp *)p; \ |
| 81 | memcpy(p, T->field, T->szfield*sizeof(tp)); \ | 81 | memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \ |
| 82 | p += T->szfield*sizeof(tp); | 82 | p += J->cur.szfield*sizeof(tp); |
| 83 | 83 | ||
| 84 | /* Save a trace by copying and compacting it. */ | 84 | /* Save current trace by copying and compacting it. */ |
| 85 | static GCtrace *trace_save(jit_State *J, GCtrace *T) | 85 | static void trace_save(jit_State *J) |
| 86 | { | 86 | { |
| 87 | size_t sztr = ((sizeof(GCtrace)+7)&~7); | 87 | size_t sztr = ((sizeof(GCtrace)+7)&~7); |
| 88 | size_t szins = (T->nins-T->nk)*sizeof(IRIns); | 88 | size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); |
| 89 | size_t sz = sztr + szins + | 89 | size_t sz = sztr + szins + |
| 90 | T->nsnap*sizeof(SnapShot) + | 90 | J->cur.nsnap*sizeof(SnapShot) + |
| 91 | T->nsnapmap*sizeof(SnapEntry); | 91 | J->cur.nsnapmap*sizeof(SnapEntry); |
| 92 | GCtrace *T2 = lj_mem_newt(J->L, (MSize)sz, GCtrace); | 92 | GCtrace *T = lj_mem_newt(J->L, (MSize)sz, GCtrace); |
| 93 | char *p = (char *)T2 + sztr; | 93 | char *p = (char *)T + sztr; |
| 94 | memcpy(T2, T, sizeof(GCtrace)); | 94 | memcpy(T, &J->cur, sizeof(GCtrace)); |
| 95 | setgcrefr(T2->nextgc, J2G(J)->gc.root); | 95 | setgcrefr(T->nextgc, J2G(J)->gc.root); |
| 96 | setgcrefp(J2G(J)->gc.root, T2); | 96 | setgcrefp(J2G(J)->gc.root, T); |
| 97 | newwhite(J2G(J), T2); | 97 | newwhite(J2G(J), T); |
| 98 | T2->gct = ~LJ_TTRACE; | 98 | T->gct = ~LJ_TTRACE; |
| 99 | T2->ir = (IRIns *)p - T->nk; | 99 | T->ir = (IRIns *)p - J->cur.nk; |
| 100 | memcpy(p, T->ir+T->nk, szins); | 100 | memcpy(p, J->cur.ir+J->cur.nk, szins); |
| 101 | p += szins; | 101 | p += szins; |
| 102 | TRACE_COPYELEM(snap, nsnap, SnapShot) | 102 | TRACE_APPENDVEC(snap, nsnap, SnapShot) |
| 103 | TRACE_COPYELEM(snapmap, nsnapmap, SnapEntry) | 103 | TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) |
| 104 | return T2; | 104 | J->cur.traceno = 0; |
| 105 | setgcrefp(J->trace[T->traceno], T); | ||
| 106 | lj_gc_barriertrace(J2G(J), T->traceno); | ||
| 107 | lj_gdbjit_addtrace(J, T); | ||
| 105 | } | 108 | } |
| 106 | 109 | ||
| 107 | void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T) | 110 | void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T) |
| @@ -225,7 +228,7 @@ int lj_trace_flushall(lua_State *L) | |||
| 225 | setgcrefnull(J->trace[i]); | 228 | setgcrefnull(J->trace[i]); |
| 226 | } | 229 | } |
| 227 | } | 230 | } |
| 228 | J->curtrace = 0; | 231 | J->cur.traceno = 0; |
| 229 | J->freetrace = 0; | 232 | J->freetrace = 0; |
| 230 | /* Free the whole machine code and invalidate all exit stub groups. */ | 233 | /* Free the whole machine code and invalidate all exit stub groups. */ |
| 231 | lj_mcode_free(J); | 234 | lj_mcode_free(J); |
| @@ -254,13 +257,11 @@ void lj_trace_initstate(global_State *g) | |||
| 254 | void lj_trace_freestate(global_State *g) | 257 | void lj_trace_freestate(global_State *g) |
| 255 | { | 258 | { |
| 256 | jit_State *J = G2J(g); | 259 | jit_State *J = G2J(g); |
| 257 | if (J->curtrace) | ||
| 258 | lj_gdbjit_deltrace(J, &J->cur); | ||
| 259 | #ifdef LUA_USE_ASSERT | 260 | #ifdef LUA_USE_ASSERT |
| 260 | { /* This assumes all traces have already been freed. */ | 261 | { /* This assumes all traces have already been freed. */ |
| 261 | ptrdiff_t i; | 262 | ptrdiff_t i; |
| 262 | for (i = 1; i < (ptrdiff_t)J->sizetrace; i++) | 263 | for (i = 1; i < (ptrdiff_t)J->sizetrace; i++) |
| 263 | lua_assert(i == (ptrdiff_t)J->curtrace || traceref(J, i) == NULL); | 264 | lua_assert(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL); |
| 264 | } | 265 | } |
| 265 | #endif | 266 | #endif |
| 266 | lj_mcode_free(J); | 267 | lj_mcode_free(J); |
| @@ -311,13 +312,7 @@ setpenalty: | |||
| 311 | static void trace_start(jit_State *J) | 312 | static void trace_start(jit_State *J) |
| 312 | { | 313 | { |
| 313 | lua_State *L; | 314 | lua_State *L; |
| 314 | 315 | TraceNo traceno; | |
| 315 | if (J->curtrace != 0 && traceref(J, J->curtrace) == &J->cur) { | ||
| 316 | TraceNo tr = J->curtrace; /* Save current trace. */ | ||
| 317 | setgcrefp(J->trace[tr], trace_save(J, &J->cur)); | ||
| 318 | J->curtrace = 0; | ||
| 319 | lj_gc_barriertrace(J2G(J), tr); | ||
| 320 | } | ||
| 321 | 316 | ||
| 322 | if ((J->pt->flags & PROTO_NO_JIT)) { /* JIT disabled for this proto? */ | 317 | if ((J->pt->flags & PROTO_NO_JIT)) { /* JIT disabled for this proto? */ |
| 323 | if (J->parent == 0) { | 318 | if (J->parent == 0) { |
| @@ -332,18 +327,18 @@ static void trace_start(jit_State *J) | |||
| 332 | } | 327 | } |
| 333 | 328 | ||
| 334 | /* Get a new trace number. */ | 329 | /* Get a new trace number. */ |
| 335 | J->curtrace = trace_findfree(J); | 330 | traceno = trace_findfree(J); |
| 336 | if (LJ_UNLIKELY(J->curtrace == 0)) { /* No free trace? */ | 331 | if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */ |
| 337 | lua_assert((J2G(J)->hookmask & HOOK_GC) == 0); | 332 | lua_assert((J2G(J)->hookmask & HOOK_GC) == 0); |
| 338 | lj_trace_flushall(J->L); | 333 | lj_trace_flushall(J->L); |
| 339 | J->state = LJ_TRACE_IDLE; /* Silently ignored. */ | 334 | J->state = LJ_TRACE_IDLE; /* Silently ignored. */ |
| 340 | return; | 335 | return; |
| 341 | } | 336 | } |
| 342 | setgcrefp(J->trace[J->curtrace], &J->cur); | 337 | setgcrefp(J->trace[traceno], &J->cur); |
| 343 | 338 | ||
| 344 | /* Setup enough of the current trace to be able to send the vmevent. */ | 339 | /* Setup enough of the current trace to be able to send the vmevent. */ |
| 345 | memset(&J->cur, 0, sizeof(GCtrace)); | 340 | memset(&J->cur, 0, sizeof(GCtrace)); |
| 346 | J->cur.traceno = J->curtrace; | 341 | J->cur.traceno = traceno; |
| 347 | J->cur.nins = J->cur.nk = REF_BASE; | 342 | J->cur.nins = J->cur.nk = REF_BASE; |
| 348 | J->cur.ir = J->irbuf; | 343 | J->cur.ir = J->irbuf; |
| 349 | J->cur.snap = J->snapbuf; | 344 | J->cur.snap = J->snapbuf; |
| @@ -356,7 +351,7 @@ static void trace_start(jit_State *J) | |||
| 356 | L = J->L; | 351 | L = J->L; |
| 357 | lj_vmevent_send(L, TRACE, | 352 | lj_vmevent_send(L, TRACE, |
| 358 | setstrV(L, L->top++, lj_str_newlit(L, "start")); | 353 | setstrV(L, L->top++, lj_str_newlit(L, "start")); |
| 359 | setintV(L->top++, J->curtrace); | 354 | setintV(L->top++, traceno); |
| 360 | setfuncV(L, L->top++, J->fn); | 355 | setfuncV(L, L->top++, J->fn); |
| 361 | setintV(L->top++, proto_bcpos(J->pt, J->pc)); | 356 | setintV(L->top++, proto_bcpos(J->pt, J->pc)); |
| 362 | if (J->parent) { | 357 | if (J->parent) { |
| @@ -373,6 +368,7 @@ static void trace_stop(jit_State *J) | |||
| 373 | BCIns *pc = (BCIns *)J->startpc; /* Not const here. */ | 368 | BCIns *pc = (BCIns *)J->startpc; /* Not const here. */ |
| 374 | BCOp op = bc_op(J->cur.startins); | 369 | BCOp op = bc_op(J->cur.startins); |
| 375 | GCproto *pt = &gcref(J->cur.startpt)->pt; | 370 | GCproto *pt = &gcref(J->cur.startpt)->pt; |
| 371 | TraceNo traceno = J->cur.traceno; | ||
| 376 | lua_State *L; | 372 | lua_State *L; |
| 377 | 373 | ||
| 378 | switch (op) { | 374 | switch (op) { |
| @@ -384,16 +380,16 @@ static void trace_stop(jit_State *J) | |||
| 384 | case BC_FUNCF: | 380 | case BC_FUNCF: |
| 385 | /* Patch bytecode of starting instruction in root trace. */ | 381 | /* Patch bytecode of starting instruction in root trace. */ |
| 386 | setbc_op(pc, (int)op+(int)BC_JLOOP-(int)BC_LOOP); | 382 | setbc_op(pc, (int)op+(int)BC_JLOOP-(int)BC_LOOP); |
| 387 | setbc_d(pc, J->curtrace); | 383 | setbc_d(pc, traceno); |
| 388 | addroot: | 384 | addroot: |
| 389 | /* Add to root trace chain in prototype. */ | 385 | /* Add to root trace chain in prototype. */ |
| 390 | J->cur.nextroot = pt->trace; | 386 | J->cur.nextroot = pt->trace; |
| 391 | pt->trace = (TraceNo1)J->curtrace; | 387 | pt->trace = (TraceNo1)traceno; |
| 392 | break; | 388 | break; |
| 393 | case BC_RET: | 389 | case BC_RET: |
| 394 | case BC_RET0: | 390 | case BC_RET0: |
| 395 | case BC_RET1: | 391 | case BC_RET1: |
| 396 | *pc = BCINS_AD(BC_JLOOP, J->cur.snap[0].nslots, J->curtrace); | 392 | *pc = BCINS_AD(BC_JLOOP, J->cur.snap[0].nslots, traceno); |
| 397 | goto addroot; | 393 | goto addroot; |
| 398 | case BC_JMP: | 394 | case BC_JMP: |
| 399 | /* Patch exit branch in parent to side trace entry. */ | 395 | /* Patch exit branch in parent to side trace entry. */ |
| @@ -406,7 +402,7 @@ static void trace_stop(jit_State *J) | |||
| 406 | GCtrace *root = traceref(J, J->cur.root); | 402 | GCtrace *root = traceref(J, J->cur.root); |
| 407 | root->nchild++; | 403 | root->nchild++; |
| 408 | J->cur.nextside = root->nextside; | 404 | J->cur.nextside = root->nextside; |
| 409 | root->nextside = (TraceNo1)J->curtrace; | 405 | root->nextside = (TraceNo1)traceno; |
| 410 | } | 406 | } |
| 411 | break; | 407 | break; |
| 412 | default: | 408 | default: |
| @@ -416,12 +412,12 @@ static void trace_stop(jit_State *J) | |||
| 416 | 412 | ||
| 417 | /* Commit new mcode only after all patching is done. */ | 413 | /* Commit new mcode only after all patching is done. */ |
| 418 | lj_mcode_commit(J, J->cur.mcode); | 414 | lj_mcode_commit(J, J->cur.mcode); |
| 419 | lj_gdbjit_addtrace(J, &J->cur, J->curtrace); | 415 | trace_save(J); |
| 420 | 416 | ||
| 421 | L = J->L; | 417 | L = J->L; |
| 422 | lj_vmevent_send(L, TRACE, | 418 | lj_vmevent_send(L, TRACE, |
| 423 | setstrV(L, L->top++, lj_str_newlit(L, "stop")); | 419 | setstrV(L, L->top++, lj_str_newlit(L, "stop")); |
| 424 | setintV(L->top++, J->curtrace); | 420 | setintV(L->top++, traceno); |
| 425 | ); | 421 | ); |
| 426 | } | 422 | } |
| 427 | 423 | ||
| @@ -445,6 +441,8 @@ static int trace_abort(jit_State *J) | |||
| 445 | { | 441 | { |
| 446 | lua_State *L = J->L; | 442 | lua_State *L = J->L; |
| 447 | TraceError e = LJ_TRERR_RECERR; | 443 | TraceError e = LJ_TRERR_RECERR; |
| 444 | TraceNo traceno; | ||
| 445 | |||
| 448 | lj_mcode_abort(J); | 446 | lj_mcode_abort(J); |
| 449 | if (tvisnum(L->top-1)) | 447 | if (tvisnum(L->top-1)) |
| 450 | e = (TraceError)lj_num2int(numV(L->top-1)); | 448 | e = (TraceError)lj_num2int(numV(L->top-1)); |
| @@ -455,14 +453,18 @@ static int trace_abort(jit_State *J) | |||
| 455 | /* Penalize or blacklist starting bytecode instruction. */ | 453 | /* Penalize or blacklist starting bytecode instruction. */ |
| 456 | if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) | 454 | if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) |
| 457 | penalty_pc(J, &gcref(J->cur.startpt)->pt, (BCIns *)J->startpc, e); | 455 | penalty_pc(J, &gcref(J->cur.startpt)->pt, (BCIns *)J->startpc, e); |
| 458 | if (J->curtrace) { /* Is there anything to abort? */ | 456 | |
| 457 | /* Is there anything to abort? */ | ||
| 458 | traceno = J->cur.traceno; | ||
| 459 | if (traceno) { | ||
| 459 | ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */ | 460 | ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */ |
| 461 | J->cur.link = 0; | ||
| 460 | lj_vmevent_send(L, TRACE, | 462 | lj_vmevent_send(L, TRACE, |
| 461 | TValue *frame; | 463 | TValue *frame; |
| 462 | const BCIns *pc; | 464 | const BCIns *pc; |
| 463 | GCfunc *fn; | 465 | GCfunc *fn; |
| 464 | setstrV(L, L->top++, lj_str_newlit(L, "abort")); | 466 | setstrV(L, L->top++, lj_str_newlit(L, "abort")); |
| 465 | setintV(L->top++, J->curtrace); | 467 | setintV(L->top++, traceno); |
| 466 | /* Find original Lua function call to generate a better error message. */ | 468 | /* Find original Lua function call to generate a better error message. */ |
| 467 | frame = J->L->base-1; | 469 | frame = J->L->base-1; |
| 468 | pc = J->pc; | 470 | pc = J->pc; |
| @@ -477,10 +479,10 @@ static int trace_abort(jit_State *J) | |||
| 477 | copyTV(L, L->top++, &J->errinfo); | 479 | copyTV(L, L->top++, &J->errinfo); |
| 478 | ); | 480 | ); |
| 479 | /* Drop aborted trace after the vmevent (which may still access it). */ | 481 | /* Drop aborted trace after the vmevent (which may still access it). */ |
| 480 | setgcrefnull(J->trace[J->curtrace]); | 482 | setgcrefnull(J->trace[traceno]); |
| 481 | if (J->curtrace < J->freetrace) | 483 | if (traceno < J->freetrace) |
| 482 | J->freetrace = J->curtrace; | 484 | J->freetrace = traceno; |
| 483 | J->curtrace = 0; | 485 | J->cur.traceno = 0; |
| 484 | } | 486 | } |
| 485 | L->top--; /* Remove error object */ | 487 | L->top--; /* Remove error object */ |
| 486 | if (e == LJ_TRERR_DOWNREC) | 488 | if (e == LJ_TRERR_DOWNREC) |
| @@ -517,7 +519,7 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud) | |||
| 517 | trace_pendpatch(J, 0); | 519 | trace_pendpatch(J, 0); |
| 518 | setvmstate(J2G(J), RECORD); | 520 | setvmstate(J2G(J), RECORD); |
| 519 | lj_vmevent_send(L, RECORD, | 521 | lj_vmevent_send(L, RECORD, |
| 520 | setintV(L->top++, J->curtrace); | 522 | setintV(L->top++, J->cur.traceno); |
| 521 | setfuncV(L, L->top++, J->fn); | 523 | setfuncV(L, L->top++, J->fn); |
| 522 | setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1); | 524 | setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1); |
| 523 | setintV(L->top++, J->framedepth); | 525 | setintV(L->top++, J->framedepth); |
| @@ -529,10 +531,11 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud) | |||
| 529 | trace_pendpatch(J, 1); | 531 | trace_pendpatch(J, 1); |
| 530 | J->loopref = 0; | 532 | J->loopref = 0; |
| 531 | if ((J->flags & JIT_F_OPT_LOOP) && | 533 | if ((J->flags & JIT_F_OPT_LOOP) && |
| 532 | J->cur.link == J->curtrace && J->framedepth + J->retdepth == 0) { | 534 | J->cur.link == J->cur.traceno && J->framedepth + J->retdepth == 0) { |
| 533 | setvmstate(J2G(J), OPT); | 535 | setvmstate(J2G(J), OPT); |
| 534 | lj_opt_dce(J); | 536 | lj_opt_dce(J); |
| 535 | if (lj_opt_loop(J)) { /* Loop optimization failed? */ | 537 | if (lj_opt_loop(J)) { /* Loop optimization failed? */ |
| 538 | J->cur.link = 0; | ||
| 536 | J->loopref = J->cur.nins; | 539 | J->loopref = J->cur.nins; |
| 537 | J->state = LJ_TRACE_RECORD; /* Try to continue recording. */ | 540 | J->state = LJ_TRACE_RECORD; /* Try to continue recording. */ |
| 538 | break; | 541 | break; |
