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);
#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);
/* 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;