summaryrefslogtreecommitdiff
path: root/src/lj_snap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_snap.c')
-rw-r--r--src/lj_snap.c57
1 files changed, 29 insertions, 28 deletions
diff --git a/src/lj_snap.c b/src/lj_snap.c
index 731b8f92..8a53e3f6 100644
--- a/src/lj_snap.c
+++ b/src/lj_snap.c
@@ -211,6 +211,7 @@ void lj_snap_restore(jit_State *J, void *exptr)
211 MSize n, nent = snap->nent; 211 MSize n, nent = snap->nent;
212 SnapEntry *map = &T->snapmap[snap->mapofs]; 212 SnapEntry *map = &T->snapmap[snap->mapofs];
213 SnapEntry *flinks = map + nent + snap->nframelinks; 213 SnapEntry *flinks = map + nent + snap->nframelinks;
214 int32_t ftsz0;
214 BCReg nslots = snap->nslots; 215 BCReg nslots = snap->nslots;
215 TValue *frame; 216 TValue *frame;
216 BloomFilter rfilt = snap_renamefilter(T, snapno); 217 BloomFilter rfilt = snap_renamefilter(T, snapno);
@@ -224,6 +225,7 @@ void lj_snap_restore(jit_State *J, void *exptr)
224 225
225 /* Fill stack slots with data from the registers and spill slots. */ 226 /* Fill stack slots with data from the registers and spill slots. */
226 frame = L->base-1; 227 frame = L->base-1;
228 ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */
227 for (n = 0; n < nent; n++) { 229 for (n = 0; n < nent; n++) {
228 SnapEntry sn = map[n]; 230 SnapEntry sn = map[n];
229 IRRef ref = snap_ref(sn); 231 IRRef ref = snap_ref(sn);
@@ -232,9 +234,34 @@ void lj_snap_restore(jit_State *J, void *exptr)
232 IRIns *ir = &T->ir[ref]; 234 IRIns *ir = &T->ir[ref];
233 if (irref_isk(ref)) { /* Restore constant slot. */ 235 if (irref_isk(ref)) { /* Restore constant slot. */
234 lj_ir_kvalue(L, o, ir); 236 lj_ir_kvalue(L, o, ir);
237 if ((sn & (SNAP_CONT|SNAP_FRAME))) {
238 /* Overwrite tag with frame link. */
239 o->fr.tp.ftsz = s != 0 ? (int32_t)*--flinks : ftsz0;
240 if ((sn & SNAP_FRAME)) {
241 GCfunc *fn = ir_kfunc(ir);
242 if (isluafunc(fn)) {
243 MSize framesize = funcproto(fn)->framesize;
244 TValue *fs;
245 L->base = ++o;
246 if (LJ_UNLIKELY(o + framesize > L->maxstack)) { /* Grow again? */
247 ptrdiff_t fsave = savestack(L, frame);
248 L->top = o;
249 lj_state_growstack(L, framesize);
250 frame = restorestack(L, fsave);
251 o = L->top;
252 }
253 fs = o + framesize;
254 if (s == 0) /* Only partially clear tail call frame at #0. */
255 o = &frame[nslots];
256 while (o < fs) /* Clear slots of newly added frames. */
257 setnilV(o++);
258 }
259 }
260 }
235 } else { 261 } else {
236 IRType1 t = ir->t; 262 IRType1 t = ir->t;
237 RegSP rs = ir->prev; 263 RegSP rs = ir->prev;
264 lua_assert(!(sn & (SNAP_CONT|SNAP_FRAME)));
238 if (LJ_UNLIKELY(bloomtest(rfilt, ref))) 265 if (LJ_UNLIKELY(bloomtest(rfilt, ref)))
239 rs = snap_renameref(T, snapno, ref, rs); 266 rs = snap_renameref(T, snapno, ref, rs);
240 if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ 267 if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */
@@ -248,8 +275,9 @@ void lj_snap_restore(jit_State *J, void *exptr)
248 setgcrefi(o->gcr, *sps); 275 setgcrefi(o->gcr, *sps);
249 setitype(o, irt_toitype(t)); 276 setitype(o, irt_toitype(t));
250 } 277 }
251 } else if (ra_hasreg(regsp_reg(rs))) { /* Restore from register. */ 278 } else { /* Restore from register. */
252 Reg r = regsp_reg(rs); 279 Reg r = regsp_reg(rs);
280 lua_assert(ra_hasreg(r));
253 if (irt_isinteger(t)) { 281 if (irt_isinteger(t)) {
254 setintV(o, ex->gpr[r-RID_MIN_GPR]); 282 setintV(o, ex->gpr[r-RID_MIN_GPR]);
255 } else if (irt_isnum(t)) { 283 } else if (irt_isnum(t)) {
@@ -259,33 +287,6 @@ void lj_snap_restore(jit_State *J, void *exptr)
259 setgcrefi(o->gcr, ex->gpr[r-RID_MIN_GPR]); 287 setgcrefi(o->gcr, ex->gpr[r-RID_MIN_GPR]);
260 setitype(o, irt_toitype(t)); 288 setitype(o, irt_toitype(t));
261 } 289 }
262 } else { /* Restore frame slot. */
263 lua_assert((sn & (SNAP_CONT|SNAP_FRAME)));
264 lua_assert(ir->o == IR_FRAME);
265 /* This works for both PTR and FUNC IR_FRAME. */
266 setgcrefp(o->fr.func, mref(T->ir[ir->op2].ptr, void));
267 if (s != 0) /* Do not overwrite link to previous frame. */
268 o->fr.tp.ftsz = (int32_t)*--flinks;
269 if (irt_isfunc(ir->t)) {
270 GCfunc *fn = gco2func(gcref(T->ir[ir->op2].gcr));
271 if (isluafunc(fn)) {
272 MSize framesize = funcproto(fn)->framesize;
273 TValue *fs;
274 L->base = ++o;
275 if (LJ_UNLIKELY(o + framesize > L->maxstack)) { /* Grow again? */
276 ptrdiff_t fsave = savestack(L, frame);
277 L->top = o;
278 lj_state_growstack(L, framesize);
279 frame = restorestack(L, fsave);
280 o = L->top;
281 }
282 fs = o + framesize;
283 if (s == 0) /* Only partially clear tail call frame at #0. */
284 o = &frame[nslots];
285 while (o < fs) /* Clear slots of newly added frames. */
286 setnilV(o++);
287 }
288 }
289 } 290 }
290 } 291 }
291 } 292 }