aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_record.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index 246545dc..e51d0b5a 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -191,6 +191,7 @@ int lj_record_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv)
191/* Loop event. */ 191/* Loop event. */
192typedef enum { 192typedef enum {
193 LOOPEV_LEAVE, /* Loop is left or not entered. */ 193 LOOPEV_LEAVE, /* Loop is left or not entered. */
194 LOOPEV_ENTERLO, /* Loop is entered with a low iteration count left. */
194 LOOPEV_ENTER /* Loop is entered. */ 195 LOOPEV_ENTER /* Loop is entered. */
195} LoopEvent; 196} LoopEvent;
196 197
@@ -316,10 +317,16 @@ static LoopEvent rec_for_iter(IROp *op, cTValue *o, int isforl)
316 if (isforl) 317 if (isforl)
317 idxv += stepv; 318 idxv += stepv;
318 if (rec_for_direction(&o[FORL_STEP])) { 319 if (rec_for_direction(&o[FORL_STEP])) {
319 if (idxv <= stopv) { *op = IR_LE; return LOOPEV_ENTER; } 320 if (idxv <= stopv) {
321 *op = IR_LE;
322 return idxv + 2*stepv > stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
323 }
320 *op = IR_GT; return LOOPEV_LEAVE; 324 *op = IR_GT; return LOOPEV_LEAVE;
321 } else { 325 } else {
322 if (stopv <= idxv) { *op = IR_GE; return LOOPEV_ENTER; } 326 if (stopv <= idxv) {
327 *op = IR_GE;
328 return idxv + 2*stepv < stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
329 }
323 *op = IR_LT; return LOOPEV_LEAVE; 330 *op = IR_LT; return LOOPEV_LEAVE;
324 } 331 }
325} 332}
@@ -522,7 +529,8 @@ static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev)
522 */ 529 */
523 if (!innerloopleft(J, pc)) 530 if (!innerloopleft(J, pc))
524 lj_trace_err(J, LJ_TRERR_LINNER); /* Root trace hit an inner loop. */ 531 lj_trace_err(J, LJ_TRERR_LINNER); /* Root trace hit an inner loop. */
525 if ((J->loopref && J->cur.nins - J->loopref > 24) || --J->loopunroll < 0) 532 if ((ev != LOOPEV_ENTERLO &&
533 J->loopref && J->cur.nins - J->loopref > 24) || --J->loopunroll < 0)
526 lj_trace_err(J, LJ_TRERR_LUNROLL); /* Limit loop unrolling. */ 534 lj_trace_err(J, LJ_TRERR_LUNROLL); /* Limit loop unrolling. */
527 J->loopref = J->cur.nins; 535 J->loopref = J->cur.nins;
528 } 536 }