Bläddra i källkod

LJ_FR2: Fix slot 1 handling.

Contributed by Peter Cawley.
Mike Pall 9 år sedan
förälder
incheckning
6a25014c1c
3 ändrade filer med 16 tillägg och 6 borttagningar
  1. 2 0
      src/jit/dump.lua
  2. 2 2
      src/lj_record.c
  3. 12 4
      src/lj_snap.c

+ 2 - 0
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

+ 2 - 2
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. */

+ 12 - 4
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;
   }