diff options
author | Mike Pall <mike> | 2010-02-03 14:55:56 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-02-03 14:55:56 +0100 |
commit | 318e86c7eb53999783c0c4a3c6796d1a723dd024 (patch) | |
tree | 2f7521d190121fbf2fcbc8c15290fcd66434b45b /src | |
parent | c1c9abeab7f3716dda213c6048344e1bf4f58486 (diff) | |
download | luajit-318e86c7eb53999783c0c4a3c6796d1a723dd024.tar.gz luajit-318e86c7eb53999783c0c4a3c6796d1a723dd024.tar.bz2 luajit-318e86c7eb53999783c0c4a3c6796d1a723dd024.zip |
Clean up frame depth checks and loop detection.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_jit.h | 1 | ||||
-rw-r--r-- | src/lj_record.c | 14 | ||||
-rw-r--r-- | src/lj_trace.c | 3 |
3 files changed, 12 insertions, 6 deletions
diff --git a/src/lj_jit.h b/src/lj_jit.h index 35595cd5..1e029182 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
@@ -231,6 +231,7 @@ typedef struct jit_State { | |||
231 | int32_t loopunroll; /* Unroll counter for loop ops in side traces. */ | 231 | int32_t loopunroll; /* Unroll counter for loop ops in side traces. */ |
232 | int32_t tailcalled; /* Number of successive tailcalls. */ | 232 | int32_t tailcalled; /* Number of successive tailcalls. */ |
233 | int32_t framedepth; /* Current frame depth. */ | 233 | int32_t framedepth; /* Current frame depth. */ |
234 | int32_t retdepth; /* Return frame depth (count of RETF). */ | ||
234 | 235 | ||
235 | MRef knum; /* Pointer to chained array of KNUM constants. */ | 236 | MRef knum; /* Pointer to chained array of KNUM constants. */ |
236 | 237 | ||
diff --git a/src/lj_record.c b/src/lj_record.c index a32d19f0..682246d7 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -209,7 +209,8 @@ static void rec_stop(jit_State *J, TraceNo lnk) | |||
209 | { | 209 | { |
210 | lj_trace_end(J); | 210 | lj_trace_end(J); |
211 | J->cur.link = (uint16_t)lnk; | 211 | J->cur.link = (uint16_t)lnk; |
212 | if (lnk == J->curtrace) { /* Looping back? */ | 212 | /* Looping back at the same stack level? */ |
213 | if (lnk == J->curtrace && J->framedepth + J->retdepth == 0) { | ||
213 | if ((J->flags & JIT_F_OPT_LOOP)) /* Shall we try to create a loop? */ | 214 | if ((J->flags & JIT_F_OPT_LOOP)) /* Shall we try to create a loop? */ |
214 | goto nocanon; /* Do not canonicalize or we lose the narrowing. */ | 215 | goto nocanon; /* Do not canonicalize or we lose the narrowing. */ |
215 | if (J->cur.root) /* Otherwise ensure we always link to the root trace. */ | 216 | if (J->cur.root) /* Otherwise ensure we always link to the root trace. */ |
@@ -368,7 +369,7 @@ static int innerloopleft(jit_State *J, const BCIns *pc) | |||
368 | static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev) | 369 | static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev) |
369 | { | 370 | { |
370 | if (J->parent == 0) { | 371 | if (J->parent == 0) { |
371 | if (pc == J->startpc && J->framedepth == 0 && !J->chain[IR_RETF]) { | 372 | if (pc == J->startpc && J->framedepth + J->retdepth == 0) { |
372 | /* Same loop? */ | 373 | /* Same loop? */ |
373 | if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */ | 374 | if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */ |
374 | lj_trace_err(J, LJ_TRERR_LLEAVE); | 375 | lj_trace_err(J, LJ_TRERR_LLEAVE); |
@@ -401,7 +402,7 @@ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev) | |||
401 | lj_trace_err(J, LJ_TRERR_LINNER); | 402 | lj_trace_err(J, LJ_TRERR_LINNER); |
402 | } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */ | 403 | } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */ |
403 | J->instunroll = 0; /* Cannot continue across a compiled loop op. */ | 404 | J->instunroll = 0; /* Cannot continue across a compiled loop op. */ |
404 | if (J->pc == J->startpc && J->framedepth == 0 && !J->chain[IR_RETF]) | 405 | if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) |
405 | lnk = J->curtrace; /* Can form an extra loop. */ | 406 | lnk = J->curtrace; /* Can form an extra loop. */ |
406 | rec_stop(J, lnk); /* Link to the loop. */ | 407 | rec_stop(J, lnk); /* Link to the loop. */ |
407 | } /* Side trace continues across a loop that's left or not entered. */ | 408 | } /* Side trace continues across a loop that's left or not entered. */ |
@@ -1538,6 +1539,7 @@ static void rec_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
1538 | TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); | 1539 | TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); |
1539 | TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame)); | 1540 | TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame)); |
1540 | emitir(IRTG(IR_RETF, IRT_PTR), trpt, trpc); | 1541 | emitir(IRTG(IR_RETF, IRT_PTR), trpt, trpc); |
1542 | J->retdepth++; | ||
1541 | J->needsnap = 1; | 1543 | J->needsnap = 1; |
1542 | lua_assert(J->baseslot == 1); | 1544 | lua_assert(J->baseslot == 1); |
1543 | /* Shift result slots up and clear the slots of the new frame below. */ | 1545 | /* Shift result slots up and clear the slots of the new frame below. */ |
@@ -1584,8 +1586,9 @@ static void check_call_unroll(jit_State *J, GCfunc *fn) | |||
1584 | frame = frame_prevd(frame); | 1586 | frame = frame_prevd(frame); |
1585 | frame = frame_prev(frame); | 1587 | frame = frame_prev(frame); |
1586 | } | 1588 | } |
1587 | if (frame_func(first) == fn && bc_op(J->cur.startins) == BC_CALL) { | 1589 | if (bc_op(J->cur.startins) == BC_CALL && |
1588 | if (count >= J->param[JIT_P_recunroll]) | 1590 | funcproto(fn) == &gcref(J->cur.startpt)->pt) { |
1591 | if (count + J->tailcalled >= J->param[JIT_P_recunroll]) | ||
1589 | lj_trace_err(J, LJ_TRERR_NYIRECU); | 1592 | lj_trace_err(J, LJ_TRERR_NYIRECU); |
1590 | } else { | 1593 | } else { |
1591 | if (count >= J->param[JIT_P_callunroll]) | 1594 | if (count >= J->param[JIT_P_callunroll]) |
@@ -2236,6 +2239,7 @@ void lj_record_setup(jit_State *J) | |||
2236 | J->base = J->slot + J->baseslot; | 2239 | J->base = J->slot + J->baseslot; |
2237 | J->maxslot = 0; | 2240 | J->maxslot = 0; |
2238 | J->framedepth = 0; | 2241 | J->framedepth = 0; |
2242 | J->retdepth = 0; | ||
2239 | 2243 | ||
2240 | J->instunroll = J->param[JIT_P_instunroll]; | 2244 | J->instunroll = J->param[JIT_P_instunroll]; |
2241 | J->loopunroll = J->param[JIT_P_loopunroll]; | 2245 | J->loopunroll = J->param[JIT_P_loopunroll]; |
diff --git a/src/lj_trace.c b/src/lj_trace.c index d1883ad2..ce313df3 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
@@ -491,7 +491,8 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud) | |||
491 | 491 | ||
492 | case LJ_TRACE_END: | 492 | case LJ_TRACE_END: |
493 | J->loopref = 0; | 493 | J->loopref = 0; |
494 | if ((J->flags & JIT_F_OPT_LOOP) && J->cur.link == J->curtrace) { | 494 | if ((J->flags & JIT_F_OPT_LOOP) && |
495 | J->cur.link == J->curtrace && J->framedepth + J->retdepth == 0) { | ||
495 | setvmstate(J2G(J), OPT); | 496 | setvmstate(J2G(J), OPT); |
496 | lj_opt_dce(J); | 497 | lj_opt_dce(J); |
497 | if (lj_opt_loop(J)) { /* Loop optimization failed? */ | 498 | if (lj_opt_loop(J)) { /* Loop optimization failed? */ |