mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Consider slots used by upvalues in use-def analysis.
Reported by XmiliaH.
This commit is contained in:
parent
0e66fc9637
commit
3a654999c6
@ -272,6 +272,31 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf,
|
|||||||
return 0; /* unreachable */
|
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. */
|
/* Purge dead slots before the next snapshot. */
|
||||||
void lj_snap_purge(jit_State *J)
|
void lj_snap_purge(jit_State *J)
|
||||||
{
|
{
|
||||||
@ -280,9 +305,12 @@ void lj_snap_purge(jit_State *J)
|
|||||||
if (bc_op(*J->pc) == BC_FUNCV && maxslot > J->pt->numparams)
|
if (bc_op(*J->pc) == BC_FUNCV && maxslot > J->pt->numparams)
|
||||||
maxslot = J->pt->numparams;
|
maxslot = J->pt->numparams;
|
||||||
s = snap_usedef(J, udf, J->pc, maxslot);
|
s = snap_usedef(J, udf, J->pc, maxslot);
|
||||||
|
if (s < maxslot) {
|
||||||
|
snap_useuv(J->pt, udf);
|
||||||
for (; s < maxslot; s++)
|
for (; s < maxslot; s++)
|
||||||
if (udf[s] != 0)
|
if (udf[s] != 0)
|
||||||
J->base[s] = 0; /* Purge dead slots. */
|
J->base[s] = 0; /* Purge dead slots. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shrink last snapshot. */
|
/* Shrink last snapshot. */
|
||||||
@ -295,6 +323,7 @@ void lj_snap_shrink(jit_State *J)
|
|||||||
BCReg maxslot = J->maxslot;
|
BCReg maxslot = J->maxslot;
|
||||||
BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot);
|
BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot);
|
||||||
BCReg baseslot = J->baseslot;
|
BCReg baseslot = J->baseslot;
|
||||||
|
if (minslot < maxslot) snap_useuv(J->pt, udf);
|
||||||
maxslot += baseslot;
|
maxslot += baseslot;
|
||||||
minslot += baseslot;
|
minslot += baseslot;
|
||||||
snap->nslots = (uint8_t)maxslot;
|
snap->nslots = (uint8_t)maxslot;
|
||||||
|
Loading…
Reference in New Issue
Block a user