aboutsummaryrefslogtreecommitdiff
path: root/src/lj_record.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_record.c')
-rw-r--r--src/lj_record.c231
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. */
163static TRef getcurrf(jit_State *J) 181static 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)
509static LoopEvent rec_iterl(jit_State *J, const BCIns iterins) 527static 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)
885static BCReg rec_mm_prep(jit_State *J, ASMFunction cont) 919static 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 }
982ok: 1021ok:
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)
1018static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op) 1060static 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)
1644static void rec_func_vararg(jit_State *J) 1688static 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)
1710static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) 1757static 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;