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 | |
| 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')
| -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; |
