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