aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-02-03 14:55:56 +0100
committerMike Pall <mike>2010-02-03 14:55:56 +0100
commit318e86c7eb53999783c0c4a3c6796d1a723dd024 (patch)
tree2f7521d190121fbf2fcbc8c15290fcd66434b45b /src
parentc1c9abeab7f3716dda213c6048344e1bf4f58486 (diff)
downloadluajit-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.h1
-rw-r--r--src/lj_record.c14
-rw-r--r--src/lj_trace.c3
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)
368static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev) 369static 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? */