diff options
author | Mike Pall <mike> | 2021-07-27 14:47:41 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2021-07-27 14:47:41 +0200 |
commit | 3a654999c6f00de4cb9e61232d23579442e544a0 (patch) | |
tree | 7fb3854907e4453decc44c94d3cc15bd5c3619dc /src/lj_snap.c | |
parent | 0e66fc96377853d898390f1a02723c54ec3a42f7 (diff) | |
download | luajit-3a654999c6f00de4cb9e61232d23579442e544a0.tar.gz luajit-3a654999c6f00de4cb9e61232d23579442e544a0.tar.bz2 luajit-3a654999c6f00de4cb9e61232d23579442e544a0.zip |
Consider slots used by upvalues in use-def analysis.
Reported by XmiliaH.
Diffstat (limited to 'src/lj_snap.c')
-rw-r--r-- | src/lj_snap.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/src/lj_snap.c b/src/lj_snap.c index 91880fcf..333812fd 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -272,6 +272,31 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf, | |||
272 | return 0; /* unreachable */ | 272 | return 0; /* unreachable */ |
273 | } | 273 | } |
274 | 274 | ||
275 | /* Mark slots used by upvalues of child prototypes as used. */ | ||
276 | void snap_useuv(GCproto *pt, uint8_t *udf) | ||
277 | { | ||
278 | /* This is a coarse check, because it's difficult to correlate the lifetime | ||
279 | ** of slots and closures. But the number of false positives is quite low. | ||
280 | ** A false positive may cause a slot not to be purged, which is just | ||
281 | ** a missed optimization. | ||
282 | */ | ||
283 | if ((pt->flags & PROTO_CHILD)) { | ||
284 | ptrdiff_t i, j, n = pt->sizekgc; | ||
285 | GCRef *kr = mref(pt->k, GCRef) - 1; | ||
286 | for (i = 0; i < n; i++, kr--) { | ||
287 | GCobj *o = gcref(*kr); | ||
288 | if (o->gch.gct == ~LJ_TPROTO) { | ||
289 | for (j = 0; j < gco2pt(o)->sizeuv; j++) { | ||
290 | uint32_t v = proto_uv(gco2pt(o))[j]; | ||
291 | if ((v & PROTO_UV_LOCAL)) { | ||
292 | udf[(v & 0xff)] = 0; | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | } | ||
299 | |||
275 | /* Purge dead slots before the next snapshot. */ | 300 | /* Purge dead slots before the next snapshot. */ |
276 | void lj_snap_purge(jit_State *J) | 301 | void lj_snap_purge(jit_State *J) |
277 | { | 302 | { |
@@ -280,9 +305,12 @@ void lj_snap_purge(jit_State *J) | |||
280 | if (bc_op(*J->pc) == BC_FUNCV && maxslot > J->pt->numparams) | 305 | if (bc_op(*J->pc) == BC_FUNCV && maxslot > J->pt->numparams) |
281 | maxslot = J->pt->numparams; | 306 | maxslot = J->pt->numparams; |
282 | s = snap_usedef(J, udf, J->pc, maxslot); | 307 | s = snap_usedef(J, udf, J->pc, maxslot); |
283 | for (; s < maxslot; s++) | 308 | if (s < maxslot) { |
284 | if (udf[s] != 0) | 309 | snap_useuv(J->pt, udf); |
285 | J->base[s] = 0; /* Purge dead slots. */ | 310 | for (; s < maxslot; s++) |
311 | if (udf[s] != 0) | ||
312 | J->base[s] = 0; /* Purge dead slots. */ | ||
313 | } | ||
286 | } | 314 | } |
287 | 315 | ||
288 | /* Shrink last snapshot. */ | 316 | /* Shrink last snapshot. */ |
@@ -295,6 +323,7 @@ void lj_snap_shrink(jit_State *J) | |||
295 | BCReg maxslot = J->maxslot; | 323 | BCReg maxslot = J->maxslot; |
296 | BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot); | 324 | BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot); |
297 | BCReg baseslot = J->baseslot; | 325 | BCReg baseslot = J->baseslot; |
326 | if (minslot < maxslot) snap_useuv(J->pt, udf); | ||
298 | maxslot += baseslot; | 327 | maxslot += baseslot; |
299 | minslot += baseslot; | 328 | minslot += baseslot; |
300 | snap->nslots = (uint8_t)maxslot; | 329 | snap->nslots = (uint8_t)maxslot; |