Merge branch 'master' into v2.1

This commit is contained in:
Mike Pall 2021-07-27 14:50:40 +02:00
commit 983d66b8c5

View File

@ -312,6 +312,31 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf,
return 0; /* unreachable */
}
/* Mark slots used by upvalues of child prototypes as used. */
void snap_useuv(GCproto *pt, uint8_t *udf)
{
/* This is a coarse check, because it's difficult to correlate the lifetime
** of slots and closures. But the number of false positives is quite low.
** A false positive may cause a slot not to be purged, which is just
** a missed optimization.
*/
if ((pt->flags & PROTO_CHILD)) {
ptrdiff_t i, j, n = pt->sizekgc;
GCRef *kr = mref(pt->k, GCRef) - 1;
for (i = 0; i < n; i++, kr--) {
GCobj *o = gcref(*kr);
if (o->gch.gct == ~LJ_TPROTO) {
for (j = 0; j < gco2pt(o)->sizeuv; j++) {
uint32_t v = proto_uv(gco2pt(o))[j];
if ((v & PROTO_UV_LOCAL)) {
udf[(v & 0xff)] = 0;
}
}
}
}
}
}
/* Purge dead slots before the next snapshot. */
void lj_snap_purge(jit_State *J)
{
@ -320,9 +345,12 @@ void lj_snap_purge(jit_State *J)
if (bc_op(*J->pc) == BC_FUNCV && maxslot > J->pt->numparams)
maxslot = J->pt->numparams;
s = snap_usedef(J, udf, J->pc, maxslot);
for (; s < maxslot; s++)
if (udf[s] != 0)
J->base[s] = 0; /* Purge dead slots. */
if (s < maxslot) {
snap_useuv(J->pt, udf);
for (; s < maxslot; s++)
if (udf[s] != 0)
J->base[s] = 0; /* Purge dead slots. */
}
}
/* Shrink last snapshot. */
@ -335,6 +363,7 @@ void lj_snap_shrink(jit_State *J)
BCReg maxslot = J->maxslot;
BCReg baseslot = J->baseslot;
BCReg minslot = snap_usedef(J, udf, snap_pc(&map[nent]), maxslot);
if (minslot < maxslot) snap_useuv(J->pt, udf);
maxslot += baseslot;
minslot += baseslot;
snap->nslots = (uint8_t)maxslot;