diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_snap.c | 129 |
1 files changed, 64 insertions, 65 deletions
diff --git a/src/lj_snap.c b/src/lj_snap.c index 252dc29e..d2e4d95e 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
| @@ -341,6 +341,56 @@ void lj_snap_regspmap(uint16_t *rsmap, GCtrace *T, SnapNo snapno, int hi) | |||
| 341 | } | 341 | } |
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | /* Restore a value from the trace exit state. */ | ||
| 345 | static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, | ||
| 346 | SnapNo snapno, BloomFilter rfilt, | ||
| 347 | IRRef ref, TValue *o) | ||
| 348 | { | ||
| 349 | IRIns *ir = &T->ir[ref]; | ||
| 350 | IRType1 t = ir->t; | ||
| 351 | RegSP rs = ir->prev; | ||
| 352 | if (irref_isk(ref)) { /* Restore constant slot. */ | ||
| 353 | lj_ir_kvalue(J->L, o, ir); | ||
| 354 | return; | ||
| 355 | } | ||
| 356 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) | ||
| 357 | rs = snap_renameref(T, snapno, ref, rs); | ||
| 358 | if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ | ||
| 359 | int32_t *sps = &ex->spill[regsp_spill(rs)]; | ||
| 360 | if (irt_isinteger(t)) { | ||
| 361 | setintV(o, *sps); | ||
| 362 | #if !LJ_SOFTFP | ||
| 363 | } else if (irt_isnum(t)) { | ||
| 364 | o->u64 = *(uint64_t *)sps; | ||
| 365 | #endif | ||
| 366 | } else if (LJ_64 && irt_islightud(t)) { | ||
| 367 | /* 64 bit lightuserdata which may escape already has the tag bits. */ | ||
| 368 | o->u64 = *(uint64_t *)sps; | ||
| 369 | } else { | ||
| 370 | lua_assert(!irt_ispri(t)); /* PRI refs never have a spill slot. */ | ||
| 371 | setgcrefi(o->gcr, *sps); | ||
| 372 | setitype(o, irt_toitype(t)); | ||
| 373 | } | ||
| 374 | } else { /* Restore from register. */ | ||
| 375 | Reg r = regsp_reg(rs); | ||
| 376 | lua_assert(ra_hasreg(r)); | ||
| 377 | if (irt_isinteger(t)) { | ||
| 378 | setintV(o, (int32_t)ex->gpr[r-RID_MIN_GPR]); | ||
| 379 | #if !LJ_SOFTFP | ||
| 380 | } else if (irt_isnum(t)) { | ||
| 381 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); | ||
| 382 | #endif | ||
| 383 | } else if (LJ_64 && irt_islightud(t)) { | ||
| 384 | /* 64 bit lightuserdata which may escape already has the tag bits. */ | ||
| 385 | o->u64 = ex->gpr[r-RID_MIN_GPR]; | ||
| 386 | } else { | ||
| 387 | if (!irt_ispri(t)) | ||
| 388 | setgcrefi(o->gcr, ex->gpr[r-RID_MIN_GPR]); | ||
| 389 | setitype(o, irt_toitype(t)); | ||
| 390 | } | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 344 | /* Restore interpreter state from exit state with the help of a snapshot. */ | 394 | /* Restore interpreter state from exit state with the help of a snapshot. */ |
| 345 | const BCIns *lj_snap_restore(jit_State *J, void *exptr) | 395 | const BCIns *lj_snap_restore(jit_State *J, void *exptr) |
| 346 | { | 396 | { |
| @@ -371,73 +421,23 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
| 371 | ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */ | 421 | ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */ |
| 372 | for (n = 0; n < nent; n++) { | 422 | for (n = 0; n < nent; n++) { |
| 373 | SnapEntry sn = map[n]; | 423 | SnapEntry sn = map[n]; |
| 374 | IRRef ref = snap_ref(sn); | 424 | if (!(sn & SNAP_NORESTORE)) { |
| 375 | BCReg s = snap_slot(sn); | 425 | TValue *o = &frame[snap_slot(sn)]; |
| 376 | TValue *o = &frame[s]; /* Stack slots are relative to start frame. */ | 426 | snap_restoreval(J, T, ex, snapno, rfilt, snap_ref(sn), o); |
| 377 | IRIns *ir = &T->ir[ref]; | 427 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && tvisint(o)) { |
| 378 | if (irref_isk(ref)) { /* Restore constant slot. */ | 428 | TValue tmp; |
| 379 | lj_ir_kvalue(L, o, ir); | 429 | snap_restoreval(J, T, ex, snapno, rfilt, snap_ref(sn)+1, &tmp); |
| 380 | } else if (!(sn & SNAP_NORESTORE)) { | 430 | o->u32.hi = tmp.u32.lo; |
| 381 | IRType1 t = ir->t; | 431 | } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { |
| 382 | RegSP rs = ir->prev; | 432 | /* Overwrite tag with frame link. */ |
| 383 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) | 433 | o->fr.tp.ftsz = snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0; |
| 384 | rs = snap_renameref(T, snapno, ref, rs); | 434 | L->base = o+1; |
| 385 | if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ | ||
| 386 | int32_t *sps = &ex->spill[regsp_spill(rs)]; | ||
| 387 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) { | ||
| 388 | o->u32.lo = (uint32_t)*sps; | ||
| 389 | } else if (irt_isinteger(t)) { | ||
| 390 | setintV(o, *sps); | ||
| 391 | #if !LJ_SOFTFP | ||
| 392 | } else if (irt_isnum(t)) { | ||
| 393 | o->u64 = *(uint64_t *)sps; | ||
| 394 | #endif | ||
| 395 | #if LJ_64 | ||
| 396 | } else if (irt_islightud(t)) { | ||
| 397 | /* 64 bit lightuserdata which may escape already has the tag bits. */ | ||
| 398 | o->u64 = *(uint64_t *)sps; | ||
| 399 | #endif | ||
| 400 | } else { | ||
| 401 | lua_assert(!irt_ispri(t)); /* PRI refs never have a spill slot. */ | ||
| 402 | setgcrefi(o->gcr, *sps); | ||
| 403 | setitype(o, irt_toitype(t)); | ||
| 404 | } | ||
| 405 | } else { /* Restore from register. */ | ||
| 406 | Reg r = regsp_reg(rs); | ||
| 407 | lua_assert(ra_hasreg(r)); | ||
| 408 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) { | ||
| 409 | o->u32.lo = (uint32_t)ex->gpr[r-RID_MIN_GPR]; | ||
| 410 | } else if (irt_isinteger(t)) { | ||
| 411 | setintV(o, (int32_t)ex->gpr[r-RID_MIN_GPR]); | ||
| 412 | #if !LJ_SOFTFP | ||
| 413 | } else if (irt_isnum(t)) { | ||
| 414 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); | ||
| 415 | #endif | ||
| 416 | #if LJ_64 | ||
| 417 | } else if (irt_islightud(t)) { | ||
| 418 | /* 64 bit lightuserdata which may escape already has the tag bits. */ | ||
| 419 | o->u64 = ex->gpr[r-RID_MIN_GPR]; | ||
| 420 | #endif | ||
| 421 | } else { | ||
| 422 | if (!irt_ispri(t)) | ||
| 423 | setgcrefi(o->gcr, ex->gpr[r-RID_MIN_GPR]); | ||
| 424 | setitype(o, irt_toitype(t)); | ||
| 425 | } | ||
| 426 | } | 435 | } |
| 427 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) { | ||
| 428 | rs = (ir+1)->prev; | ||
| 429 | if (LJ_UNLIKELY(bloomtest(rfilt, ref+1))) | ||
| 430 | rs = snap_renameref(T, snapno, ref+1, rs); | ||
| 431 | o->u32.hi = (ra_hasspill(regsp_spill(rs))) ? | ||
| 432 | (uint32_t)*&ex->spill[regsp_spill(rs)] : | ||
| 433 | (uint32_t)ex->gpr[regsp_reg(rs)-RID_MIN_GPR]; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | if ((sn & (SNAP_CONT|SNAP_FRAME))) { /* Overwrite tag with frame link. */ | ||
| 437 | o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks-- : ftsz0; | ||
| 438 | L->base = o+1; | ||
| 439 | } | 436 | } |
| 440 | } | 437 | } |
| 438 | lua_assert(map + nent == flinks); | ||
| 439 | |||
| 440 | /* Compute current stack top. */ | ||
| 441 | switch (bc_op(*pc)) { | 441 | switch (bc_op(*pc)) { |
| 442 | case BC_CALLM: case BC_CALLMT: case BC_RETM: case BC_TSETM: | 442 | case BC_CALLM: case BC_CALLMT: case BC_RETM: case BC_TSETM: |
| 443 | L->top = frame + snap->nslots; | 443 | L->top = frame + snap->nslots; |
| @@ -446,7 +446,6 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
| 446 | L->top = curr_topL(L); | 446 | L->top = curr_topL(L); |
| 447 | break; | 447 | break; |
| 448 | } | 448 | } |
| 449 | lua_assert(map + nent == flinks); | ||
| 450 | return pc; | 449 | return pc; |
| 451 | } | 450 | } |
| 452 | 451 | ||
