diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 6 | ||||
-rw-r--r-- | src/lj_def.h | 1 | ||||
-rw-r--r-- | src/lj_jit.h | 1 | ||||
-rw-r--r-- | src/lj_record.c | 39 | ||||
-rw-r--r-- | src/lj_snap.c | 38 |
5 files changed, 38 insertions, 47 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 9cdbcf12..aed12043 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -3044,7 +3044,7 @@ static void asm_tail_sync(ASMState *as) | |||
3044 | SnapShot *snap = &as->T->snap[as->T->nsnap-1]; /* Last snapshot. */ | 3044 | SnapShot *snap = &as->T->snap[as->T->nsnap-1]; /* Last snapshot. */ |
3045 | MSize n, nent = snap->nent; | 3045 | MSize n, nent = snap->nent; |
3046 | SnapEntry *map = &as->T->snapmap[snap->mapofs]; | 3046 | SnapEntry *map = &as->T->snapmap[snap->mapofs]; |
3047 | SnapEntry *flinks = map + nent + 1; | 3047 | SnapEntry *flinks = map + nent + snap->depth; |
3048 | BCReg newbase = 0, topslot = 0; | 3048 | BCReg newbase = 0, topslot = 0; |
3049 | 3049 | ||
3050 | checkmclim(as); | 3050 | checkmclim(as); |
@@ -3102,11 +3102,11 @@ static void asm_tail_sync(ASMState *as) | |||
3102 | if (!(sn & (SNAP_CONT|SNAP_FRAME))) | 3102 | if (!(sn & (SNAP_CONT|SNAP_FRAME))) |
3103 | emit_movmroi(as, RID_BASE, ofs+4, irt_toitype(ir->t)); | 3103 | emit_movmroi(as, RID_BASE, ofs+4, irt_toitype(ir->t)); |
3104 | else if (s != 0) /* Do not overwrite link to previous frame. */ | 3104 | else if (s != 0) /* Do not overwrite link to previous frame. */ |
3105 | emit_movmroi(as, RID_BASE, ofs+4, (int32_t)(*flinks++)); | 3105 | emit_movmroi(as, RID_BASE, ofs+4, (int32_t)(*flinks--)); |
3106 | } | 3106 | } |
3107 | checkmclim(as); | 3107 | checkmclim(as); |
3108 | } | 3108 | } |
3109 | lua_assert(map + nent + 1 + snap->depth == flinks); | 3109 | lua_assert(map + nent == flinks); |
3110 | } | 3110 | } |
3111 | 3111 | ||
3112 | /* Fixup the tail code. */ | 3112 | /* Fixup the tail code. */ |
diff --git a/src/lj_def.h b/src/lj_def.h index 83b1935c..de4ad1be 100644 --- a/src/lj_def.h +++ b/src/lj_def.h | |||
@@ -66,7 +66,6 @@ typedef unsigned __int32 uintptr_t; | |||
66 | 66 | ||
67 | /* JIT compiler limits. */ | 67 | /* JIT compiler limits. */ |
68 | #define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */ | 68 | #define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */ |
69 | #define LJ_MAX_JFRAME 20 /* Max. # of frames for a trace. */ | ||
70 | #define LJ_MAX_PHI 32 /* Max. # of PHIs for a loop. */ | 69 | #define LJ_MAX_PHI 32 /* Max. # of PHIs for a loop. */ |
71 | #define LJ_MAX_EXITSTUBGR 8 /* Max. # of exit stub groups. */ | 70 | #define LJ_MAX_EXITSTUBGR 8 /* Max. # of exit stub groups. */ |
72 | 71 | ||
diff --git a/src/lj_jit.h b/src/lj_jit.h index 229642a5..ec368feb 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
@@ -252,7 +252,6 @@ typedef struct jit_State { | |||
252 | 252 | ||
253 | IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */ | 253 | IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */ |
254 | TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */ | 254 | TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */ |
255 | SnapEntry frame[LJ_MAX_JFRAME+2]; /* Frame link stack. */ | ||
256 | 255 | ||
257 | int32_t param[JIT_P__MAX]; /* JIT engine parameters. */ | 256 | int32_t param[JIT_P__MAX]; /* JIT engine parameters. */ |
258 | 257 | ||
diff --git a/src/lj_record.c b/src/lj_record.c index eaaafc51..e5a8b208 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -92,26 +92,6 @@ static void rec_check_ir(jit_State *J) | |||
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | /* Compare frame stack of the recorder and the VM. */ | ||
96 | static void rec_check_frames(jit_State *J) | ||
97 | { | ||
98 | cTValue *frame = J->L->base - 1; | ||
99 | cTValue *lim = J->L->base - J->baseslot; | ||
100 | int32_t depth = J->framedepth; | ||
101 | while (frame > lim) { | ||
102 | depth--; | ||
103 | lua_assert(depth >= 0); | ||
104 | lua_assert((SnapEntry)frame_ftsz(frame) == J->frame[depth]); | ||
105 | if (frame_iscont(frame)) { | ||
106 | depth--; | ||
107 | lua_assert(depth >= 0); | ||
108 | lua_assert((SnapEntry)frame_ftsz(frame-1) == J->frame[depth]); | ||
109 | } | ||
110 | frame = frame_prev(frame); | ||
111 | } | ||
112 | lua_assert(depth == 0); | ||
113 | } | ||
114 | |||
115 | /* Compare stack slots and frames of the recorder and the VM. */ | 95 | /* Compare stack slots and frames of the recorder and the VM. */ |
116 | static void rec_check_slots(jit_State *J) | 96 | static void rec_check_slots(jit_State *J) |
117 | { | 97 | { |
@@ -157,7 +137,6 @@ static void rec_check_slots(jit_State *J) | |||
157 | } | 137 | } |
158 | } | 138 | } |
159 | lua_assert(J->framedepth == depth); | 139 | lua_assert(J->framedepth == depth); |
160 | rec_check_frames(J); | ||
161 | } | 140 | } |
162 | #endif | 141 | #endif |
163 | 142 | ||
@@ -519,9 +498,7 @@ static void rec_call(jit_State *J, BCReg func, ptrdiff_t nargs) | |||
519 | fbase[0] = trfunc | TREF_FRAME; | 498 | fbase[0] = trfunc | TREF_FRAME; |
520 | 499 | ||
521 | /* Bump frame. */ | 500 | /* Bump frame. */ |
522 | J->frame[J->framedepth++] = SNAP_MKPC(J->pc+1); | 501 | J->framedepth++; |
523 | if (J->framedepth > LJ_MAX_JFRAME) | ||
524 | lj_trace_err(J, LJ_TRERR_STACKOV); | ||
525 | J->base += func+1; | 502 | J->base += func+1; |
526 | J->baseslot += func+1; | 503 | J->baseslot += func+1; |
527 | J->maxslot = nargs; | 504 | J->maxslot = nargs; |
@@ -626,6 +603,7 @@ static BCReg rec_mm_prep(jit_State *J, ASMFunction cont) | |||
626 | trcont = lj_ir_kptr(J, (void *)cont); | 603 | trcont = lj_ir_kptr(J, (void *)cont); |
627 | #endif | 604 | #endif |
628 | J->base[top] = trcont | TREF_CONT; | 605 | J->base[top] = trcont | TREF_CONT; |
606 | J->framedepth++; | ||
629 | for (s = J->maxslot; s < top; s++) | 607 | for (s = J->maxslot; s < top; s++) |
630 | J->base[s] = 0; /* Clear frame gap to avoid resurrecting previous refs. */ | 608 | J->base[s] = 0; /* Clear frame gap to avoid resurrecting previous refs. */ |
631 | return top+1; | 609 | return top+1; |
@@ -695,7 +673,6 @@ ok: | |||
695 | base[0] = ix->mobj; | 673 | base[0] = ix->mobj; |
696 | copyTV(J->L, basev+0, &ix->mobjv); | 674 | copyTV(J->L, basev+0, &ix->mobjv); |
697 | rec_call(J, func, 2); | 675 | rec_call(J, func, 2); |
698 | J->frame[J->framedepth++] = SNAP_MKFTSZ((func+1)*sizeof(TValue)+FRAME_CONT); | ||
699 | return 0; /* No result yet. */ | 676 | return 0; /* No result yet. */ |
700 | } | 677 | } |
701 | 678 | ||
@@ -710,7 +687,6 @@ static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op) | |||
710 | copyTV(J->L, tv+1, &ix->valv); | 687 | copyTV(J->L, tv+1, &ix->valv); |
711 | copyTV(J->L, tv+2, &ix->keyv); | 688 | copyTV(J->L, tv+2, &ix->keyv); |
712 | rec_call(J, func, 2); | 689 | rec_call(J, func, 2); |
713 | J->frame[J->framedepth++] = SNAP_MKFTSZ((func+1)*sizeof(TValue)+FRAME_CONT); | ||
714 | } | 690 | } |
715 | 691 | ||
716 | /* Record call to equality comparison metamethod (for tab and udata only). */ | 692 | /* Record call to equality comparison metamethod (for tab and udata only). */ |
@@ -890,11 +866,9 @@ static TRef rec_idx(jit_State *J, RecordIndex *ix) | |||
890 | base[3] = ix->val; | 866 | base[3] = ix->val; |
891 | copyTV(J->L, tv+3, &ix->valv); | 867 | copyTV(J->L, tv+3, &ix->valv); |
892 | rec_call(J, func, 3); /* mobj(tab, key, val) */ | 868 | rec_call(J, func, 3); /* mobj(tab, key, val) */ |
893 | J->frame[J->framedepth++] = SNAP_MKFTSZ((func+1)*sizeof(TValue)+FRAME_CONT); | ||
894 | return 0; | 869 | return 0; |
895 | } else { | 870 | } else { |
896 | rec_call(J, func, 2); /* res = mobj(tab, key) */ | 871 | rec_call(J, func, 2); /* res = mobj(tab, key) */ |
897 | J->frame[J->framedepth++] = SNAP_MKFTSZ((func+1)*sizeof(TValue)+FRAME_CONT); | ||
898 | return 0; /* No result yet. */ | 872 | return 0; /* No result yet. */ |
899 | } | 873 | } |
900 | } | 874 | } |
@@ -1294,8 +1268,6 @@ static void LJ_FASTCALL recff_ipairs(jit_State *J, RecordFFData *rd) | |||
1294 | static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd) | 1268 | static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd) |
1295 | { | 1269 | { |
1296 | if (J->maxslot >= 1) { | 1270 | if (J->maxslot >= 1) { |
1297 | J->pc = (const BCIns *)(sizeof(TValue) - 4 + | ||
1298 | (hook_active(J2G(J)) ? FRAME_PCALLH : FRAME_PCALL)); | ||
1299 | rec_call(J, 0, J->maxslot - 1); | 1271 | rec_call(J, 0, J->maxslot - 1); |
1300 | rd->nres = -1; /* Pending call. */ | 1272 | rd->nres = -1; /* Pending call. */ |
1301 | } /* else: Interpreter will throw. */ | 1273 | } /* else: Interpreter will throw. */ |
@@ -1321,8 +1293,6 @@ static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd) | |||
1321 | copyTV(J->L, &argv1, &rd->argv[1]); | 1293 | copyTV(J->L, &argv1, &rd->argv[1]); |
1322 | copyTV(J->L, &rd->argv[0], &argv1); | 1294 | copyTV(J->L, &rd->argv[0], &argv1); |
1323 | copyTV(J->L, &rd->argv[1], &argv0); | 1295 | copyTV(J->L, &rd->argv[1], &argv0); |
1324 | J->pc = (const BCIns *)(2*sizeof(TValue) - 4 + | ||
1325 | (hook_active(J2G(J)) ? FRAME_PCALLH : FRAME_PCALL)); | ||
1326 | /* Need to protect rec_call because it may throw. */ | 1296 | /* Need to protect rec_call because it may throw. */ |
1327 | errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp); | 1297 | errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp); |
1328 | /* Always undo Lua stack swap to avoid confusing the interpreter. */ | 1298 | /* Always undo Lua stack swap to avoid confusing the interpreter. */ |
@@ -2329,13 +2299,12 @@ static void rec_setup_side(jit_State *J, Trace *T) | |||
2329 | } | 2299 | } |
2330 | setslot: | 2300 | setslot: |
2331 | J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */ | 2301 | J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */ |
2332 | if ((sn & SNAP_FRAME) && s != 0) | 2302 | if ((sn & SNAP_FRAME)) |
2333 | J->baseslot = s+1; | 2303 | J->baseslot = s+1; |
2334 | } | 2304 | } |
2335 | J->base = J->slot + J->baseslot; | 2305 | J->base = J->slot + J->baseslot; |
2336 | J->maxslot = snap->nslots - J->baseslot; | 2306 | J->maxslot = snap->nslots - J->baseslot; |
2337 | J->framedepth = snap->depth; /* Copy frames from snapshot. */ | 2307 | J->framedepth = snap->depth; |
2338 | memcpy(J->frame, &map[nent+1], sizeof(SnapEntry)*(size_t)snap->depth); | ||
2339 | lj_snap_add(J); | 2308 | lj_snap_add(J); |
2340 | } | 2309 | } |
2341 | 2310 | ||
diff --git a/src/lj_snap.c b/src/lj_snap.c index 04b9a7f6..e17b7a0d 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -68,6 +68,31 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) | |||
68 | return n; | 68 | return n; |
69 | } | 69 | } |
70 | 70 | ||
71 | /* Add frame links at the end of the snapshot. */ | ||
72 | static void snapshot_framelinks(jit_State *J, SnapEntry *map) | ||
73 | { | ||
74 | cTValue *frame = J->L->base - 1; | ||
75 | cTValue *lim = J->L->base - J->baseslot; | ||
76 | MSize f = 0; | ||
77 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ | ||
78 | while (frame > lim) { /* Backwards traversal of all frames above base. */ | ||
79 | if (frame_islua(frame)) { | ||
80 | map[f++] = SNAP_MKPC(frame_pc(frame)); | ||
81 | frame = frame_prevl(frame); | ||
82 | } else if (frame_ispcall(frame)) { | ||
83 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | ||
84 | frame = frame_prevd(frame); | ||
85 | } else if (frame_iscont(frame)) { | ||
86 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | ||
87 | map[f++] = SNAP_MKPC(frame_contpc(frame)); | ||
88 | frame = frame_prevd(frame); | ||
89 | } else { | ||
90 | lua_assert(0); | ||
91 | } | ||
92 | } | ||
93 | lua_assert(f == (MSize)(1 + J->framedepth)); | ||
94 | } | ||
95 | |||
71 | /* Take a snapshot of the current stack. */ | 96 | /* Take a snapshot of the current stack. */ |
72 | static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) | 97 | static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) |
73 | { | 98 | { |
@@ -78,6 +103,7 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) | |||
78 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1); | 103 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1); |
79 | p = &J->cur.snapmap[nsnapmap]; | 104 | p = &J->cur.snapmap[nsnapmap]; |
80 | nent = snapshot_slots(J, p, nslots); | 105 | nent = snapshot_slots(J, p, nslots); |
106 | snapshot_framelinks(J, p + nent); | ||
81 | snap->mapofs = (uint16_t)nsnapmap; | 107 | snap->mapofs = (uint16_t)nsnapmap; |
82 | snap->ref = (IRRef1)J->cur.nins; | 108 | snap->ref = (IRRef1)J->cur.nins; |
83 | snap->nent = (uint8_t)nent; | 109 | snap->nent = (uint8_t)nent; |
@@ -85,9 +111,6 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) | |||
85 | snap->nslots = (uint8_t)nslots; | 111 | snap->nslots = (uint8_t)nslots; |
86 | snap->count = 0; | 112 | snap->count = 0; |
87 | J->cur.nsnapmap = (uint16_t)(nsnapmap + nent + 1 + J->framedepth); | 113 | J->cur.nsnapmap = (uint16_t)(nsnapmap + nent + 1 + J->framedepth); |
88 | /* Add frame links at the end of the snapshot. */ | ||
89 | p[nent] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ | ||
90 | memcpy(&p[nent+1], J->frame, sizeof(SnapEntry)*(size_t)J->framedepth); | ||
91 | } | 114 | } |
92 | 115 | ||
93 | /* Add or merge a snapshot. */ | 116 | /* Add or merge a snapshot. */ |
@@ -119,6 +142,7 @@ void lj_snap_shrink(jit_State *J) | |||
119 | snap->nslots = (uint8_t)nslots; | 142 | snap->nslots = (uint8_t)nslots; |
120 | if (nent > 0 && snap_slot(map[nent-1]) >= nslots) { | 143 | if (nent > 0 && snap_slot(map[nent-1]) >= nslots) { |
121 | MSize s, delta, depth = snap->depth; | 144 | MSize s, delta, depth = snap->depth; |
145 | lua_assert(depth == (MSize)J->framedepth); | ||
122 | for (nent--; nent > 0 && snap_slot(map[nent-1]) >= nslots; nent--) | 146 | for (nent--; nent > 0 && snap_slot(map[nent-1]) >= nslots; nent--) |
123 | ; | 147 | ; |
124 | delta = snap->nent - nent; | 148 | delta = snap->nent - nent; |
@@ -187,7 +211,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
187 | SnapShot *snap = &T->snap[snapno]; | 211 | SnapShot *snap = &T->snap[snapno]; |
188 | MSize n, nent = snap->nent; | 212 | MSize n, nent = snap->nent; |
189 | SnapEntry *map = &T->snapmap[snap->mapofs]; | 213 | SnapEntry *map = &T->snapmap[snap->mapofs]; |
190 | SnapEntry *flinks = map + nent + 1; | 214 | SnapEntry *flinks = map + nent + snap->depth; |
191 | int32_t ftsz0; | 215 | int32_t ftsz0; |
192 | BCReg nslots = snap->nslots; | 216 | BCReg nslots = snap->nslots; |
193 | TValue *frame; | 217 | TValue *frame; |
@@ -213,7 +237,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
213 | lj_ir_kvalue(L, o, ir); | 237 | lj_ir_kvalue(L, o, ir); |
214 | if ((sn & (SNAP_CONT|SNAP_FRAME))) { | 238 | if ((sn & (SNAP_CONT|SNAP_FRAME))) { |
215 | /* Overwrite tag with frame link. */ | 239 | /* Overwrite tag with frame link. */ |
216 | o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks++ : ftsz0; | 240 | o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks-- : ftsz0; |
217 | if ((sn & SNAP_FRAME)) { | 241 | if ((sn & SNAP_FRAME)) { |
218 | GCfunc *fn = ir_kfunc(ir); | 242 | GCfunc *fn = ir_kfunc(ir); |
219 | if (isluafunc(fn)) { | 243 | if (isluafunc(fn)) { |
@@ -264,8 +288,8 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
264 | } | 288 | } |
265 | } | 289 | } |
266 | L->top = curr_topL(L); | 290 | L->top = curr_topL(L); |
267 | lua_assert(map + nent + 1 + snap->depth == flinks); | 291 | lua_assert(map + nent == flinks); |
268 | return snap_pc(map[nent]); | 292 | return snap_pc(*flinks); |
269 | } | 293 | } |
270 | 294 | ||
271 | #undef IR | 295 | #undef IR |