diff options
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 231 |
1 files changed, 149 insertions, 82 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index 3b754897..f0481050 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -87,30 +87,48 @@ static void rec_check_slots(jit_State *J) | |||
87 | BCReg s, nslots = J->baseslot + J->maxslot; | 87 | BCReg s, nslots = J->baseslot + J->maxslot; |
88 | int32_t depth = 0; | 88 | int32_t depth = 0; |
89 | cTValue *base = J->L->base - J->baseslot; | 89 | cTValue *base = J->L->base - J->baseslot; |
90 | lua_assert(J->baseslot >= 1 && J->baseslot < LJ_MAX_JSLOTS); | 90 | lua_assert(J->baseslot >= 1+LJ_FR2 && J->baseslot < LJ_MAX_JSLOTS); |
91 | lua_assert(J->baseslot == 1 || (J->slot[J->baseslot-1] & TREF_FRAME)); | 91 | lua_assert(J->baseslot == 1+LJ_FR2 || (J->slot[J->baseslot-1] & TREF_FRAME)); |
92 | lua_assert(nslots < LJ_MAX_JSLOTS); | 92 | lua_assert(nslots < LJ_MAX_JSLOTS); |
93 | for (s = 0; s < nslots; s++) { | 93 | for (s = 0; s < nslots; s++) { |
94 | TRef tr = J->slot[s]; | 94 | TRef tr = J->slot[s]; |
95 | if (tr) { | 95 | if (tr) { |
96 | cTValue *tv = &base[s]; | 96 | cTValue *tv = &base[s]; |
97 | IRRef ref = tref_ref(tr); | 97 | IRRef ref = tref_ref(tr); |
98 | IRIns *ir; | 98 | IRIns *ir = NULL; /* Silence compiler. */ |
99 | lua_assert(ref >= J->cur.nk && ref < J->cur.nins); | 99 | if (!LJ_FR2 || ref || !(tr & (TREF_FRAME | TREF_CONT))) { |
100 | ir = IR(ref); | 100 | lua_assert(ref >= J->cur.nk && ref < J->cur.nins); |
101 | lua_assert(irt_t(ir->t) == tref_t(tr)); | 101 | ir = IR(ref); |
102 | lua_assert(irt_t(ir->t) == tref_t(tr)); | ||
103 | } | ||
102 | if (s == 0) { | 104 | if (s == 0) { |
103 | lua_assert(tref_isfunc(tr)); | 105 | lua_assert(tref_isfunc(tr)); |
106 | #if LJ_FR2 | ||
107 | } else if (s == 1) { | ||
108 | lua_assert(0); | ||
109 | #endif | ||
104 | } else if ((tr & TREF_FRAME)) { | 110 | } else if ((tr & TREF_FRAME)) { |
105 | GCfunc *fn = gco2func(frame_gc(tv)); | 111 | GCfunc *fn = gco2func(frame_gc(tv)); |
106 | BCReg delta = (BCReg)(tv - frame_prev(tv)); | 112 | BCReg delta = (BCReg)(tv - frame_prev(tv)); |
113 | #if LJ_FR2 | ||
114 | if (ref) | ||
115 | lua_assert(ir_knum(ir)->u64 == tv->u64); | ||
116 | tr = J->slot[s-1]; | ||
117 | ir = IR(tref_ref(tr)); | ||
118 | #endif | ||
107 | lua_assert(tref_isfunc(tr)); | 119 | lua_assert(tref_isfunc(tr)); |
108 | if (tref_isk(tr)) lua_assert(fn == ir_kfunc(ir)); | 120 | if (tref_isk(tr)) lua_assert(fn == ir_kfunc(ir)); |
109 | lua_assert(s > delta ? (J->slot[s-delta] & TREF_FRAME) : (s == delta)); | 121 | lua_assert(s > delta + LJ_FR2 ? (J->slot[s-delta] & TREF_FRAME) |
122 | : (s == delta + LJ_FR2)); | ||
110 | depth++; | 123 | depth++; |
111 | } else if ((tr & TREF_CONT)) { | 124 | } else if ((tr & TREF_CONT)) { |
125 | #if LJ_FR2 | ||
126 | if (ref) | ||
127 | lua_assert(ir_knum(ir)->u64 == tv->u64); | ||
128 | #else | ||
112 | lua_assert(ir_kptr(ir) == gcrefp(tv->gcr, void)); | 129 | lua_assert(ir_kptr(ir) == gcrefp(tv->gcr, void)); |
113 | lua_assert((J->slot[s+1] & TREF_FRAME)); | 130 | #endif |
131 | lua_assert((J->slot[s+1+LJ_FR2] & TREF_FRAME)); | ||
114 | depth++; | 132 | depth++; |
115 | } else { | 133 | } else { |
116 | if (tvisnumber(tv)) | 134 | if (tvisnumber(tv)) |
@@ -162,10 +180,10 @@ static TRef sload(jit_State *J, int32_t slot) | |||
162 | /* Get TRef for current function. */ | 180 | /* Get TRef for current function. */ |
163 | static TRef getcurrf(jit_State *J) | 181 | static TRef getcurrf(jit_State *J) |
164 | { | 182 | { |
165 | if (J->base[-1]) | 183 | if (J->base[-1-LJ_FR2]) |
166 | return J->base[-1]; | 184 | return J->base[-1-LJ_FR2]; |
167 | lua_assert(J->baseslot == 1); | 185 | lua_assert(J->baseslot == 1+LJ_FR2); |
168 | return sloadt(J, -1, IRT_FUNC, IRSLOAD_READONLY); | 186 | return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY); |
169 | } | 187 | } |
170 | 188 | ||
171 | /* Compare for raw object equality. | 189 | /* Compare for raw object equality. |
@@ -509,7 +527,6 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl) | |||
509 | static LoopEvent rec_iterl(jit_State *J, const BCIns iterins) | 527 | static LoopEvent rec_iterl(jit_State *J, const BCIns iterins) |
510 | { | 528 | { |
511 | BCReg ra = bc_a(iterins); | 529 | BCReg ra = bc_a(iterins); |
512 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
513 | if (!tref_isnil(getslot(J, ra))) { /* Looping back? */ | 530 | if (!tref_isnil(getslot(J, ra))) { /* Looping back? */ |
514 | J->base[ra-1] = J->base[ra]; /* Copy result of ITERC to control var. */ | 531 | J->base[ra-1] = J->base[ra]; /* Copy result of ITERC to control var. */ |
515 | J->maxslot = ra-1+bc_b(J->pc[-1]); | 532 | J->maxslot = ra-1+bc_b(J->pc[-1]); |
@@ -678,22 +695,31 @@ static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs) | |||
678 | { | 695 | { |
679 | RecordIndex ix; | 696 | RecordIndex ix; |
680 | TValue *functv = &J->L->base[func]; | 697 | TValue *functv = &J->L->base[func]; |
681 | TRef *fbase = &J->base[func]; | 698 | TRef kfunc, *fbase = &J->base[func]; |
682 | ptrdiff_t i; | 699 | ptrdiff_t i; |
683 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | 700 | (void)getslot(J, func); /* Ensure func has a reference. */ |
684 | for (i = 0; i <= nargs; i++) | 701 | for (i = 1; i <= nargs; i++) |
685 | (void)getslot(J, func+i); /* Ensure func and all args have a reference. */ | 702 | (void)getslot(J, func+LJ_FR2+i); /* Ensure all args have a reference. */ |
686 | if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */ | 703 | if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */ |
687 | ix.tab = fbase[0]; | 704 | ix.tab = fbase[0]; |
688 | copyTV(J->L, &ix.tabv, functv); | 705 | copyTV(J->L, &ix.tabv, functv); |
689 | if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj)) | 706 | if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj)) |
690 | lj_trace_err(J, LJ_TRERR_NOMM); | 707 | lj_trace_err(J, LJ_TRERR_NOMM); |
691 | for (i = ++nargs; i > 0; i--) /* Shift arguments up. */ | 708 | for (i = ++nargs; i > LJ_FR2; i--) /* Shift arguments up. */ |
692 | fbase[i] = fbase[i-1]; | 709 | fbase[i+LJ_FR2] = fbase[i+LJ_FR2-1]; |
710 | #if LJ_FR2 | ||
711 | fbase[2] = fbase[0]; | ||
712 | #endif | ||
693 | fbase[0] = ix.mobj; /* Replace function. */ | 713 | fbase[0] = ix.mobj; /* Replace function. */ |
694 | functv = &ix.mobjv; | 714 | functv = &ix.mobjv; |
695 | } | 715 | } |
696 | fbase[0] = TREF_FRAME | rec_call_specialize(J, funcV(functv), fbase[0]); | 716 | kfunc = rec_call_specialize(J, funcV(functv), fbase[0]); |
717 | #if LJ_FR2 | ||
718 | fbase[0] = kfunc; | ||
719 | fbase[1] = TREF_FRAME; | ||
720 | #else | ||
721 | fbase[0] = kfunc | TREF_FRAME; | ||
722 | #endif | ||
697 | J->maxslot = (BCReg)nargs; | 723 | J->maxslot = (BCReg)nargs; |
698 | } | 724 | } |
699 | 725 | ||
@@ -703,8 +729,8 @@ void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs) | |||
703 | rec_call_setup(J, func, nargs); | 729 | rec_call_setup(J, func, nargs); |
704 | /* Bump frame. */ | 730 | /* Bump frame. */ |
705 | J->framedepth++; | 731 | J->framedepth++; |
706 | J->base += func+1; | 732 | J->base += func+1+LJ_FR2; |
707 | J->baseslot += func+1; | 733 | J->baseslot += func+1+LJ_FR2; |
708 | } | 734 | } |
709 | 735 | ||
710 | /* Record tail call. */ | 736 | /* Record tail call. */ |
@@ -720,7 +746,9 @@ void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs) | |||
720 | func += cbase; | 746 | func += cbase; |
721 | } | 747 | } |
722 | /* Move func + args down. */ | 748 | /* Move func + args down. */ |
723 | memmove(&J->base[-1], &J->base[func], sizeof(TRef)*(J->maxslot+1)); | 749 | if (LJ_FR2 && J->baseslot == 2) |
750 | J->base[func+1] = 0; | ||
751 | memmove(&J->base[-1-LJ_FR2], &J->base[func], sizeof(TRef)*(J->maxslot+1+LJ_FR2)); | ||
724 | /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */ | 752 | /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */ |
725 | /* Tailcalls can form a loop, so count towards the loop unroll limit. */ | 753 | /* Tailcalls can form a loop, so count towards the loop unroll limit. */ |
726 | if (++J->tailcalled > J->loopunroll) | 754 | if (++J->tailcalled > J->loopunroll) |
@@ -763,7 +791,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
763 | BCReg cbase = (BCReg)frame_delta(frame); | 791 | BCReg cbase = (BCReg)frame_delta(frame); |
764 | if (--J->framedepth < 0) | 792 | if (--J->framedepth < 0) |
765 | lj_trace_err(J, LJ_TRERR_NYIRETL); | 793 | lj_trace_err(J, LJ_TRERR_NYIRETL); |
766 | lua_assert(J->baseslot > 1); | 794 | lua_assert(J->baseslot > 1+LJ_FR2); |
767 | gotresults++; | 795 | gotresults++; |
768 | rbase += cbase; | 796 | rbase += cbase; |
769 | J->baseslot -= (BCReg)cbase; | 797 | J->baseslot -= (BCReg)cbase; |
@@ -787,7 +815,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
787 | BCReg cbase = (BCReg)frame_delta(frame); | 815 | BCReg cbase = (BCReg)frame_delta(frame); |
788 | if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */ | 816 | if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */ |
789 | lj_trace_err(J, LJ_TRERR_NYIRETL); | 817 | lj_trace_err(J, LJ_TRERR_NYIRETL); |
790 | lua_assert(J->baseslot > 1); | 818 | lua_assert(J->baseslot > 1+LJ_FR2); |
791 | rbase += cbase; | 819 | rbase += cbase; |
792 | J->baseslot -= (BCReg)cbase; | 820 | J->baseslot -= (BCReg)cbase; |
793 | J->base -= cbase; | 821 | J->base -= cbase; |
@@ -797,8 +825,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
797 | BCIns callins = *(frame_pc(frame)-1); | 825 | BCIns callins = *(frame_pc(frame)-1); |
798 | ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults; | 826 | ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults; |
799 | BCReg cbase = bc_a(callins); | 827 | BCReg cbase = bc_a(callins); |
800 | GCproto *pt = funcproto(frame_func(frame - (cbase+1-LJ_FR2))); | 828 | GCproto *pt = funcproto(frame_func(frame - (cbase+1+LJ_FR2))); |
801 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame teardown. */ | ||
802 | if ((pt->flags & PROTO_NOJIT)) | 829 | if ((pt->flags & PROTO_NOJIT)) |
803 | lj_trace_err(J, LJ_TRERR_CJITOFF); | 830 | lj_trace_err(J, LJ_TRERR_CJITOFF); |
804 | if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) { | 831 | if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) { |
@@ -811,13 +838,13 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
811 | lj_snap_add(J); | 838 | lj_snap_add(J); |
812 | } | 839 | } |
813 | for (i = 0; i < nresults; i++) /* Adjust results. */ | 840 | for (i = 0; i < nresults; i++) /* Adjust results. */ |
814 | J->base[i-1] = i < gotresults ? J->base[rbase+i] : TREF_NIL; | 841 | J->base[i-1-LJ_FR2] = i < gotresults ? J->base[rbase+i] : TREF_NIL; |
815 | J->maxslot = cbase+(BCReg)nresults; | 842 | J->maxslot = cbase+(BCReg)nresults; |
816 | if (J->framedepth > 0) { /* Return to a frame that is part of the trace. */ | 843 | if (J->framedepth > 0) { /* Return to a frame that is part of the trace. */ |
817 | J->framedepth--; | 844 | J->framedepth--; |
818 | lua_assert(J->baseslot > cbase+1); | 845 | lua_assert(J->baseslot > cbase+1+LJ_FR2); |
819 | J->baseslot -= cbase+1; | 846 | J->baseslot -= cbase+1+LJ_FR2; |
820 | J->base -= cbase+1; | 847 | J->base -= cbase+1+LJ_FR2; |
821 | } else if (J->parent == 0 && J->exitno == 0 && | 848 | } else if (J->parent == 0 && J->exitno == 0 && |
822 | !bc_isret(bc_op(J->cur.startins))) { | 849 | !bc_isret(bc_op(J->cur.startins))) { |
823 | /* Return to lower frame would leave the loop in a root trace. */ | 850 | /* Return to lower frame would leave the loop in a root trace. */ |
@@ -827,13 +854,13 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
827 | } else { /* Return to lower frame. Guard for the target we return to. */ | 854 | } else { /* Return to lower frame. Guard for the target we return to. */ |
828 | TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); | 855 | TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); |
829 | TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame)); | 856 | TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame)); |
830 | emitir(IRTG(IR_RETF, IRT_P32), trpt, trpc); | 857 | emitir(IRTG(IR_RETF, IRT_PGC), trpt, trpc); |
831 | J->retdepth++; | 858 | J->retdepth++; |
832 | J->needsnap = 1; | 859 | J->needsnap = 1; |
833 | lua_assert(J->baseslot == 1); | 860 | lua_assert(J->baseslot == 1+LJ_FR2); |
834 | /* Shift result slots up and clear the slots of the new frame below. */ | 861 | /* Shift result slots up and clear the slots of the new frame below. */ |
835 | memmove(J->base + cbase, J->base-1, sizeof(TRef)*nresults); | 862 | memmove(J->base + cbase, J->base-1-LJ_FR2, sizeof(TRef)*nresults); |
836 | memset(J->base-1, 0, sizeof(TRef)*(cbase+1)); | 863 | memset(J->base-1-LJ_FR2, 0, sizeof(TRef)*(cbase+1+LJ_FR2)); |
837 | } | 864 | } |
838 | } else if (frame_iscont(frame)) { /* Return to continuation frame. */ | 865 | } else if (frame_iscont(frame)) { /* Return to continuation frame. */ |
839 | ASMFunction cont = frame_contf(frame); | 866 | ASMFunction cont = frame_contf(frame); |
@@ -842,32 +869,39 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
842 | lj_trace_err(J, LJ_TRERR_NYIRETL); | 869 | lj_trace_err(J, LJ_TRERR_NYIRETL); |
843 | J->baseslot -= (BCReg)cbase; | 870 | J->baseslot -= (BCReg)cbase; |
844 | J->base -= cbase; | 871 | J->base -= cbase; |
845 | J->maxslot = cbase-2; | 872 | J->maxslot = cbase-(2<<LJ_FR2); |
846 | if (cont == lj_cont_ra) { | 873 | if (cont == lj_cont_ra) { |
847 | /* Copy result to destination slot. */ | 874 | /* Copy result to destination slot. */ |
848 | BCReg dst = bc_a(*(frame_contpc(frame)-1)); | 875 | BCReg dst = bc_a(*(frame_contpc(frame)-1)); |
849 | J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL; | 876 | J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL; |
850 | if (dst >= J->maxslot) J->maxslot = dst+1; | 877 | if (dst >= J->maxslot) { |
878 | J->maxslot = dst+1; | ||
879 | } | ||
851 | } else if (cont == lj_cont_nop) { | 880 | } else if (cont == lj_cont_nop) { |
852 | /* Nothing to do here. */ | 881 | /* Nothing to do here. */ |
853 | } else if (cont == lj_cont_cat) { | 882 | } else if (cont == lj_cont_cat) { |
854 | BCReg bslot = bc_b(*(frame_contpc(frame)-1)); | 883 | BCReg bslot = bc_b(*(frame_contpc(frame)-1)); |
855 | TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL; | 884 | TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL; |
856 | if (bslot != cbase-2) { /* Concatenate the remainder. */ | 885 | if (bslot != J->maxslot) { /* Concatenate the remainder. */ |
857 | TValue *b = J->L->base, save; /* Simulate lower frame and result. */ | 886 | TValue *b = J->L->base, save; /* Simulate lower frame and result. */ |
858 | J->base[cbase-2] = tr; | 887 | J->base[J->maxslot] = tr; |
859 | copyTV(J->L, &save, b-2); | 888 | copyTV(J->L, &save, b-(2<<LJ_FR2)); |
860 | if (gotresults) copyTV(J->L, b-2, b+rbase); else setnilV(b-2); | 889 | if (gotresults) |
890 | copyTV(J->L, b-(2<<LJ_FR2), b+rbase); | ||
891 | else | ||
892 | setnilV(b-(2<<LJ_FR2)); | ||
861 | J->L->base = b - cbase; | 893 | J->L->base = b - cbase; |
862 | tr = rec_cat(J, bslot, cbase-2); | 894 | tr = rec_cat(J, bslot, cbase-(2<<LJ_FR2)); |
863 | b = J->L->base + cbase; /* Undo. */ | 895 | b = J->L->base + cbase; /* Undo. */ |
864 | J->L->base = b; | 896 | J->L->base = b; |
865 | copyTV(J->L, b-2, &save); | 897 | copyTV(J->L, b-(2<<LJ_FR2), &save); |
866 | } | 898 | } |
867 | if (tr) { /* Store final result. */ | 899 | if (tr) { /* Store final result. */ |
868 | BCReg dst = bc_a(*(frame_contpc(frame)-1)); | 900 | BCReg dst = bc_a(*(frame_contpc(frame)-1)); |
869 | J->base[dst] = tr; | 901 | J->base[dst] = tr; |
870 | if (dst >= J->maxslot) J->maxslot = dst+1; | 902 | if (dst >= J->maxslot) { |
903 | J->maxslot = dst+1; | ||
904 | } | ||
871 | } /* Otherwise continue with another __concat call. */ | 905 | } /* Otherwise continue with another __concat call. */ |
872 | } else { | 906 | } else { |
873 | /* Result type already specialized. */ | 907 | /* Result type already specialized. */ |
@@ -876,7 +910,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
876 | } else { | 910 | } else { |
877 | lj_trace_err(J, LJ_TRERR_NYIRETL); /* NYI: handle return to C frame. */ | 911 | lj_trace_err(J, LJ_TRERR_NYIRETL); /* NYI: handle return to C frame. */ |
878 | } | 912 | } |
879 | lua_assert(J->baseslot >= 1); | 913 | lua_assert(J->baseslot >= 1+LJ_FR2); |
880 | } | 914 | } |
881 | 915 | ||
882 | /* -- Metamethod handling ------------------------------------------------- */ | 916 | /* -- Metamethod handling ------------------------------------------------- */ |
@@ -885,11 +919,16 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
885 | static BCReg rec_mm_prep(jit_State *J, ASMFunction cont) | 919 | static BCReg rec_mm_prep(jit_State *J, ASMFunction cont) |
886 | { | 920 | { |
887 | BCReg s, top = cont == lj_cont_cat ? J->maxslot : curr_proto(J->L)->framesize; | 921 | BCReg s, top = cont == lj_cont_cat ? J->maxslot : curr_proto(J->L)->framesize; |
922 | #if LJ_FR2 | ||
923 | J->base[top] = lj_ir_k64(J, IR_KNUM, u64ptr(contptr(cont))); | ||
924 | J->base[top+1] = TREF_CONT; | ||
925 | #else | ||
888 | J->base[top] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT; | 926 | J->base[top] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT; |
927 | #endif | ||
889 | J->framedepth++; | 928 | J->framedepth++; |
890 | for (s = J->maxslot; s < top; s++) | 929 | for (s = J->maxslot; s < top; s++) |
891 | J->base[s] = 0; /* Clear frame gap to avoid resurrecting previous refs. */ | 930 | J->base[s] = 0; /* Clear frame gap to avoid resurrecting previous refs. */ |
892 | return top+1; | 931 | return top+1+LJ_FR2; |
893 | } | 932 | } |
894 | 933 | ||
895 | /* Record metamethod lookup. */ | 934 | /* Record metamethod lookup. */ |
@@ -967,9 +1006,9 @@ static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm) | |||
967 | BCReg func = rec_mm_prep(J, mm == MM_concat ? lj_cont_cat : lj_cont_ra); | 1006 | BCReg func = rec_mm_prep(J, mm == MM_concat ? lj_cont_cat : lj_cont_ra); |
968 | TRef *base = J->base + func; | 1007 | TRef *base = J->base + func; |
969 | TValue *basev = J->L->base + func; | 1008 | TValue *basev = J->L->base + func; |
970 | base[1] = ix->tab; base[2] = ix->key; | 1009 | base[1+LJ_FR2] = ix->tab; base[2+LJ_FR2] = ix->key; |
971 | copyTV(J->L, basev+1, &ix->tabv); | 1010 | copyTV(J->L, basev+1+LJ_FR2, &ix->tabv); |
972 | copyTV(J->L, basev+2, &ix->keyv); | 1011 | copyTV(J->L, basev+2+LJ_FR2, &ix->keyv); |
973 | if (!lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */ | 1012 | if (!lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */ |
974 | if (mm != MM_unm) { | 1013 | if (mm != MM_unm) { |
975 | ix->tab = ix->key; | 1014 | ix->tab = ix->key; |
@@ -980,8 +1019,10 @@ static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm) | |||
980 | lj_trace_err(J, LJ_TRERR_NOMM); | 1019 | lj_trace_err(J, LJ_TRERR_NOMM); |
981 | } | 1020 | } |
982 | ok: | 1021 | ok: |
983 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
984 | base[0] = ix->mobj; | 1022 | base[0] = ix->mobj; |
1023 | #if LJ_FR2 | ||
1024 | base[1] = 0; | ||
1025 | #endif | ||
985 | copyTV(J->L, basev+0, &ix->mobjv); | 1026 | copyTV(J->L, basev+0, &ix->mobjv); |
986 | lj_record_call(J, func, 2); | 1027 | lj_record_call(J, func, 2); |
987 | return 0; /* No result yet. */ | 1028 | return 0; /* No result yet. */ |
@@ -997,8 +1038,9 @@ static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv) | |||
997 | BCReg func = rec_mm_prep(J, lj_cont_ra); | 1038 | BCReg func = rec_mm_prep(J, lj_cont_ra); |
998 | TRef *base = J->base + func; | 1039 | TRef *base = J->base + func; |
999 | TValue *basev = J->L->base + func; | 1040 | TValue *basev = J->L->base + func; |
1000 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
1001 | base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv); | 1041 | base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv); |
1042 | base += LJ_FR2; | ||
1043 | basev += LJ_FR2; | ||
1002 | base[1] = tr; copyTV(J->L, basev+1, tv); | 1044 | base[1] = tr; copyTV(J->L, basev+1, tv); |
1003 | #if LJ_52 | 1045 | #if LJ_52 |
1004 | base[2] = tr; copyTV(J->L, basev+2, tv); | 1046 | base[2] = tr; copyTV(J->L, basev+2, tv); |
@@ -1018,11 +1060,10 @@ static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv) | |||
1018 | static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op) | 1060 | static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op) |
1019 | { | 1061 | { |
1020 | BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt); | 1062 | BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt); |
1021 | TRef *base = J->base + func; | 1063 | TRef *base = J->base + func + LJ_FR2; |
1022 | TValue *tv = J->L->base + func; | 1064 | TValue *tv = J->L->base + func + LJ_FR2; |
1023 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | 1065 | base[-LJ_FR2] = ix->mobj; base[1] = ix->val; base[2] = ix->key; |
1024 | base[0] = ix->mobj; base[1] = ix->val; base[2] = ix->key; | 1066 | copyTV(J->L, tv-LJ_FR2, &ix->mobjv); |
1025 | copyTV(J->L, tv+0, &ix->mobjv); | ||
1026 | copyTV(J->L, tv+1, &ix->valv); | 1067 | copyTV(J->L, tv+1, &ix->valv); |
1027 | copyTV(J->L, tv+2, &ix->keyv); | 1068 | copyTV(J->L, tv+2, &ix->keyv); |
1028 | lj_record_call(J, func, 2); | 1069 | lj_record_call(J, func, 2); |
@@ -1339,11 +1380,10 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) | |||
1339 | handlemm: | 1380 | handlemm: |
1340 | if (tref_isfunc(ix->mobj)) { /* Handle metamethod call. */ | 1381 | if (tref_isfunc(ix->mobj)) { /* Handle metamethod call. */ |
1341 | BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra); | 1382 | BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra); |
1342 | TRef *base = J->base + func; | 1383 | TRef *base = J->base + func + LJ_FR2; |
1343 | TValue *tv = J->L->base + func; | 1384 | TValue *tv = J->L->base + func + LJ_FR2; |
1344 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | 1385 | base[-LJ_FR2] = ix->mobj; base[1] = ix->tab; base[2] = ix->key; |
1345 | base[0] = ix->mobj; base[1] = ix->tab; base[2] = ix->key; | 1386 | setfuncV(J->L, tv-LJ_FR2, funcV(&ix->mobjv)); |
1346 | setfuncV(J->L, tv+0, funcV(&ix->mobjv)); | ||
1347 | copyTV(J->L, tv+1, &ix->tabv); | 1387 | copyTV(J->L, tv+1, &ix->tabv); |
1348 | copyTV(J->L, tv+2, &ix->keyv); | 1388 | copyTV(J->L, tv+2, &ix->keyv); |
1349 | if (ix->val) { | 1389 | if (ix->val) { |
@@ -1533,7 +1573,11 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) | |||
1533 | goto noconstify; | 1573 | goto noconstify; |
1534 | kfunc = lj_ir_kfunc(J, J->fn); | 1574 | kfunc = lj_ir_kfunc(J, J->fn); |
1535 | emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc); | 1575 | emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc); |
1536 | J->base[-1] = TREF_FRAME | kfunc; | 1576 | #if LJ_FR2 |
1577 | J->base[-2] = kfunc; | ||
1578 | #else | ||
1579 | J->base[-1] = kfunc | TREF_FRAME; | ||
1580 | #endif | ||
1537 | fn = kfunc; | 1581 | fn = kfunc; |
1538 | } | 1582 | } |
1539 | tr = lj_record_constify(J, uvval(uvp)); | 1583 | tr = lj_record_constify(J, uvval(uvp)); |
@@ -1644,11 +1688,14 @@ static void rec_func_setup(jit_State *J) | |||
1644 | static void rec_func_vararg(jit_State *J) | 1688 | static void rec_func_vararg(jit_State *J) |
1645 | { | 1689 | { |
1646 | GCproto *pt = J->pt; | 1690 | GCproto *pt = J->pt; |
1647 | BCReg s, fixargs, vframe = J->maxslot+1; | 1691 | BCReg s, fixargs, vframe = J->maxslot+1+LJ_FR2; |
1648 | lua_assert((pt->flags & PROTO_VARARG)); | 1692 | lua_assert((pt->flags & PROTO_VARARG)); |
1649 | if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS) | 1693 | if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS) |
1650 | lj_trace_err(J, LJ_TRERR_STACKOV); | 1694 | lj_trace_err(J, LJ_TRERR_STACKOV); |
1651 | J->base[vframe-1] = J->base[-1]; /* Copy function up. */ | 1695 | J->base[vframe-1-LJ_FR2] = J->base[-1-LJ_FR2]; /* Copy function up. */ |
1696 | #if LJ_FR2 | ||
1697 | J->base[vframe-1] = TREF_FRAME; | ||
1698 | #endif | ||
1652 | /* Copy fixarg slots up and set their original slots to nil. */ | 1699 | /* Copy fixarg slots up and set their original slots to nil. */ |
1653 | fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot; | 1700 | fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot; |
1654 | for (s = 0; s < fixargs; s++) { | 1701 | for (s = 0; s < fixargs; s++) { |
@@ -1710,7 +1757,7 @@ static int select_detect(jit_State *J) | |||
1710 | static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | 1757 | static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) |
1711 | { | 1758 | { |
1712 | int32_t numparams = J->pt->numparams; | 1759 | int32_t numparams = J->pt->numparams; |
1713 | ptrdiff_t nvararg = frame_delta(J->L->base-1) - numparams - 1; | 1760 | ptrdiff_t nvararg = frame_delta(J->L->base-1) - numparams - 1 - LJ_FR2; |
1714 | lua_assert(frame_isvarg(J->L->base-1)); | 1761 | lua_assert(frame_isvarg(J->L->base-1)); |
1715 | if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */ | 1762 | if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */ |
1716 | ptrdiff_t i; | 1763 | ptrdiff_t i; |
@@ -1722,10 +1769,10 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | |||
1722 | J->maxslot = dst + (BCReg)nresults; | 1769 | J->maxslot = dst + (BCReg)nresults; |
1723 | } | 1770 | } |
1724 | for (i = 0; i < nresults; i++) | 1771 | for (i = 0; i < nresults; i++) |
1725 | J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1) : TREF_NIL; | 1772 | J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1 - LJ_FR2) : TREF_NIL; |
1726 | } else { /* Unknown number of varargs passed to trace. */ | 1773 | } else { /* Unknown number of varargs passed to trace. */ |
1727 | TRef fr = emitir(IRTI(IR_SLOAD), 0, IRSLOAD_READONLY|IRSLOAD_FRAME); | 1774 | TRef fr = emitir(IRTI(IR_SLOAD), LJ_FR2, IRSLOAD_READONLY|IRSLOAD_FRAME); |
1728 | int32_t frofs = 8*(1+numparams)+FRAME_VARG; | 1775 | int32_t frofs = 8*(1+LJ_FR2+numparams)+FRAME_VARG; |
1729 | if (nresults >= 0) { /* Known fixed number of results. */ | 1776 | if (nresults >= 0) { /* Known fixed number of results. */ |
1730 | ptrdiff_t i; | 1777 | ptrdiff_t i; |
1731 | if (nvararg > 0) { | 1778 | if (nvararg > 0) { |
@@ -1739,7 +1786,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | |||
1739 | vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr); | 1786 | vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr); |
1740 | vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8)); | 1787 | vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8)); |
1741 | for (i = 0; i < nload; i++) { | 1788 | for (i = 0; i < nload; i++) { |
1742 | IRType t = itype2irt(&J->L->base[i-1-nvararg]); | 1789 | IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]); |
1743 | TRef aref = emitir(IRT(IR_AREF, IRT_PGC), | 1790 | TRef aref = emitir(IRT(IR_AREF, IRT_PGC), |
1744 | vbase, lj_ir_kint(J, (int32_t)i)); | 1791 | vbase, lj_ir_kint(J, (int32_t)i)); |
1745 | TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0); | 1792 | TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0); |
@@ -1787,14 +1834,15 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | |||
1787 | if (idx != 0 && idx <= nvararg) { | 1834 | if (idx != 0 && idx <= nvararg) { |
1788 | IRType t; | 1835 | IRType t; |
1789 | TRef aref, vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr); | 1836 | TRef aref, vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr); |
1790 | vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8)); | 1837 | vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, |
1791 | t = itype2irt(&J->L->base[idx-2-nvararg]); | 1838 | lj_ir_kint(J, frofs-(8<<LJ_FR2))); |
1839 | t = itype2irt(&J->L->base[idx-2-LJ_FR2-nvararg]); | ||
1792 | aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx); | 1840 | aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx); |
1793 | tr = emitir(IRTG(IR_VLOAD, t), aref, 0); | 1841 | tr = emitir(IRTG(IR_VLOAD, t), aref, 0); |
1794 | if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ | 1842 | if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ |
1795 | } | 1843 | } |
1796 | J->base[dst-2] = tr; | 1844 | J->base[dst-2-LJ_FR2] = tr; |
1797 | J->maxslot = dst-1; | 1845 | J->maxslot = dst-1-LJ_FR2; |
1798 | J->bcskip = 2; /* Skip CALLM + select. */ | 1846 | J->bcskip = 2; /* Skip CALLM + select. */ |
1799 | } else { | 1847 | } else { |
1800 | nyivarg: | 1848 | nyivarg: |
@@ -1887,7 +1935,15 @@ static void rec_comp_fixup(jit_State *J, const BCIns *pc, int cond) | |||
1887 | const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0); | 1935 | const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0); |
1888 | SnapShot *snap = &J->cur.snap[J->cur.nsnap-1]; | 1936 | SnapShot *snap = &J->cur.snap[J->cur.nsnap-1]; |
1889 | /* Set PC to opposite target to avoid re-recording the comp. in side trace. */ | 1937 | /* Set PC to opposite target to avoid re-recording the comp. in side trace. */ |
1938 | #if LJ_FR2 | ||
1939 | SnapEntry *flink = &J->cur.snapmap[snap->mapofs + snap->nent]; | ||
1940 | uint64_t pcbase; | ||
1941 | memcpy(&pcbase, flink, sizeof(uint64_t)); | ||
1942 | pcbase = (pcbase & 0xff) | (u64ptr(npc) << 8); | ||
1943 | memcpy(flink, &pcbase, sizeof(uint64_t)); | ||
1944 | #else | ||
1890 | J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc); | 1945 | J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc); |
1946 | #endif | ||
1891 | J->needsnap = 1; | 1947 | J->needsnap = 1; |
1892 | if (bc_a(jmpins) < J->maxslot) J->maxslot = bc_a(jmpins); | 1948 | if (bc_a(jmpins) < J->maxslot) J->maxslot = bc_a(jmpins); |
1893 | lj_snap_shrink(J); /* Shrink last snapshot if possible. */ | 1949 | lj_snap_shrink(J); /* Shrink last snapshot if possible. */ |
@@ -2185,7 +2241,13 @@ void lj_record_ins(jit_State *J) | |||
2185 | 2241 | ||
2186 | case BC_MOV: | 2242 | case BC_MOV: |
2187 | /* Clear gap of method call to avoid resurrecting previous refs. */ | 2243 | /* Clear gap of method call to avoid resurrecting previous refs. */ |
2188 | if (ra > J->maxslot) J->base[ra-1] = 0; | 2244 | if (ra > J->maxslot) { |
2245 | #if LJ_FR2 | ||
2246 | memset(J->base + J->maxslot, 0, (ra - J->maxslot) * sizeof(TRef)); | ||
2247 | #else | ||
2248 | J->base[ra-1] = 0; | ||
2249 | #endif | ||
2250 | } | ||
2189 | break; | 2251 | break; |
2190 | case BC_KSTR: case BC_KNUM: case BC_KPRI: | 2252 | case BC_KSTR: case BC_KNUM: case BC_KPRI: |
2191 | break; | 2253 | break; |
@@ -2254,14 +2316,14 @@ void lj_record_ins(jit_State *J) | |||
2254 | /* -- Calls and vararg handling ----------------------------------------- */ | 2316 | /* -- Calls and vararg handling ----------------------------------------- */ |
2255 | 2317 | ||
2256 | case BC_ITERC: | 2318 | case BC_ITERC: |
2257 | J->base[ra] = getslot(J, ra-3-LJ_FR2); | 2319 | J->base[ra] = getslot(J, ra-3); |
2258 | J->base[ra+1] = getslot(J, ra-2-LJ_FR2); | 2320 | J->base[ra+1+LJ_FR2] = getslot(J, ra-2); |
2259 | J->base[ra+2] = getslot(J, ra-1-LJ_FR2); | 2321 | J->base[ra+2+LJ_FR2] = getslot(J, ra-1); |
2260 | { /* Do the actual copy now because lj_record_call needs the values. */ | 2322 | { /* Do the actual copy now because lj_record_call needs the values. */ |
2261 | TValue *b = &J->L->base[ra]; | 2323 | TValue *b = &J->L->base[ra]; |
2262 | copyTV(J->L, b, b-3-LJ_FR2); | 2324 | copyTV(J->L, b, b-3); |
2263 | copyTV(J->L, b+1, b-2-LJ_FR2); | 2325 | copyTV(J->L, b+1+LJ_FR2, b-2); |
2264 | copyTV(J->L, b+2, b-1-LJ_FR2); | 2326 | copyTV(J->L, b+2+LJ_FR2, b-1); |
2265 | } | 2327 | } |
2266 | lj_record_call(J, ra, (ptrdiff_t)rc-1); | 2328 | lj_record_call(J, ra, (ptrdiff_t)rc-1); |
2267 | break; | 2329 | break; |
@@ -2384,7 +2446,12 @@ void lj_record_ins(jit_State *J) | |||
2384 | /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */ | 2446 | /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */ |
2385 | if (bcmode_a(op) == BCMdst && rc) { | 2447 | if (bcmode_a(op) == BCMdst && rc) { |
2386 | J->base[ra] = rc; | 2448 | J->base[ra] = rc; |
2387 | if (ra >= J->maxslot) J->maxslot = ra+1; | 2449 | if (ra >= J->maxslot) { |
2450 | #if LJ_FR2 | ||
2451 | if (ra > J->maxslot) J->base[ra-1] = 0; | ||
2452 | #endif | ||
2453 | J->maxslot = ra+1; | ||
2454 | } | ||
2388 | } | 2455 | } |
2389 | 2456 | ||
2390 | #undef rav | 2457 | #undef rav |
@@ -2469,7 +2536,7 @@ void lj_record_setup(jit_State *J) | |||
2469 | J->scev.idx = REF_NIL; | 2536 | J->scev.idx = REF_NIL; |
2470 | setmref(J->scev.pc, NULL); | 2537 | setmref(J->scev.pc, NULL); |
2471 | 2538 | ||
2472 | J->baseslot = 1; /* Invoking function is at base[-1]. */ | 2539 | J->baseslot = 1+LJ_FR2; /* Invoking function is at base[-1-LJ_FR2]. */ |
2473 | J->base = J->slot + J->baseslot; | 2540 | J->base = J->slot + J->baseslot; |
2474 | J->maxslot = 0; | 2541 | J->maxslot = 0; |
2475 | J->framedepth = 0; | 2542 | J->framedepth = 0; |