diff --git a/src/lj_asm.c b/src/lj_asm.c index 1e934d7c..3813a5d7 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -2581,9 +2581,7 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) int32_t ofs = 8*((int32_t)s-1); IRRef ref = snap_ref(sn); IRIns *ir = IR(ref); - /* No need to restore readonly slots and unmodified non-parent slots. */ - if (ir->o == IR_SLOAD && ir->op1 == s && - (ir->op2 & (IRSLOAD_READONLY|IRSLOAD_PARENT)) != IRSLOAD_PARENT) + if ((sn & SNAP_NORESTORE)) continue; if (irt_isnum(ir->t)) { Reg src = ra_alloc1(as, ref, RSET_FPR); diff --git a/src/lj_jit.h b/src/lj_jit.h index 68cebbc2..18069ac9 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -125,6 +125,7 @@ typedef uint32_t SnapEntry; #define SNAP_FRAME 0x010000 /* Frame slot. */ #define SNAP_CONT 0x020000 /* Continuation slot. */ +#define SNAP_NORESTORE 0x040000 /* No need to restore slot. */ LJ_STATIC_ASSERT(SNAP_FRAME == TREF_FRAME); LJ_STATIC_ASSERT(SNAP_CONT == TREF_CONT); diff --git a/src/lj_snap.c b/src/lj_snap.c index 1353e90f..2b82e672 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -53,16 +53,24 @@ void lj_snap_grow_map_(jit_State *J, MSize need) /* Add all modified slots to the snapshot. */ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) { + IRRef retf = J->chain[IR_RETF]; /* Limits SLOAD restore elimination. */ BCReg s; MSize n = 0; for (s = 0; s < nslots; s++) { TRef tr = J->slot[s]; IRRef ref = tref_ref(tr); if (ref) { + SnapEntry sn = SNAP_TR(s, tr); IRIns *ir = IR(ref); - if (!(ir->o == IR_SLOAD && ir->op1 == s && - !(ir->op2 & IRSLOAD_INHERIT))) - map[n++] = SNAP_TR(s, tr); + if (ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { + /* No need to snapshot unmodified non-inherited slots. */ + if (!(ir->op2 & IRSLOAD_INHERIT)) + continue; + /* No need to restore readonly slots and unmodified non-parent slots. */ + if ((ir->op2 & (IRSLOAD_READONLY|IRSLOAD_PARENT)) != IRSLOAD_PARENT) + sn |= SNAP_NORESTORE; + } + map[n++] = sn; } } return n;