From 1761fd2ef79ffe1778011c7e9cb03ed361b48c5e Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Sun, 10 Dec 2023 14:29:45 +0100 Subject: [PATCH] Emit sunk IR_NEWREF only once per key on snapshot replay. Thanks to Sergey Kaplun and Peter Cawley. #1128 --- src/lj_snap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lj_snap.c b/src/lj_snap.c index a6cd93d4..5a5c481b 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -575,9 +575,21 @@ void lj_snap_replay(jit_State *J, GCtrace *T) if (irr->o == IR_HREFK || irr->o == IR_AREF) { IRIns *irf = &T->ir[irr->op1]; tmp = emitir(irf->ot, tmp, irf->op2); + } else if (irr->o == IR_NEWREF) { + IRRef allocref = tref_ref(tr); + IRRef keyref = tref_ref(key); + IRRef newref_ref = J->chain[IR_NEWREF]; + IRIns *newref = &J->cur.ir[newref_ref]; + lua_assert(irref_isk(keyref)); + if (newref_ref > allocref && newref->op2 == keyref) { + lua_assert(newref->op1 == allocref); + tmp = newref_ref; + goto skip_newref; + } } } tmp = emitir(irr->ot, tmp, key); + skip_newref: val = snap_pref(J, T, map, nent, seen, irs->op2); if (val == 0) { IRIns *irc = &T->ir[irs->op2]; -- 2.11.4.GIT