diff --git a/src/jit/dump.lua b/src/jit/dump.lua index fbadccec..a8bc2af2 100644 --- a/src/jit/dump.lua +++ b/src/jit/dump.lua @@ -338,6 +338,8 @@ local function formatk(tr, idx, sn) elseif t == 21 then -- int64_t s = sub(tostring(k), 1, -3) if sub(s, 1, 1) ~= "-" then s = "+"..s end + elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL) + return "----" -- Special case for LJ_FR2 slot 1. else s = tostring(k) -- For primitives. end diff --git a/src/lj_record.c b/src/lj_record.c index 48018f42..a858ffa9 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -105,7 +105,7 @@ static void rec_check_slots(jit_State *J) lua_assert(tref_isfunc(tr)); #if LJ_FR2 } else if (s == 1) { - lua_assert(0); + lua_assert((tr & ~TREF_FRAME) == 0); #endif } else if ((tr & TREF_FRAME)) { GCfunc *fn = gco2func(frame_gc(tv)); @@ -747,7 +747,7 @@ void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs) } /* Move func + args down. */ if (LJ_FR2 && J->baseslot == 2) - J->base[func+1] = 0; + J->base[func+1] = TREF_FRAME; memmove(&J->base[-1-LJ_FR2], &J->base[func], sizeof(TRef)*(J->maxslot+1+LJ_FR2)); /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */ /* Tailcalls can form a loop, so count towards the loop unroll limit. */ diff --git a/src/lj_snap.c b/src/lj_snap.c index 48259972..8ca6deb7 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -69,9 +69,13 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) TRef tr = J->slot[s]; IRRef ref = tref_ref(tr); #if LJ_FR2 - if (s == 1) continue; + if (s == 1) { /* Ignore slot 1 in LJ_FR2 mode, except if tailcalled. */ + if ((tr & TREF_FRAME)) + map[n++] = SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL); + continue; + } if ((tr & (TREF_FRAME | TREF_CONT)) && !ref) { - TValue *base = J->L->base - J->baseslot; + cTValue *base = J->L->base - J->baseslot; tr = J->slot[s] = (tr & 0xff0000) | lj_ir_k64(J, IR_KNUM, base[s].u64); ref = tref_ref(tr); } @@ -470,7 +474,11 @@ void lj_snap_replay(jit_State *J, GCtrace *T) goto setslot; bloomset(seen, ref); if (irref_isk(ref)) { - tr = snap_replay_const(J, ir); + /* See special treatment of LJ_FR2 slot 1 in snapshot_slots() above. */ + if (LJ_FR2 && (sn == SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL))) + tr = 0; + else + tr = snap_replay_const(J, ir); } else if (!regsp_used(ir->prev)) { pass23 = 1; lua_assert(s != 0); @@ -484,7 +492,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T) } setslot: J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */ - J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && s); + J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && (s != LJ_FR2)); if ((sn & SNAP_FRAME)) J->baseslot = s+1; }