aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_snap.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/lj_snap.c b/src/lj_snap.c
index b2b8450c..40bfad92 100644
--- a/src/lj_snap.c
+++ b/src/lj_snap.c
@@ -312,6 +312,31 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf,
312 return 0; /* unreachable */ 312 return 0; /* unreachable */
313} 313}
314 314
315/* Mark slots used by upvalues of child prototypes as used. */
316void snap_useuv(GCproto *pt, uint8_t *udf)
317{
318 /* This is a coarse check, because it's difficult to correlate the lifetime
319 ** of slots and closures. But the number of false positives is quite low.
320 ** A false positive may cause a slot not to be purged, which is just
321 ** a missed optimization.
322 */
323 if ((pt->flags & PROTO_CHILD)) {
324 ptrdiff_t i, j, n = pt->sizekgc;
325 GCRef *kr = mref(pt->k, GCRef) - 1;
326 for (i = 0; i < n; i++, kr--) {
327 GCobj *o = gcref(*kr);
328 if (o->gch.gct == ~LJ_TPROTO) {
329 for (j = 0; j < gco2pt(o)->sizeuv; j++) {
330 uint32_t v = proto_uv(gco2pt(o))[j];
331 if ((v & PROTO_UV_LOCAL)) {
332 udf[(v & 0xff)] = 0;
333 }
334 }
335 }
336 }
337 }
338}
339
315/* Purge dead slots before the next snapshot. */ 340/* Purge dead slots before the next snapshot. */
316void lj_snap_purge(jit_State *J) 341void lj_snap_purge(jit_State *J)
317{ 342{
@@ -320,9 +345,12 @@ void lj_snap_purge(jit_State *J)
320 if (bc_op(*J->pc) == BC_FUNCV && maxslot > J->pt->numparams) 345 if (bc_op(*J->pc) == BC_FUNCV && maxslot > J->pt->numparams)
321 maxslot = J->pt->numparams; 346 maxslot = J->pt->numparams;
322 s = snap_usedef(J, udf, J->pc, maxslot); 347 s = snap_usedef(J, udf, J->pc, maxslot);
323 for (; s < maxslot; s++) 348 if (s < maxslot) {
324 if (udf[s] != 0) 349 snap_useuv(J->pt, udf);
325 J->base[s] = 0; /* Purge dead slots. */ 350 for (; s < maxslot; s++)
351 if (udf[s] != 0)
352 J->base[s] = 0; /* Purge dead slots. */
353 }
326} 354}
327 355
328/* Shrink last snapshot. */ 356/* Shrink last snapshot. */
@@ -335,6 +363,7 @@ void lj_snap_shrink(jit_State *J)
335 BCReg maxslot = J->maxslot; 363 BCReg maxslot = J->maxslot;
336 BCReg baseslot = J->baseslot; 364 BCReg baseslot = J->baseslot;
337 BCReg minslot = snap_usedef(J, udf, snap_pc(&map[nent]), maxslot); 365 BCReg minslot = snap_usedef(J, udf, snap_pc(&map[nent]), maxslot);
366 if (minslot < maxslot) snap_useuv(J->pt, udf);
338 maxslot += baseslot; 367 maxslot += baseslot;
339 minslot += baseslot; 368 minslot += baseslot;
340 snap->nslots = (uint8_t)maxslot; 369 snap->nslots = (uint8_t)maxslot;