aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2010-01-27 03:50:29 +0100
committerMike Pall <mike>2010-01-27 03:50:29 +0100
commit3aeb89226202439c0be07830ae6e71007a7b5dd3 (patch)
tree77789041551fc1b5bcb2eb69c85e9b221a49d578
parentd216cdb2b9eb41879cdfc327486d805cc260d8fa (diff)
downloadluajit-3aeb89226202439c0be07830ae6e71007a7b5dd3.tar.gz
luajit-3aeb89226202439c0be07830ae6e71007a7b5dd3.tar.bz2
luajit-3aeb89226202439c0be07830ae6e71007a7b5dd3.zip
Eliminate IR_FRAME. Replace with KGC and TRef/SnapEntry flags.
-rw-r--r--src/lj_asm.c67
-rw-r--r--src/lj_ir.h8
-rw-r--r--src/lj_record.c54
-rw-r--r--src/lj_snap.c57
4 files changed, 81 insertions, 105 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 3912bbeb..48b6ec5a 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -931,7 +931,7 @@ static void asm_snap_alloc(ASMState *as)
931 IRRef ref = snap_ref(map[n]); 931 IRRef ref = snap_ref(map[n]);
932 if (!irref_isk(ref)) { 932 if (!irref_isk(ref)) {
933 IRIns *ir = IR(ref); 933 IRIns *ir = IR(ref);
934 if (!ra_used(ir) && ir->o != IR_FRAME) { 934 if (!ra_used(ir)) {
935 RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR; 935 RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
936 /* Not a var-to-invar ref and got a free register (or a remat)? */ 936 /* Not a var-to-invar ref and got a free register (or a remat)? */
937 if ((!iscrossref(as, ref) || irt_isphi(ir->t)) && 937 if ((!iscrossref(as, ref) || irt_isphi(ir->t)) &&
@@ -2831,27 +2831,25 @@ static void asm_head_side(ASMState *as)
2831 /* Scan all parent SLOADs and collect register dependencies. */ 2831 /* Scan all parent SLOADs and collect register dependencies. */
2832 for (i = as->curins; i > REF_BASE; i--) { 2832 for (i = as->curins; i > REF_BASE; i--) {
2833 IRIns *ir = IR(i); 2833 IRIns *ir = IR(i);
2834 lua_assert((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) || 2834 RegSP rs;
2835 ir->o == IR_FRAME); 2835 lua_assert(ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT));
2836 if (ir->o == IR_SLOAD) { 2836 rs = as->parentmap[ir->op1];
2837 RegSP rs = as->parentmap[ir->op1]; 2837 if (ra_hasreg(ir->r)) {
2838 if (ra_hasreg(ir->r)) { 2838 rset_clear(allow, ir->r);
2839 rset_clear(allow, ir->r); 2839 if (ra_hasspill(ir->s))
2840 if (ra_hasspill(ir->s)) 2840 ra_save(as, ir, ir->r);
2841 ra_save(as, ir, ir->r); 2841 } else if (ra_hasspill(ir->s)) {
2842 } else if (ra_hasspill(ir->s)) { 2842 irt_setmark(ir->t);
2843 irt_setmark(ir->t); 2843 pass2 = 1;
2844 pass2 = 1; 2844 }
2845 } 2845 if (ir->r == rs) { /* Coalesce matching registers right now. */
2846 if (ir->r == rs) { /* Coalesce matching registers right now. */ 2846 ra_free(as, ir->r);
2847 ra_free(as, ir->r); 2847 } else if (ra_hasspill(regsp_spill(rs))) {
2848 } else if (ra_hasspill(regsp_spill(rs))) { 2848 if (ra_hasreg(ir->r))
2849 if (ra_hasreg(ir->r)) 2849 pass3 = 1;
2850 pass3 = 1; 2850 } else if (ra_used(ir)) {
2851 } else if (ra_used(ir)) { 2851 sloadins[rs] = (IRRef1)i;
2852 sloadins[rs] = (IRRef1)i; 2852 rset_set(live, rs); /* Block live parent register. */
2853 rset_set(live, rs); /* Block live parent register. */
2854 }
2855 } 2853 }
2856 } 2854 }
2857 2855
@@ -2979,8 +2977,7 @@ static void asm_tail_sync(ASMState *as)
2979 SnapEntry sn = map[n]; 2977 SnapEntry sn = map[n];
2980 if ((sn & SNAP_FRAME)) { 2978 if ((sn & SNAP_FRAME)) {
2981 IRIns *ir = IR(snap_ref(sn)); 2979 IRIns *ir = IR(snap_ref(sn));
2982 GCfunc *fn = ir_kfunc(IR(ir->op2)); 2980 GCfunc *fn = ir_kfunc(ir);
2983 lua_assert(ir->o == IR_FRAME && irt_isfunc(ir->t));
2984 if (isluafunc(fn)) { 2981 if (isluafunc(fn)) {
2985 BCReg s = snap_slot(sn); 2982 BCReg s = snap_slot(sn);
2986 BCReg fs = s + funcproto(fn)->framesize; 2983 BCReg fs = s + funcproto(fn)->framesize;
@@ -3019,9 +3016,10 @@ static void asm_tail_sync(ASMState *as)
3019 3016
3020 /* Store the value of all modified slots to the Lua stack. */ 3017 /* Store the value of all modified slots to the Lua stack. */
3021 for (n = 0; n < nent; n++) { 3018 for (n = 0; n < nent; n++) {
3022 BCReg s = snap_slot(map[n]); 3019 SnapEntry sn = map[n];
3020 BCReg s = snap_slot(sn);
3023 int32_t ofs = 8*((int32_t)s-1); 3021 int32_t ofs = 8*((int32_t)s-1);
3024 IRRef ref = snap_ref(map[n]); 3022 IRRef ref = snap_ref(sn);
3025 IRIns *ir = IR(ref); 3023 IRIns *ir = IR(ref);
3026 /* No need to restore readonly slots and unmodified non-parent slots. */ 3024 /* No need to restore readonly slots and unmodified non-parent slots. */
3027 if (ir->o == IR_SLOAD && ir->op1 == s && 3025 if (ir->o == IR_SLOAD && ir->op1 == s &&
@@ -3030,10 +3028,6 @@ static void asm_tail_sync(ASMState *as)
3030 if (irt_isnum(ir->t)) { 3028 if (irt_isnum(ir->t)) {
3031 Reg src = ra_alloc1(as, ref, RSET_FPR); 3029 Reg src = ra_alloc1(as, ref, RSET_FPR);
3032 emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs); 3030 emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs);
3033 } else if (ir->o == IR_FRAME) {
3034 emit_movmroi(as, RID_BASE, ofs, ptr2addr(ir_kgc(IR(ir->op2))));
3035 if (s != 0) /* Do not overwrite link to previous frame. */
3036 emit_movmroi(as, RID_BASE, ofs+4, (int32_t)(*--flinks));
3037 } else { 3031 } else {
3038 lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t)); 3032 lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t));
3039 if (!irref_isk(ref)) { 3033 if (!irref_isk(ref)) {
@@ -3042,7 +3036,10 @@ static void asm_tail_sync(ASMState *as)
3042 } else if (!irt_ispri(ir->t)) { 3036 } else if (!irt_ispri(ir->t)) {
3043 emit_movmroi(as, RID_BASE, ofs, ir->i); 3037 emit_movmroi(as, RID_BASE, ofs, ir->i);
3044 } 3038 }
3045 emit_movmroi(as, RID_BASE, ofs+4, irt_toitype(ir->t)); 3039 if (!(sn & (SNAP_CONT|SNAP_FRAME)))
3040 emit_movmroi(as, RID_BASE, ofs+4, irt_toitype(ir->t));
3041 else if (s != 0) /* Do not overwrite link to previous frame. */
3042 emit_movmroi(as, RID_BASE, ofs+4, (int32_t)(*--flinks));
3046 } 3043 }
3047 checkmclim(as); 3044 checkmclim(as);
3048 } 3045 }
@@ -3110,10 +3107,6 @@ static void asm_ir(ASMState *as, IRIns *ir)
3110 case IR_ULE: asm_comp(as, ir, CC_A, CC_A, VCC_U); break; 3107 case IR_ULE: asm_comp(as, ir, CC_A, CC_A, VCC_U); break;
3111 case IR_ABC: 3108 case IR_ABC:
3112 case IR_UGT: asm_comp(as, ir, CC_BE, CC_BE, VCC_U|VCC_PS); break; 3109 case IR_UGT: asm_comp(as, ir, CC_BE, CC_BE, VCC_U|VCC_PS); break;
3113
3114 case IR_FRAME:
3115 if (ir->op1 == ir->op2) break; /* No check needed for placeholder. */
3116 /* fallthrough */
3117 case IR_EQ: asm_comp(as, ir, CC_NE, CC_NE, VCC_P); break; 3110 case IR_EQ: asm_comp(as, ir, CC_NE, CC_NE, VCC_P); break;
3118 case IR_NE: asm_comp(as, ir, CC_E, CC_E, VCC_U|VCC_P); break; 3111 case IR_NE: asm_comp(as, ir, CC_E, CC_E, VCC_U|VCC_P); break;
3119 3112
@@ -3272,10 +3265,6 @@ static void asm_setup_regsp(ASMState *as, Trace *T)
3272 } 3265 }
3273 } 3266 }
3274 break; 3267 break;
3275 case IR_FRAME:
3276 if (i == as->stopins+1 && ir->op1 == ir->op2)
3277 as->stopins++;
3278 break;
3279 case IR_CALLN: case IR_CALLL: case IR_CALLS: { 3268 case IR_CALLN: case IR_CALLL: case IR_CALLS: {
3280 const CCallInfo *ci = &lj_ir_callinfo[ir->op2]; 3269 const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
3281 /* NYI: not fastcall-aware, but doesn't matter (yet). */ 3270 /* NYI: not fastcall-aware, but doesn't matter (yet). */
diff --git a/src/lj_ir.h b/src/lj_ir.h
index 672aca4a..34c14519 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -34,7 +34,7 @@
34 _(NE, GC, ref, ref) \ 34 _(NE, GC, ref, ref) \
35 \ 35 \
36 _(ABC, G , ref, ref) \ 36 _(ABC, G , ref, ref) \
37 _(FRAME, G , ref, ref) \ 37 _(UNUSED, G , ref, ref) /* Placeholder. */ \
38 \ 38 \
39 _(LT, G , ref, ref) \ 39 _(LT, G , ref, ref) \
40 _(GE, G , ref, ref) \ 40 _(GE, G , ref, ref) \
@@ -511,11 +511,11 @@ typedef union IRIns {
511 MRef ptr; /* Pointer constant (overlaps op12). */ 511 MRef ptr; /* Pointer constant (overlaps op12). */
512} IRIns; 512} IRIns;
513 513
514#define ir_kgc(ir) (gcref((ir)->gcr)) 514#define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)->gcr))
515#define ir_kstr(ir) (gco2str(ir_kgc((ir)))) 515#define ir_kstr(ir) (gco2str(ir_kgc((ir))))
516#define ir_ktab(ir) (gco2tab(ir_kgc((ir)))) 516#define ir_ktab(ir) (gco2tab(ir_kgc((ir))))
517#define ir_kfunc(ir) (gco2func(ir_kgc((ir)))) 517#define ir_kfunc(ir) (gco2func(ir_kgc((ir))))
518#define ir_knum(ir) (mref((ir)->ptr, cTValue)) 518#define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue))
519#define ir_kptr(ir) (mref((ir)->ptr, void)) 519#define ir_kptr(ir) check_exp((ir)->o == IR_KPTR, mref((ir)->ptr, void))
520 520
521#endif 521#endif
diff --git a/src/lj_record.c b/src/lj_record.c
index 94ea42ed..7b2e977e 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -148,15 +148,10 @@ static TRef sload(jit_State *J, int32_t slot)
148/* Get TRef for current function. */ 148/* Get TRef for current function. */
149static TRef getcurrf(jit_State *J) 149static TRef getcurrf(jit_State *J)
150{ 150{
151 if (J->base[-1]) { 151 if (J->base[-1])
152 IRIns *ir = IR(tref_ref(J->base[-1]));
153 if (ir->o == IR_FRAME) /* Shortcut if already specialized. */
154 return TREF(ir->op2, IRT_FUNC); /* Return TRef of KFUNC. */
155 return J->base[-1]; 152 return J->base[-1];
156 } else { 153 lua_assert(J->baseslot == 1);
157 lua_assert(J->baseslot == 1); 154 return sloadt(J, -1, IRT_FUNC, IRSLOAD_READONLY);
158 return sloadt(J, -1, IRT_FUNC, IRSLOAD_READONLY);
159 }
160} 155}
161 156
162/* Compare for raw object equality. 157/* Compare for raw object equality.
@@ -424,7 +419,7 @@ static BCReg rec_mm_prep(jit_State *J, ASMFunction cont)
424#else 419#else
425 trcont = lj_ir_kptr(J, (void *)cont); 420 trcont = lj_ir_kptr(J, (void *)cont);
426#endif 421#endif
427 J->base[top] = emitir(IRTG(IR_FRAME, IRT_PTR), trcont, trcont) | TREF_CONT; 422 J->base[top] = trcont | TREF_CONT;
428 for (s = J->maxslot; s < top; s++) 423 for (s = J->maxslot; s < top; s++)
429 J->base[s] = TREF_NIL; 424 J->base[s] = TREF_NIL;
430 return top+1; 425 return top+1;
@@ -1586,7 +1581,7 @@ static void check_call_unroll(jit_State *J, GCfunc *fn)
1586static int rec_call(jit_State *J, BCReg func, int cres, int nargs) 1581static int rec_call(jit_State *J, BCReg func, int cres, int nargs)
1587{ 1582{
1588 RecordFFData rd; 1583 RecordFFData rd;
1589 TRef *res = &J->base[func]; 1584 TRef trfunc, *res = &J->base[func];
1590 TValue *tv = &J->L->base[func]; 1585 TValue *tv = &J->L->base[func];
1591 1586
1592 if (tref_isfunc(res[0])) { /* Regular function call. */ 1587 if (tref_isfunc(res[0])) { /* Regular function call. */
@@ -1608,7 +1603,9 @@ static int rec_call(jit_State *J, BCReg func, int cres, int nargs)
1608 } 1603 }
1609 1604
1610 /* Specialize to the runtime value of the called function. */ 1605 /* Specialize to the runtime value of the called function. */
1611 res[0] = emitir(IRTG(IR_FRAME, IRT_FUNC), res[0], lj_ir_kfunc(J, rd.fn)) | TREF_FRAME; 1606 trfunc = lj_ir_kfunc(J, rd.fn);
1607 emitir(IRTG(IR_EQ, IRT_FUNC), res[0], trfunc);
1608 res[0] = trfunc | TREF_FRAME;
1612 1609
1613 if (isluafunc(rd.fn)) { /* Record call to Lua function. */ 1610 if (isluafunc(rd.fn)) { /* Record call to Lua function. */
1614 GCproto *pt = funcproto(rd.fn); 1611 GCproto *pt = funcproto(rd.fn);
@@ -2175,12 +2172,7 @@ static void rec_setup_side(jit_State *J, Trace *T)
2175 for (j = 0; j < n; j++) 2172 for (j = 0; j < n; j++)
2176 if (snap_ref(map[j]) == ref) { 2173 if (snap_ref(map[j]) == ref) {
2177 tr = J->slot[snap_slot(map[j])]; 2174 tr = J->slot[snap_slot(map[j])];
2178 if (ir->o == IR_FRAME && irt_isfunc(ir->t)) { 2175 goto setslot;
2179 lua_assert(s != 0);
2180 J->baseslot = s+1;
2181 J->framedepth++;
2182 }
2183 goto dupslot;
2184 } 2176 }
2185 } 2177 }
2186 bloomset(seen, ref); 2178 bloomset(seen, ref);
@@ -2190,30 +2182,24 @@ static void rec_setup_side(jit_State *J, Trace *T)
2190 case IR_KINT: tr = lj_ir_kint(J, ir->i); break; 2182 case IR_KINT: tr = lj_ir_kint(J, ir->i); break;
2191 case IR_KGC: tr = lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); break; 2183 case IR_KGC: tr = lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); break;
2192 case IR_KNUM: tr = lj_ir_knum_addr(J, ir_knum(ir)); break; 2184 case IR_KNUM: tr = lj_ir_knum_addr(J, ir_knum(ir)); break;
2193 case IR_FRAME: /* Placeholder FRAMEs don't need a guard. */ 2185 case IR_KPTR: tr = lj_ir_kptr(J, ir_kptr(ir)); break; /* Continuation. */
2194 if (irt_isfunc(ir->t)) { 2186 /* Inherited SLOADs don't need a guard or type check. */
2195 if (s != 0) { 2187 case IR_SLOAD:
2196 J->baseslot = s+1;
2197 J->framedepth++;
2198 }
2199 tr = lj_ir_kfunc(J, ir_kfunc(&T->ir[ir->op2]));
2200 tr = emitir_raw(IRT(IR_FRAME, IRT_FUNC), tr, tr) | TREF_FRAME;
2201 } else {
2202 tr = lj_ir_kptr(J, mref(T->ir[ir->op2].ptr, void));
2203 tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr) | TREF_CONT;
2204 }
2205 break;
2206 case IR_SLOAD: /* Inherited SLOADs don't need a guard or type check. */
2207 tr = emitir_raw(ir->ot & ~IRT_GUARD, s, 2188 tr = emitir_raw(ir->ot & ~IRT_GUARD, s,
2208 (ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT); 2189 (ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT);
2209 break; 2190 break;
2210 default: /* Parent refs are already typed and don't need a guard. */ 2191 /* Parent refs are already typed and don't need a guard. */
2192 default:
2211 tr = emitir_raw(IRT(IR_SLOAD, irt_type(ir->t)), s, 2193 tr = emitir_raw(IRT(IR_SLOAD, irt_type(ir->t)), s,
2212 IRSLOAD_INHERIT|IRSLOAD_PARENT); 2194 IRSLOAD_INHERIT|IRSLOAD_PARENT);
2213 break; 2195 break;
2214 } 2196 }
2215 dupslot: 2197 setslot:
2216 J->slot[s] = tr; 2198 J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */
2199 if ((sn & SNAP_FRAME) && s != 0) {
2200 J->baseslot = s+1;
2201 J->framedepth++;
2202 }
2217 } 2203 }
2218 J->base = J->slot + J->baseslot; 2204 J->base = J->slot + J->baseslot;
2219 J->maxslot = snap->nslots - J->baseslot; 2205 J->maxslot = snap->nslots - J->baseslot;
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 }