diff --git a/src/lj_jit.h b/src/lj_jit.h index f52c8d33d5..b72207d6c8 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -223,13 +223,13 @@ static LJ_AINLINE MSize snap_nextofs(GCtrace *T, SnapShot *snap) /* Round-robin penalty cache for bytecodes leading to aborted traces. */ typedef struct HotPenalty { MRef pc; /* Starting bytecode PC. */ - uint16_t val; /* Penalty value, i.e. hotcount start. */ + uint32_t val; /* Penalty value, i.e. hotcount start. */ uint16_t reason; /* Abort reason (really TraceErr). */ } HotPenalty; #define PENALTY_SLOTS 64 /* Penalty cache slot. Must be a power of 2. */ #define PENALTY_MIN (36*2) /* Minimum penalty value. */ -#define PENALTY_MAX 60000 /* Maximum penalty value. */ +#define PENALTY_MAX 6000000 /* Maximum penalty value. */ #define PENALTY_RNDBITS 4 /* # of random bits to add to penalty value. */ /* Round-robin backpropagation cache for narrowing conversions. */ diff --git a/src/lj_record.c b/src/lj_record.c index f4b3c0e0d5..e6e6c3be5d 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -568,7 +568,8 @@ static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev) /* Handle the case when an already compiled loop op is hit. */ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev) { - if (J->parent == 0 && J->exitno == 0) { /* Root trace hit an inner loop. */ + /* Root trace hit an inner loop. */ + if (J->parent == 0 && J->exitno == 0 && !innerloopleft(J, J->startpc)) { /* Better let the inner loop spawn a side trace back here. */ lj_trace_err(J, LJ_TRERR_LINNER); } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */ diff --git a/src/lj_trace.c b/src/lj_trace.c index c99cff1156..5be350ad17 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -264,6 +264,8 @@ int lj_trace_flushall(lua_State *L) } /* Clear penalty cache. */ memset(J->penalty, 0, sizeof(J->penalty)); + /* Reset hotcounts. */ + lj_dispatch_init_hotcount(J2G(J)); /* Free the whole machine code and invalidate all exit stub groups. */ lj_mcode_free(J); memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); @@ -335,7 +337,7 @@ static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e) J->penaltyslot = (J->penaltyslot + 1) & (PENALTY_SLOTS-1); setmref(J->penalty[i].pc, pc); setpenalty: - J->penalty[i].val = (uint16_t)val; + J->penalty[i].val = val; J->penalty[i].reason = e; hotcount_set(J2GG(J), pc+1, val); } @@ -401,6 +403,7 @@ static void trace_stop(jit_State *J) TraceNo traceno = J->cur.traceno; GCtrace *T = J->curfinal; lua_State *L; + int i; switch (op) { case BC_FORL: @@ -452,6 +455,11 @@ static void trace_stop(jit_State *J) J->postproc = LJ_POST_NONE; trace_save(J, T); + /* Clear any penalty after successful recording. */ + for (i = 0; i < PENALTY_SLOTS; i++) + if (mref(J->penalty[i].pc, const BCIns) == pc) + J->penalty[i].val = PENALTY_MIN; + L = J->L; }