diff options
Diffstat (limited to 'src/lj_snap.c')
-rw-r--r-- | src/lj_snap.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/lj_snap.c b/src/lj_snap.c index 3371375a..c04d622d 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -351,6 +351,70 @@ IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir) | |||
351 | return ir; | 351 | return ir; |
352 | } | 352 | } |
353 | 353 | ||
354 | /* -- Snapshot replay ----------------------------------------------------- */ | ||
355 | |||
356 | /* Replay constant from parent trace. */ | ||
357 | static TRef snap_replay_const(jit_State *J, IRIns *ir) | ||
358 | { | ||
359 | /* Only have to deal with constants that can occur in stack slots. */ | ||
360 | switch ((IROp)ir->o) { | ||
361 | case IR_KPRI: return TREF_PRI(irt_type(ir->t)); | ||
362 | case IR_KINT: return lj_ir_kint(J, ir->i); | ||
363 | case IR_KGC: return lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); | ||
364 | case IR_KNUM: return lj_ir_k64(J, IR_KNUM, ir_knum(ir)); | ||
365 | case IR_KINT64: return lj_ir_k64(J, IR_KINT64, ir_kint64(ir)); | ||
366 | case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir)); /* Continuation. */ | ||
367 | default: lua_assert(0); return TREF_NIL; break; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | /* Replay snapshot state to setup side trace. */ | ||
372 | void lj_snap_replay(jit_State *J, GCtrace *T) | ||
373 | { | ||
374 | SnapShot *snap = &T->snap[J->exitno]; | ||
375 | SnapEntry *map = &T->snapmap[snap->mapofs]; | ||
376 | MSize n, nent = snap->nent; | ||
377 | BloomFilter seen = 0; | ||
378 | J->framedepth = 0; | ||
379 | /* Emit IR for slots inherited from parent snapshot. */ | ||
380 | for (n = 0; n < nent; n++) { | ||
381 | SnapEntry sn = map[n]; | ||
382 | BCReg s = snap_slot(sn); | ||
383 | IRRef ref = snap_ref(sn); | ||
384 | IRIns *ir = &T->ir[ref]; | ||
385 | TRef tr; | ||
386 | /* The bloom filter avoids O(nent^2) overhead for de-duping slots. */ | ||
387 | if (bloomtest(seen, ref)) { | ||
388 | MSize j; | ||
389 | for (j = 0; j < n; j++) | ||
390 | if (snap_ref(map[j]) == ref) { | ||
391 | tr = J->slot[snap_slot(map[j])]; | ||
392 | goto setslot; | ||
393 | } | ||
394 | } | ||
395 | bloomset(seen, ref); | ||
396 | if (irref_isk(ref)) { | ||
397 | tr = snap_replay_const(J, ir); | ||
398 | } else { | ||
399 | IRType t = irt_type(ir->t); | ||
400 | uint32_t mode = IRSLOAD_INHERIT|IRSLOAD_PARENT; | ||
401 | lua_assert(regsp_used(ir->prev)); | ||
402 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM; | ||
403 | if (ir->o == IR_SLOAD) mode |= (ir->op2 & IRSLOAD_READONLY); | ||
404 | tr = emitir_raw(IRT(IR_SLOAD, t), s, mode); | ||
405 | } | ||
406 | setslot: | ||
407 | J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */ | ||
408 | J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && s); | ||
409 | if ((sn & SNAP_FRAME)) | ||
410 | J->baseslot = s+1; | ||
411 | } | ||
412 | J->base = J->slot + J->baseslot; | ||
413 | J->maxslot = snap->nslots - J->baseslot; | ||
414 | } | ||
415 | |||
416 | /* -- Snapshot restore ---------------------------------------------------- */ | ||
417 | |||
354 | /* Restore a value from the trace exit state. */ | 418 | /* Restore a value from the trace exit state. */ |
355 | static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, | 419 | static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, |
356 | SnapNo snapno, BloomFilter rfilt, | 420 | SnapNo snapno, BloomFilter rfilt, |