diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_snap.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/src/lj_snap.c b/src/lj_snap.c index 6199b1f0..33c058be 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -68,10 +68,18 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) | |||
68 | for (s = 0; s < nslots; s++) { | 68 | for (s = 0; s < nslots; s++) { |
69 | TRef tr = J->slot[s]; | 69 | TRef tr = J->slot[s]; |
70 | IRRef ref = tref_ref(tr); | 70 | IRRef ref = tref_ref(tr); |
71 | #if LJ_FR2 | ||
72 | if (s == 1) continue; | ||
73 | if ((tr & (TREF_FRAME | TREF_CONT)) && !ref) { | ||
74 | TValue *base = J->L->base - J->baseslot; | ||
75 | tr = J->slot[s] = (tr & 0xff0000) | lj_ir_k64(J, IR_KNUM, base[s].u64); | ||
76 | ref = tref_ref(tr); | ||
77 | } | ||
78 | #endif | ||
71 | if (ref) { | 79 | if (ref) { |
72 | SnapEntry sn = SNAP_TR(s, tr); | 80 | SnapEntry sn = SNAP_TR(s, tr); |
73 | IRIns *ir = &J->cur.ir[ref]; | 81 | IRIns *ir = &J->cur.ir[ref]; |
74 | if (!(sn & (SNAP_CONT|SNAP_FRAME)) && | 82 | if ((LJ_FR2 || !(sn & (SNAP_CONT|SNAP_FRAME))) && |
75 | ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { | 83 | ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { |
76 | /* No need to snapshot unmodified non-inherited slots. */ | 84 | /* No need to snapshot unmodified non-inherited slots. */ |
77 | if (!(ir->op2 & IRSLOAD_INHERIT)) | 85 | if (!(ir->op2 & IRSLOAD_INHERIT)) |
@@ -90,34 +98,51 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) | |||
90 | } | 98 | } |
91 | 99 | ||
92 | /* Add frame links at the end of the snapshot. */ | 100 | /* Add frame links at the end of the snapshot. */ |
93 | static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map) | 101 | static MSize snapshot_framelinks(jit_State *J, SnapEntry *map, uint8_t *topslot) |
94 | { | 102 | { |
95 | cTValue *frame = J->L->base - 1; | 103 | cTValue *frame = J->L->base - 1; |
96 | cTValue *lim = J->L->base - J->baseslot; | 104 | cTValue *lim = J->L->base - J->baseslot + LJ_FR2; |
97 | GCfunc *fn = frame_func(frame); | 105 | GCfunc *fn = frame_func(frame); |
98 | cTValue *ftop = isluafunc(fn) ? (frame+funcproto(fn)->framesize) : J->L->top; | 106 | cTValue *ftop = isluafunc(fn) ? (frame+funcproto(fn)->framesize) : J->L->top; |
107 | #if LJ_FR2 | ||
108 | uint64_t pcbase = (u64ptr(J->pc) << 8) | (J->baseslot - 2); | ||
109 | lua_assert(2 <= J->baseslot && J->baseslot <= 257); | ||
110 | memcpy(map, &pcbase, sizeof(uint64_t)); | ||
111 | #else | ||
99 | MSize f = 0; | 112 | MSize f = 0; |
100 | lua_assert(!LJ_FR2); /* TODO_FR2: store 64 bit PCs. */ | ||
101 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ | 113 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ |
114 | #endif | ||
102 | while (frame > lim) { /* Backwards traversal of all frames above base. */ | 115 | while (frame > lim) { /* Backwards traversal of all frames above base. */ |
103 | if (frame_islua(frame)) { | 116 | if (frame_islua(frame)) { |
117 | #if !LJ_FR2 | ||
104 | map[f++] = SNAP_MKPC(frame_pc(frame)); | 118 | map[f++] = SNAP_MKPC(frame_pc(frame)); |
119 | #endif | ||
105 | frame = frame_prevl(frame); | 120 | frame = frame_prevl(frame); |
106 | } else if (frame_iscont(frame)) { | 121 | } else if (frame_iscont(frame)) { |
122 | #if !LJ_FR2 | ||
107 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | 123 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); |
108 | map[f++] = SNAP_MKPC(frame_contpc(frame)); | 124 | map[f++] = SNAP_MKPC(frame_contpc(frame)); |
125 | #endif | ||
109 | frame = frame_prevd(frame); | 126 | frame = frame_prevd(frame); |
110 | } else { | 127 | } else { |
111 | lua_assert(!frame_isc(frame)); | 128 | lua_assert(!frame_isc(frame)); |
129 | #if !LJ_FR2 | ||
112 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | 130 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); |
131 | #endif | ||
113 | frame = frame_prevd(frame); | 132 | frame = frame_prevd(frame); |
114 | continue; | 133 | continue; |
115 | } | 134 | } |
116 | if (frame + funcproto(frame_func(frame))->framesize > ftop) | 135 | if (frame + funcproto(frame_func(frame))->framesize > ftop) |
117 | ftop = frame + funcproto(frame_func(frame))->framesize; | 136 | ftop = frame + funcproto(frame_func(frame))->framesize; |
118 | } | 137 | } |
138 | *topslot = (uint8_t)(ftop - lim); | ||
139 | #if LJ_FR2 | ||
140 | lua_assert(sizeof(SnapEntry) * 2 == sizeof(uint64_t)); | ||
141 | return 2; | ||
142 | #else | ||
119 | lua_assert(f == (MSize)(1 + J->framedepth)); | 143 | lua_assert(f == (MSize)(1 + J->framedepth)); |
120 | return (BCReg)(ftop - lim); | 144 | return f; |
145 | #endif | ||
121 | } | 146 | } |
122 | 147 | ||
123 | /* Take a snapshot of the current stack. */ | 148 | /* Take a snapshot of the current stack. */ |
@@ -127,16 +152,16 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) | |||
127 | MSize nent; | 152 | MSize nent; |
128 | SnapEntry *p; | 153 | SnapEntry *p; |
129 | /* Conservative estimate. */ | 154 | /* Conservative estimate. */ |
130 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1); | 155 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)(LJ_FR2?2:J->framedepth+1)); |
131 | p = &J->cur.snapmap[nsnapmap]; | 156 | p = &J->cur.snapmap[nsnapmap]; |
132 | nent = snapshot_slots(J, p, nslots); | 157 | nent = snapshot_slots(J, p, nslots); |
133 | snap->topslot = (uint8_t)snapshot_framelinks(J, p + nent); | 158 | snap->nent = (uint8_t)nent; |
159 | nent += snapshot_framelinks(J, p + nent, &snap->topslot); | ||
134 | snap->mapofs = (uint16_t)nsnapmap; | 160 | snap->mapofs = (uint16_t)nsnapmap; |
135 | snap->ref = (IRRef1)J->cur.nins; | 161 | snap->ref = (IRRef1)J->cur.nins; |
136 | snap->nent = (uint8_t)nent; | ||
137 | snap->nslots = (uint8_t)nslots; | 162 | snap->nslots = (uint8_t)nslots; |
138 | snap->count = 0; | 163 | snap->count = 0; |
139 | J->cur.nsnapmap = (uint16_t)(nsnapmap + nent + 1 + J->framedepth); | 164 | J->cur.nsnapmap = (uint16_t)(nsnapmap + nent); |
140 | } | 165 | } |
141 | 166 | ||
142 | /* Add or merge a snapshot. */ | 167 | /* Add or merge a snapshot. */ |
@@ -284,8 +309,8 @@ void lj_snap_shrink(jit_State *J) | |||
284 | MSize n, m, nlim, nent = snap->nent; | 309 | MSize n, m, nlim, nent = snap->nent; |
285 | uint8_t udf[SNAP_USEDEF_SLOTS]; | 310 | uint8_t udf[SNAP_USEDEF_SLOTS]; |
286 | BCReg maxslot = J->maxslot; | 311 | BCReg maxslot = J->maxslot; |
287 | BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot); | ||
288 | BCReg baseslot = J->baseslot; | 312 | BCReg baseslot = J->baseslot; |
313 | BCReg minslot = snap_usedef(J, udf, snap_pc(&map[nent]), maxslot); | ||
289 | maxslot += baseslot; | 314 | maxslot += baseslot; |
290 | minslot += baseslot; | 315 | minslot += baseslot; |
291 | snap->nslots = (uint8_t)maxslot; | 316 | snap->nslots = (uint8_t)maxslot; |
@@ -794,11 +819,13 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
794 | SnapShot *snap = &T->snap[snapno]; | 819 | SnapShot *snap = &T->snap[snapno]; |
795 | MSize n, nent = snap->nent; | 820 | MSize n, nent = snap->nent; |
796 | SnapEntry *map = &T->snapmap[snap->mapofs]; | 821 | SnapEntry *map = &T->snapmap[snap->mapofs]; |
797 | SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1]; | 822 | SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1-LJ_FR2]; |
823 | #if !LJ_FR2 | ||
798 | ptrdiff_t ftsz0; | 824 | ptrdiff_t ftsz0; |
825 | #endif | ||
799 | TValue *frame; | 826 | TValue *frame; |
800 | BloomFilter rfilt = snap_renamefilter(T, snapno); | 827 | BloomFilter rfilt = snap_renamefilter(T, snapno); |
801 | const BCIns *pc = snap_pc(map[nent]); | 828 | const BCIns *pc = snap_pc(&map[nent]); |
802 | lua_State *L = J->L; | 829 | lua_State *L = J->L; |
803 | 830 | ||
804 | /* Set interpreter PC to the next PC to get correct error messages. */ | 831 | /* Set interpreter PC to the next PC to get correct error messages. */ |
@@ -811,8 +838,10 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
811 | } | 838 | } |
812 | 839 | ||
813 | /* Fill stack slots with data from the registers and spill slots. */ | 840 | /* Fill stack slots with data from the registers and spill slots. */ |
814 | frame = L->base-1; | 841 | frame = L->base-1-LJ_FR2; |
842 | #if !LJ_FR2 | ||
815 | ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */ | 843 | ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */ |
844 | #endif | ||
816 | for (n = 0; n < nent; n++) { | 845 | for (n = 0; n < nent; n++) { |
817 | SnapEntry sn = map[n]; | 846 | SnapEntry sn = map[n]; |
818 | if (!(sn & SNAP_NORESTORE)) { | 847 | if (!(sn & SNAP_NORESTORE)) { |
@@ -835,14 +864,18 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
835 | TValue tmp; | 864 | TValue tmp; |
836 | snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp); | 865 | snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp); |
837 | o->u32.hi = tmp.u32.lo; | 866 | o->u32.hi = tmp.u32.lo; |
867 | #if !LJ_FR2 | ||
838 | } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { | 868 | } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { |
839 | lua_assert(!LJ_FR2); /* TODO_FR2: store 64 bit PCs. */ | ||
840 | /* Overwrite tag with frame link. */ | 869 | /* Overwrite tag with frame link. */ |
841 | setframe_ftsz(o, snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0); | 870 | setframe_ftsz(o, snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0); |
842 | L->base = o+1; | 871 | L->base = o+1; |
872 | #endif | ||
843 | } | 873 | } |
844 | } | 874 | } |
845 | } | 875 | } |
876 | #if LJ_FR2 | ||
877 | L->base += (map[nent+LJ_BE] & 0xff); | ||
878 | #endif | ||
846 | lua_assert(map + nent == flinks); | 879 | lua_assert(map + nent == flinks); |
847 | 880 | ||
848 | /* Compute current stack top. */ | 881 | /* Compute current stack top. */ |