diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_opt_loop.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c index 529bacf5..91f8067c 100644 --- a/src/lj_opt_loop.c +++ b/src/lj_opt_loop.c | |||
| @@ -254,9 +254,16 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap, | |||
| 254 | J->cur.nsnapmap = (uint16_t)(nmap - J->cur.snapmap); | 254 | J->cur.nsnapmap = (uint16_t)(nmap - J->cur.snapmap); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | typedef struct LoopState { | ||
| 258 | jit_State *J; | ||
| 259 | IRRef1 *subst; | ||
| 260 | MSize sizesubst; | ||
| 261 | } LoopState; | ||
| 262 | |||
| 257 | /* Unroll loop. */ | 263 | /* Unroll loop. */ |
| 258 | static void loop_unroll(jit_State *J) | 264 | static void loop_unroll(LoopState *lps) |
| 259 | { | 265 | { |
| 266 | jit_State *J = lps->J; | ||
| 260 | IRRef1 phi[LJ_MAX_PHI]; | 267 | IRRef1 phi[LJ_MAX_PHI]; |
| 261 | uint32_t nphi = 0; | 268 | uint32_t nphi = 0; |
| 262 | IRRef1 *subst; | 269 | IRRef1 *subst; |
| @@ -265,12 +272,13 @@ static void loop_unroll(jit_State *J) | |||
| 265 | SnapEntry *loopmap, *psentinel; | 272 | SnapEntry *loopmap, *psentinel; |
| 266 | IRRef ins, invar; | 273 | IRRef ins, invar; |
| 267 | 274 | ||
| 268 | /* Use temp buffer for substitution table. | 275 | /* Allocate substitution table. |
| 269 | ** Only non-constant refs in [REF_BIAS,invar) are valid indexes. | 276 | ** Only non-constant refs in [REF_BIAS,invar) are valid indexes. |
| 270 | ** Caveat: don't call into the VM or run the GC or the buffer may be gone. | ||
| 271 | */ | 277 | */ |
| 272 | invar = J->cur.nins; | 278 | invar = J->cur.nins; |
| 273 | subst = (IRRef1 *)lj_buf_tmp(J->L, (invar-REF_BIAS)*sizeof(IRRef1))-REF_BIAS; | 279 | lps->sizesubst = invar - REF_BIAS; |
| 280 | lps->subst = lj_mem_newvec(J->L, lps->sizesubst, IRRef1); | ||
| 281 | subst = lps->subst - REF_BIAS; | ||
| 274 | subst[REF_BASE] = REF_BASE; | 282 | subst[REF_BASE] = REF_BASE; |
| 275 | 283 | ||
| 276 | /* LOOP separates the pre-roll from the loop body. */ | 284 | /* LOOP separates the pre-roll from the loop body. */ |
| @@ -395,7 +403,7 @@ static void loop_undo(jit_State *J, IRRef ins, SnapNo nsnap, MSize nsnapmap) | |||
| 395 | static TValue *cploop_opt(lua_State *L, lua_CFunction dummy, void *ud) | 403 | static TValue *cploop_opt(lua_State *L, lua_CFunction dummy, void *ud) |
| 396 | { | 404 | { |
| 397 | UNUSED(L); UNUSED(dummy); | 405 | UNUSED(L); UNUSED(dummy); |
| 398 | loop_unroll((jit_State *)ud); | 406 | loop_unroll((LoopState *)ud); |
| 399 | return NULL; | 407 | return NULL; |
| 400 | } | 408 | } |
| 401 | 409 | ||
| @@ -405,7 +413,13 @@ int lj_opt_loop(jit_State *J) | |||
| 405 | IRRef nins = J->cur.nins; | 413 | IRRef nins = J->cur.nins; |
| 406 | SnapNo nsnap = J->cur.nsnap; | 414 | SnapNo nsnap = J->cur.nsnap; |
| 407 | MSize nsnapmap = J->cur.nsnapmap; | 415 | MSize nsnapmap = J->cur.nsnapmap; |
| 408 | int errcode = lj_vm_cpcall(J->L, NULL, J, cploop_opt); | 416 | LoopState lps; |
| 417 | int errcode; | ||
| 418 | lps.J = J; | ||
| 419 | lps.subst = NULL; | ||
| 420 | lps.sizesubst = 0; | ||
| 421 | errcode = lj_vm_cpcall(J->L, NULL, &lps, cploop_opt); | ||
| 422 | lj_mem_freevec(J2G(J), lps.subst, lps.sizesubst, IRRef1); | ||
| 409 | if (LJ_UNLIKELY(errcode)) { | 423 | if (LJ_UNLIKELY(errcode)) { |
| 410 | lua_State *L = J->L; | 424 | lua_State *L = J->L; |
| 411 | if (errcode == LUA_ERRRUN && tvisnumber(L->top-1)) { /* Trace error? */ | 425 | if (errcode == LUA_ERRRUN && tvisnumber(L->top-1)) { /* Trace error? */ |
