diff options
author | Mike Pall <mike> | 2023-12-10 14:29:45 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2023-12-10 14:29:45 +0100 |
commit | 1761fd2ef79ffe1778011c7e9cb03ed361b48c5e (patch) | |
tree | cc0760ed291de463a68847e18641365495280933 | |
parent | 644723649ea04cb23b72c814b88b72a29e4afed4 (diff) | |
download | luajit-1761fd2ef79ffe1778011c7e9cb03ed361b48c5e.tar.gz luajit-1761fd2ef79ffe1778011c7e9cb03ed361b48c5e.tar.bz2 luajit-1761fd2ef79ffe1778011c7e9cb03ed361b48c5e.zip |
Emit sunk IR_NEWREF only once per key on snapshot replay.
Thanks to Sergey Kaplun and Peter Cawley. #1128
-rw-r--r-- | src/lj_snap.c | 12 |
1 files changed, 12 insertions, 0 deletions
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) | |||
575 | if (irr->o == IR_HREFK || irr->o == IR_AREF) { | 575 | if (irr->o == IR_HREFK || irr->o == IR_AREF) { |
576 | IRIns *irf = &T->ir[irr->op1]; | 576 | IRIns *irf = &T->ir[irr->op1]; |
577 | tmp = emitir(irf->ot, tmp, irf->op2); | 577 | tmp = emitir(irf->ot, tmp, irf->op2); |
578 | } else if (irr->o == IR_NEWREF) { | ||
579 | IRRef allocref = tref_ref(tr); | ||
580 | IRRef keyref = tref_ref(key); | ||
581 | IRRef newref_ref = J->chain[IR_NEWREF]; | ||
582 | IRIns *newref = &J->cur.ir[newref_ref]; | ||
583 | lua_assert(irref_isk(keyref)); | ||
584 | if (newref_ref > allocref && newref->op2 == keyref) { | ||
585 | lua_assert(newref->op1 == allocref); | ||
586 | tmp = newref_ref; | ||
587 | goto skip_newref; | ||
588 | } | ||
578 | } | 589 | } |
579 | } | 590 | } |
580 | tmp = emitir(irr->ot, tmp, key); | 591 | tmp = emitir(irr->ot, tmp, key); |
592 | skip_newref: | ||
581 | val = snap_pref(J, T, map, nent, seen, irs->op2); | 593 | val = snap_pref(J, T, map, nent, seen, irs->op2); |
582 | if (val == 0) { | 594 | if (val == 0) { |
583 | IRIns *irc = &T->ir[irs->op2]; | 595 | IRIns *irc = &T->ir[irs->op2]; |