diff options
Diffstat (limited to 'src/lj_snap.c')
-rw-r--r-- | src/lj_snap.c | 57 |
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 | } |