diff options
Diffstat (limited to 'src/lj_opt_loop.c')
-rw-r--r-- | src/lj_opt_loop.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c index cc881110..441b8add 100644 --- a/src/lj_opt_loop.c +++ b/src/lj_opt_loop.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #if LJ_HASJIT | 11 | #if LJ_HASJIT |
12 | 12 | ||
13 | #include "lj_err.h" | 13 | #include "lj_err.h" |
14 | #include "lj_str.h" | 14 | #include "lj_buf.h" |
15 | #include "lj_ir.h" | 15 | #include "lj_ir.h" |
16 | #include "lj_jit.h" | 16 | #include "lj_jit.h" |
17 | #include "lj_iropt.h" | 17 | #include "lj_iropt.h" |
@@ -254,9 +254,16 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap, | |||
254 | J->cur.nsnapmap = (uint32_t)(nmap - J->cur.snapmap); | 254 | J->cur.nsnapmap = (uint32_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,13 +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_str_needbuf(J->L, &G(J->L)->tmpbuf, | 279 | lps->sizesubst = invar - REF_BIAS; |
274 | (invar-REF_BIAS)*sizeof(IRRef1)) - REF_BIAS; | 280 | lps->subst = lj_mem_newvec(J->L, lps->sizesubst, IRRef1); |
281 | subst = lps->subst - REF_BIAS; | ||
275 | subst[REF_BASE] = REF_BASE; | 282 | subst[REF_BASE] = REF_BASE; |
276 | 283 | ||
277 | /* LOOP separates the pre-roll from the loop body. */ | 284 | /* LOOP separates the pre-roll from the loop body. */ |
@@ -396,7 +403,7 @@ static void loop_undo(jit_State *J, IRRef ins, SnapNo nsnap, MSize nsnapmap) | |||
396 | 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) |
397 | { | 404 | { |
398 | UNUSED(L); UNUSED(dummy); | 405 | UNUSED(L); UNUSED(dummy); |
399 | loop_unroll((jit_State *)ud); | 406 | loop_unroll((LoopState *)ud); |
400 | return NULL; | 407 | return NULL; |
401 | } | 408 | } |
402 | 409 | ||
@@ -406,7 +413,13 @@ int lj_opt_loop(jit_State *J) | |||
406 | IRRef nins = J->cur.nins; | 413 | IRRef nins = J->cur.nins; |
407 | SnapNo nsnap = J->cur.nsnap; | 414 | SnapNo nsnap = J->cur.nsnap; |
408 | MSize nsnapmap = J->cur.nsnapmap; | 415 | MSize nsnapmap = J->cur.nsnapmap; |
409 | 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); | ||
410 | if (LJ_UNLIKELY(errcode)) { | 423 | if (LJ_UNLIKELY(errcode)) { |
411 | lua_State *L = J->L; | 424 | lua_State *L = J->L; |
412 | if (errcode == LUA_ERRRUN && tvisnumber(L->top-1)) { /* Trace error? */ | 425 | if (errcode == LUA_ERRRUN && tvisnumber(L->top-1)) { /* Trace error? */ |