diff options
-rw-r--r-- | src/lj_asm.c | 67 | ||||
-rw-r--r-- | src/lj_ir.h | 8 | ||||
-rw-r--r-- | src/lj_record.c | 54 | ||||
-rw-r--r-- | src/lj_snap.c | 57 |
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. */ |
149 | static TRef getcurrf(jit_State *J) | 149 | static 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) | |||
1586 | static int rec_call(jit_State *J, BCReg func, int cres, int nargs) | 1581 | static 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 | } |