diff options
Diffstat (limited to 'src/lj_snap.c')
-rw-r--r-- | src/lj_snap.c | 271 |
1 files changed, 182 insertions, 89 deletions
diff --git a/src/lj_snap.c b/src/lj_snap.c index 7a02c9a9..bcc9da38 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -68,20 +68,37 @@ 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) { /* Ignore slot 1 in LJ_FR2 mode, except if tailcalled. */ | ||
73 | if ((tr & TREF_FRAME)) | ||
74 | map[n++] = SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL); | ||
75 | continue; | ||
76 | } | ||
77 | if ((tr & (TREF_FRAME | TREF_CONT)) && !ref) { | ||
78 | cTValue *base = J->L->base - J->baseslot; | ||
79 | tr = J->slot[s] = (tr & 0xff0000) | lj_ir_k64(J, IR_KNUM, base[s].u64); | ||
80 | ref = tref_ref(tr); | ||
81 | } | ||
82 | #endif | ||
71 | if (ref) { | 83 | if (ref) { |
72 | SnapEntry sn = SNAP_TR(s, tr); | 84 | SnapEntry sn = SNAP_TR(s, tr); |
73 | IRIns *ir = &J->cur.ir[ref]; | 85 | IRIns *ir = &J->cur.ir[ref]; |
74 | if (!(sn & (SNAP_CONT|SNAP_FRAME)) && | 86 | if ((LJ_FR2 || !(sn & (SNAP_CONT|SNAP_FRAME))) && |
75 | ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { | 87 | ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { |
76 | /* No need to snapshot unmodified non-inherited slots. */ | 88 | /* |
77 | if (!(ir->op2 & IRSLOAD_INHERIT)) | 89 | ** No need to snapshot unmodified non-inherited slots. |
90 | ** But always snapshot the function below a frame in LJ_FR2 mode. | ||
91 | */ | ||
92 | if (!(ir->op2 & IRSLOAD_INHERIT) && | ||
93 | (!LJ_FR2 || s == 0 || s+1 == nslots || | ||
94 | !(J->slot[s+1] & (TREF_CONT|TREF_FRAME)))) | ||
78 | continue; | 95 | continue; |
79 | /* No need to restore readonly slots and unmodified non-parent slots. */ | 96 | /* No need to restore readonly slots and unmodified non-parent slots. */ |
80 | if (!(LJ_DUALNUM && (ir->op2 & IRSLOAD_CONVERT)) && | 97 | if (!(LJ_DUALNUM && (ir->op2 & IRSLOAD_CONVERT)) && |
81 | (ir->op2 & (IRSLOAD_READONLY|IRSLOAD_PARENT)) != IRSLOAD_PARENT) | 98 | (ir->op2 & (IRSLOAD_READONLY|IRSLOAD_PARENT)) != IRSLOAD_PARENT) |
82 | sn |= SNAP_NORESTORE; | 99 | sn |= SNAP_NORESTORE; |
83 | } | 100 | } |
84 | if (LJ_SOFTFP && irt_isnum(ir->t)) | 101 | if (LJ_SOFTFP32 && irt_isnum(ir->t)) |
85 | sn |= SNAP_SOFTFPNUM; | 102 | sn |= SNAP_SOFTFPNUM; |
86 | map[n++] = sn; | 103 | map[n++] = sn; |
87 | } | 104 | } |
@@ -90,35 +107,54 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) | |||
90 | } | 107 | } |
91 | 108 | ||
92 | /* Add frame links at the end of the snapshot. */ | 109 | /* Add frame links at the end of the snapshot. */ |
93 | static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map) | 110 | static MSize snapshot_framelinks(jit_State *J, SnapEntry *map, uint8_t *topslot) |
94 | { | 111 | { |
95 | cTValue *frame = J->L->base - 1; | 112 | cTValue *frame = J->L->base - 1; |
96 | cTValue *lim = J->L->base - J->baseslot; | 113 | cTValue *lim = J->L->base - J->baseslot + LJ_FR2; |
97 | cTValue *ftop = frame + funcproto(frame_func(frame))->framesize; | 114 | GCfunc *fn = frame_func(frame); |
115 | cTValue *ftop = isluafunc(fn) ? (frame+funcproto(fn)->framesize) : J->L->top; | ||
116 | #if LJ_FR2 | ||
117 | uint64_t pcbase = (u64ptr(J->pc) << 8) | (J->baseslot - 2); | ||
118 | lj_assertJ(2 <= J->baseslot && J->baseslot <= 257, "bad baseslot"); | ||
119 | memcpy(map, &pcbase, sizeof(uint64_t)); | ||
120 | #else | ||
98 | MSize f = 0; | 121 | MSize f = 0; |
99 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ | 122 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ |
100 | lua_assert(!J->pt || | 123 | #endif |
124 | lj_assertJ(!J->pt || | ||
101 | (J->pc >= proto_bc(J->pt) && | 125 | (J->pc >= proto_bc(J->pt) && |
102 | J->pc < proto_bc(J->pt) + J->pt->sizebc)); | 126 | J->pc < proto_bc(J->pt) + J->pt->sizebc), "bad snapshot PC"); |
103 | while (frame > lim) { /* Backwards traversal of all frames above base. */ | 127 | while (frame > lim) { /* Backwards traversal of all frames above base. */ |
104 | if (frame_islua(frame)) { | 128 | if (frame_islua(frame)) { |
129 | #if !LJ_FR2 | ||
105 | map[f++] = SNAP_MKPC(frame_pc(frame)); | 130 | map[f++] = SNAP_MKPC(frame_pc(frame)); |
131 | #endif | ||
106 | frame = frame_prevl(frame); | 132 | frame = frame_prevl(frame); |
107 | } else if (frame_iscont(frame)) { | 133 | } else if (frame_iscont(frame)) { |
134 | #if !LJ_FR2 | ||
108 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | 135 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); |
109 | map[f++] = SNAP_MKPC(frame_contpc(frame)); | 136 | map[f++] = SNAP_MKPC(frame_contpc(frame)); |
137 | #endif | ||
110 | frame = frame_prevd(frame); | 138 | frame = frame_prevd(frame); |
111 | } else { | 139 | } else { |
112 | lua_assert(!frame_isc(frame)); | 140 | lj_assertJ(!frame_isc(frame), "broken frame chain"); |
141 | #if !LJ_FR2 | ||
113 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | 142 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); |
143 | #endif | ||
114 | frame = frame_prevd(frame); | 144 | frame = frame_prevd(frame); |
115 | continue; | 145 | continue; |
116 | } | 146 | } |
117 | if (frame + funcproto(frame_func(frame))->framesize > ftop) | 147 | if (frame + funcproto(frame_func(frame))->framesize > ftop) |
118 | ftop = frame + funcproto(frame_func(frame))->framesize; | 148 | ftop = frame + funcproto(frame_func(frame))->framesize; |
119 | } | 149 | } |
120 | lua_assert(f == (MSize)(1 + J->framedepth)); | 150 | *topslot = (uint8_t)(ftop - lim); |
121 | return (BCReg)(ftop - lim); | 151 | #if LJ_FR2 |
152 | lj_assertJ(sizeof(SnapEntry) * 2 == sizeof(uint64_t), "bad SnapEntry def"); | ||
153 | return 2; | ||
154 | #else | ||
155 | lj_assertJ(f == (MSize)(1 + J->framedepth), "miscalculated snapshot size"); | ||
156 | return f; | ||
157 | #endif | ||
122 | } | 158 | } |
123 | 159 | ||
124 | /* Take a snapshot of the current stack. */ | 160 | /* Take a snapshot of the current stack. */ |
@@ -128,16 +164,17 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) | |||
128 | MSize nent; | 164 | MSize nent; |
129 | SnapEntry *p; | 165 | SnapEntry *p; |
130 | /* Conservative estimate. */ | 166 | /* Conservative estimate. */ |
131 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1); | 167 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)(LJ_FR2?2:J->framedepth+1)); |
132 | p = &J->cur.snapmap[nsnapmap]; | 168 | p = &J->cur.snapmap[nsnapmap]; |
133 | nent = snapshot_slots(J, p, nslots); | 169 | nent = snapshot_slots(J, p, nslots); |
134 | snap->topslot = (uint8_t)snapshot_framelinks(J, p + nent); | 170 | snap->nent = (uint8_t)nent; |
171 | nent += snapshot_framelinks(J, p + nent, &snap->topslot); | ||
135 | snap->mapofs = (uint32_t)nsnapmap; | 172 | snap->mapofs = (uint32_t)nsnapmap; |
136 | snap->ref = (IRRef1)J->cur.nins; | 173 | snap->ref = (IRRef1)J->cur.nins; |
137 | snap->nent = (uint8_t)nent; | 174 | snap->mcofs = 0; |
138 | snap->nslots = (uint8_t)nslots; | 175 | snap->nslots = (uint8_t)nslots; |
139 | snap->count = 0; | 176 | snap->count = 0; |
140 | J->cur.nsnapmap = (uint32_t)(nsnapmap + nent + 1 + J->framedepth); | 177 | J->cur.nsnapmap = (uint32_t)(nsnapmap + nent); |
141 | } | 178 | } |
142 | 179 | ||
143 | /* Add or merge a snapshot. */ | 180 | /* Add or merge a snapshot. */ |
@@ -146,8 +183,8 @@ void lj_snap_add(jit_State *J) | |||
146 | MSize nsnap = J->cur.nsnap; | 183 | MSize nsnap = J->cur.nsnap; |
147 | MSize nsnapmap = J->cur.nsnapmap; | 184 | MSize nsnapmap = J->cur.nsnapmap; |
148 | /* Merge if no ins. inbetween or if requested and no guard inbetween. */ | 185 | /* Merge if no ins. inbetween or if requested and no guard inbetween. */ |
149 | if (J->mergesnap ? !irt_isguard(J->guardemit) : | 186 | if ((nsnap > 0 && J->cur.snap[nsnap-1].ref == J->cur.nins) || |
150 | (nsnap > 0 && J->cur.snap[nsnap-1].ref == J->cur.nins)) { | 187 | (J->mergesnap && !irt_isguard(J->guardemit))) { |
151 | if (nsnap == 1) { /* But preserve snap #0 PC. */ | 188 | if (nsnap == 1) { /* But preserve snap #0 PC. */ |
152 | emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0); | 189 | emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0); |
153 | goto nomerge; | 190 | goto nomerge; |
@@ -194,7 +231,8 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf, | |||
194 | #define DEF_SLOT(s) udf[(s)] *= 3 | 231 | #define DEF_SLOT(s) udf[(s)] *= 3 |
195 | 232 | ||
196 | /* Scan through following bytecode and check for uses/defs. */ | 233 | /* Scan through following bytecode and check for uses/defs. */ |
197 | lua_assert(pc >= proto_bc(J->pt) && pc < proto_bc(J->pt) + J->pt->sizebc); | 234 | lj_assertJ(pc >= proto_bc(J->pt) && pc < proto_bc(J->pt) + J->pt->sizebc, |
235 | "snapshot PC out of range"); | ||
198 | for (;;) { | 236 | for (;;) { |
199 | BCIns ins = *pc++; | 237 | BCIns ins = *pc++; |
200 | BCOp op = bc_op(ins); | 238 | BCOp op = bc_op(ins); |
@@ -205,7 +243,7 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf, | |||
205 | switch (bcmode_c(op)) { | 243 | switch (bcmode_c(op)) { |
206 | case BCMvar: USE_SLOT(bc_c(ins)); break; | 244 | case BCMvar: USE_SLOT(bc_c(ins)); break; |
207 | case BCMrbase: | 245 | case BCMrbase: |
208 | lua_assert(op == BC_CAT); | 246 | lj_assertJ(op == BC_CAT, "unhandled op %d with RC rbase", op); |
209 | for (s = bc_b(ins); s <= bc_c(ins); s++) USE_SLOT(s); | 247 | for (s = bc_b(ins); s <= bc_c(ins); s++) USE_SLOT(s); |
210 | for (; s < maxslot; s++) DEF_SLOT(s); | 248 | for (; s < maxslot; s++) DEF_SLOT(s); |
211 | break; | 249 | break; |
@@ -245,7 +283,8 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf, | |||
245 | case BCMbase: | 283 | case BCMbase: |
246 | if (op >= BC_CALLM && op <= BC_ITERN) { | 284 | if (op >= BC_CALLM && op <= BC_ITERN) { |
247 | BCReg top = (op == BC_CALLM || op == BC_CALLMT || bc_c(ins) == 0) ? | 285 | BCReg top = (op == BC_CALLM || op == BC_CALLMT || bc_c(ins) == 0) ? |
248 | maxslot : (bc_a(ins) + bc_c(ins)); | 286 | maxslot : (bc_a(ins) + bc_c(ins)+LJ_FR2); |
287 | if (LJ_FR2) DEF_SLOT(bc_a(ins)+1); | ||
249 | s = bc_a(ins) - ((op == BC_ITERC || op == BC_ITERN) ? 3 : 0); | 288 | s = bc_a(ins) - ((op == BC_ITERC || op == BC_ITERN) ? 3 : 0); |
250 | for (; s < top; s++) USE_SLOT(s); | 289 | for (; s < top; s++) USE_SLOT(s); |
251 | for (; s < maxslot; s++) DEF_SLOT(s); | 290 | for (; s < maxslot; s++) DEF_SLOT(s); |
@@ -263,7 +302,8 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf, | |||
263 | break; | 302 | break; |
264 | default: break; | 303 | default: break; |
265 | } | 304 | } |
266 | lua_assert(pc >= proto_bc(J->pt) && pc < proto_bc(J->pt) + J->pt->sizebc); | 305 | lj_assertJ(pc >= proto_bc(J->pt) && pc < proto_bc(J->pt) + J->pt->sizebc, |
306 | "use/def analysis PC out of range"); | ||
267 | } | 307 | } |
268 | 308 | ||
269 | #undef USE_SLOT | 309 | #undef USE_SLOT |
@@ -321,8 +361,8 @@ void lj_snap_shrink(jit_State *J) | |||
321 | MSize n, m, nlim, nent = snap->nent; | 361 | MSize n, m, nlim, nent = snap->nent; |
322 | uint8_t udf[SNAP_USEDEF_SLOTS]; | 362 | uint8_t udf[SNAP_USEDEF_SLOTS]; |
323 | BCReg maxslot = J->maxslot; | 363 | BCReg maxslot = J->maxslot; |
324 | BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot); | ||
325 | BCReg baseslot = J->baseslot; | 364 | BCReg baseslot = J->baseslot; |
365 | BCReg minslot = snap_usedef(J, udf, snap_pc(&map[nent]), maxslot); | ||
326 | if (minslot < maxslot) snap_useuv(J->pt, udf); | 366 | if (minslot < maxslot) snap_useuv(J->pt, udf); |
327 | maxslot += baseslot; | 367 | maxslot += baseslot; |
328 | minslot += baseslot; | 368 | minslot += baseslot; |
@@ -365,25 +405,26 @@ static RegSP snap_renameref(GCtrace *T, SnapNo lim, IRRef ref, RegSP rs) | |||
365 | } | 405 | } |
366 | 406 | ||
367 | /* Copy RegSP from parent snapshot to the parent links of the IR. */ | 407 | /* Copy RegSP from parent snapshot to the parent links of the IR. */ |
368 | IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir) | 408 | IRIns *lj_snap_regspmap(jit_State *J, GCtrace *T, SnapNo snapno, IRIns *ir) |
369 | { | 409 | { |
370 | SnapShot *snap = &T->snap[snapno]; | 410 | SnapShot *snap = &T->snap[snapno]; |
371 | SnapEntry *map = &T->snapmap[snap->mapofs]; | 411 | SnapEntry *map = &T->snapmap[snap->mapofs]; |
372 | BloomFilter rfilt = snap_renamefilter(T, snapno); | 412 | BloomFilter rfilt = snap_renamefilter(T, snapno); |
373 | MSize n = 0; | 413 | MSize n = 0; |
374 | IRRef ref = 0; | 414 | IRRef ref = 0; |
415 | UNUSED(J); | ||
375 | for ( ; ; ir++) { | 416 | for ( ; ; ir++) { |
376 | uint32_t rs; | 417 | uint32_t rs; |
377 | if (ir->o == IR_SLOAD) { | 418 | if (ir->o == IR_SLOAD) { |
378 | if (!(ir->op2 & IRSLOAD_PARENT)) break; | 419 | if (!(ir->op2 & IRSLOAD_PARENT)) break; |
379 | for ( ; ; n++) { | 420 | for ( ; ; n++) { |
380 | lua_assert(n < snap->nent); | 421 | lj_assertJ(n < snap->nent, "slot %d not found in snapshot", ir->op1); |
381 | if (snap_slot(map[n]) == ir->op1) { | 422 | if (snap_slot(map[n]) == ir->op1) { |
382 | ref = snap_ref(map[n++]); | 423 | ref = snap_ref(map[n++]); |
383 | break; | 424 | break; |
384 | } | 425 | } |
385 | } | 426 | } |
386 | } else if (LJ_SOFTFP && ir->o == IR_HIOP) { | 427 | } else if (LJ_SOFTFP32 && ir->o == IR_HIOP) { |
387 | ref++; | 428 | ref++; |
388 | } else if (ir->o == IR_PVAL) { | 429 | } else if (ir->o == IR_PVAL) { |
389 | ref = ir->op1 + REF_BIAS; | 430 | ref = ir->op1 + REF_BIAS; |
@@ -394,7 +435,7 @@ IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir) | |||
394 | if (bloomtest(rfilt, ref)) | 435 | if (bloomtest(rfilt, ref)) |
395 | rs = snap_renameref(T, snapno, ref, rs); | 436 | rs = snap_renameref(T, snapno, ref, rs); |
396 | ir->prev = (uint16_t)rs; | 437 | ir->prev = (uint16_t)rs; |
397 | lua_assert(regsp_used(rs)); | 438 | lj_assertJ(regsp_used(rs), "unused IR %04d in snapshot", ref - REF_BIAS); |
398 | } | 439 | } |
399 | return ir; | 440 | return ir; |
400 | } | 441 | } |
@@ -409,10 +450,10 @@ static TRef snap_replay_const(jit_State *J, IRIns *ir) | |||
409 | case IR_KPRI: return TREF_PRI(irt_type(ir->t)); | 450 | case IR_KPRI: return TREF_PRI(irt_type(ir->t)); |
410 | case IR_KINT: return lj_ir_kint(J, ir->i); | 451 | case IR_KINT: return lj_ir_kint(J, ir->i); |
411 | case IR_KGC: return lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); | 452 | case IR_KGC: return lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); |
412 | case IR_KNUM: return lj_ir_k64(J, IR_KNUM, ir_knum(ir)); | 453 | case IR_KNUM: case IR_KINT64: |
413 | case IR_KINT64: return lj_ir_k64(J, IR_KINT64, ir_kint64(ir)); | 454 | return lj_ir_k64(J, (IROp)ir->o, ir_k64(ir)->u64); |
414 | case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir)); /* Continuation. */ | 455 | case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir)); /* Continuation. */ |
415 | default: lua_assert(0); return TREF_NIL; break; | 456 | default: lj_assertJ(0, "bad IR constant op %d", ir->o); return TREF_NIL; |
416 | } | 457 | } |
417 | } | 458 | } |
418 | 459 | ||
@@ -422,7 +463,7 @@ static TRef snap_dedup(jit_State *J, SnapEntry *map, MSize nmax, IRRef ref) | |||
422 | MSize j; | 463 | MSize j; |
423 | for (j = 0; j < nmax; j++) | 464 | for (j = 0; j < nmax; j++) |
424 | if (snap_ref(map[j]) == ref) | 465 | if (snap_ref(map[j]) == ref) |
425 | return J->slot[snap_slot(map[j])] & ~(SNAP_CONT|SNAP_FRAME); | 466 | return J->slot[snap_slot(map[j])] & ~(SNAP_KEYINDEX|SNAP_CONT|SNAP_FRAME); |
426 | return 0; | 467 | return 0; |
427 | } | 468 | } |
428 | 469 | ||
@@ -483,21 +524,27 @@ void lj_snap_replay(jit_State *J, GCtrace *T) | |||
483 | goto setslot; | 524 | goto setslot; |
484 | bloomset(seen, ref); | 525 | bloomset(seen, ref); |
485 | if (irref_isk(ref)) { | 526 | if (irref_isk(ref)) { |
486 | tr = snap_replay_const(J, ir); | 527 | /* See special treatment of LJ_FR2 slot 1 in snapshot_slots() above. */ |
528 | if (LJ_FR2 && (sn == SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL))) | ||
529 | tr = 0; | ||
530 | else | ||
531 | tr = snap_replay_const(J, ir); | ||
487 | } else if (!regsp_used(ir->prev)) { | 532 | } else if (!regsp_used(ir->prev)) { |
488 | pass23 = 1; | 533 | pass23 = 1; |
489 | lua_assert(s != 0); | 534 | lj_assertJ(s != 0, "unused slot 0 in snapshot"); |
490 | tr = s; | 535 | tr = s; |
491 | } else { | 536 | } else { |
492 | IRType t = irt_type(ir->t); | 537 | IRType t = irt_type(ir->t); |
493 | uint32_t mode = IRSLOAD_INHERIT|IRSLOAD_PARENT; | 538 | uint32_t mode = IRSLOAD_INHERIT|IRSLOAD_PARENT; |
494 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM; | 539 | if (LJ_SOFTFP32 && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM; |
495 | if (ir->o == IR_SLOAD) mode |= (ir->op2 & IRSLOAD_READONLY); | 540 | if (ir->o == IR_SLOAD) mode |= (ir->op2 & IRSLOAD_READONLY); |
541 | if ((sn & SNAP_KEYINDEX)) mode |= IRSLOAD_KEYINDEX; | ||
496 | tr = emitir_raw(IRT(IR_SLOAD, t), s, mode); | 542 | tr = emitir_raw(IRT(IR_SLOAD, t), s, mode); |
497 | } | 543 | } |
498 | setslot: | 544 | setslot: |
499 | J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */ | 545 | /* Same as TREF_* flags. */ |
500 | J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && s); | 546 | J->slot[s] = tr | (sn&(SNAP_KEYINDEX|SNAP_CONT|SNAP_FRAME)); |
547 | J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && (s != LJ_FR2)); | ||
501 | if ((sn & SNAP_FRAME)) | 548 | if ((sn & SNAP_FRAME)) |
502 | J->baseslot = s+1; | 549 | J->baseslot = s+1; |
503 | } | 550 | } |
@@ -512,8 +559,9 @@ void lj_snap_replay(jit_State *J, GCtrace *T) | |||
512 | if (regsp_reg(ir->r) == RID_SUNK) { | 559 | if (regsp_reg(ir->r) == RID_SUNK) { |
513 | if (J->slot[snap_slot(sn)] != snap_slot(sn)) continue; | 560 | if (J->slot[snap_slot(sn)] != snap_slot(sn)) continue; |
514 | pass23 = 1; | 561 | pass23 = 1; |
515 | lua_assert(ir->o == IR_TNEW || ir->o == IR_TDUP || | 562 | lj_assertJ(ir->o == IR_TNEW || ir->o == IR_TDUP || |
516 | ir->o == IR_CNEW || ir->o == IR_CNEWI); | 563 | ir->o == IR_CNEW || ir->o == IR_CNEWI, |
564 | "sunk parent IR %04d has bad op %d", refp - REF_BIAS, ir->o); | ||
517 | if (ir->op1 >= T->nk) snap_pref(J, T, map, nent, seen, ir->op1); | 565 | if (ir->op1 >= T->nk) snap_pref(J, T, map, nent, seen, ir->op1); |
518 | if (ir->op2 >= T->nk) snap_pref(J, T, map, nent, seen, ir->op2); | 566 | if (ir->op2 >= T->nk) snap_pref(J, T, map, nent, seen, ir->op2); |
519 | if (LJ_HASFFI && ir->o == IR_CNEWI) { | 567 | if (LJ_HASFFI && ir->o == IR_CNEWI) { |
@@ -525,13 +573,14 @@ void lj_snap_replay(jit_State *J, GCtrace *T) | |||
525 | if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { | 573 | if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { |
526 | if (snap_pref(J, T, map, nent, seen, irs->op2) == 0) | 574 | if (snap_pref(J, T, map, nent, seen, irs->op2) == 0) |
527 | snap_pref(J, T, map, nent, seen, T->ir[irs->op2].op1); | 575 | snap_pref(J, T, map, nent, seen, T->ir[irs->op2].op1); |
528 | else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) && | 576 | else if ((LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)) && |
529 | irs+1 < irlast && (irs+1)->o == IR_HIOP) | 577 | irs+1 < irlast && (irs+1)->o == IR_HIOP) |
530 | snap_pref(J, T, map, nent, seen, (irs+1)->op2); | 578 | snap_pref(J, T, map, nent, seen, (irs+1)->op2); |
531 | } | 579 | } |
532 | } | 580 | } |
533 | } else if (!irref_isk(refp) && !regsp_used(ir->prev)) { | 581 | } else if (!irref_isk(refp) && !regsp_used(ir->prev)) { |
534 | lua_assert(ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT); | 582 | lj_assertJ(ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT, |
583 | "sunk parent IR %04d has bad op %d", refp - REF_BIAS, ir->o); | ||
535 | J->slot[snap_slot(sn)] = snap_pref(J, T, map, nent, seen, ir->op1); | 584 | J->slot[snap_slot(sn)] = snap_pref(J, T, map, nent, seen, ir->op1); |
536 | } | 585 | } |
537 | } | 586 | } |
@@ -581,20 +630,21 @@ void lj_snap_replay(jit_State *J, GCtrace *T) | |||
581 | val = snap_pref(J, T, map, nent, seen, irs->op2); | 630 | val = snap_pref(J, T, map, nent, seen, irs->op2); |
582 | if (val == 0) { | 631 | if (val == 0) { |
583 | IRIns *irc = &T->ir[irs->op2]; | 632 | IRIns *irc = &T->ir[irs->op2]; |
584 | lua_assert(irc->o == IR_CONV && irc->op2 == IRCONV_NUM_INT); | 633 | lj_assertJ(irc->o == IR_CONV && irc->op2 == IRCONV_NUM_INT, |
634 | "sunk store for parent IR %04d with bad op %d", | ||
635 | refp - REF_BIAS, irc->o); | ||
585 | val = snap_pref(J, T, map, nent, seen, irc->op1); | 636 | val = snap_pref(J, T, map, nent, seen, irc->op1); |
586 | val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT); | 637 | val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT); |
587 | } else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) && | 638 | } else if ((LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)) && |
588 | irs+1 < irlast && (irs+1)->o == IR_HIOP) { | 639 | irs+1 < irlast && (irs+1)->o == IR_HIOP) { |
589 | IRType t = IRT_I64; | 640 | IRType t = IRT_I64; |
590 | if (LJ_SOFTFP && irt_type((irs+1)->t) == IRT_SOFTFP) | 641 | if (LJ_SOFTFP32 && irt_type((irs+1)->t) == IRT_SOFTFP) |
591 | t = IRT_NUM; | 642 | t = IRT_NUM; |
592 | lj_needsplit(J); | 643 | lj_needsplit(J); |
593 | if (irref_isk(irs->op2) && irref_isk((irs+1)->op2)) { | 644 | if (irref_isk(irs->op2) && irref_isk((irs+1)->op2)) { |
594 | uint64_t k = (uint32_t)T->ir[irs->op2].i + | 645 | uint64_t k = (uint32_t)T->ir[irs->op2].i + |
595 | ((uint64_t)T->ir[(irs+1)->op2].i << 32); | 646 | ((uint64_t)T->ir[(irs+1)->op2].i << 32); |
596 | val = lj_ir_k64(J, t == IRT_I64 ? IR_KINT64 : IR_KNUM, | 647 | val = lj_ir_k64(J, t == IRT_I64 ? IR_KINT64 : IR_KNUM, k); |
597 | lj_ir_k64_find(J, k)); | ||
598 | } else { | 648 | } else { |
599 | val = emitir_raw(IRT(IR_HIOP, t), val, | 649 | val = emitir_raw(IRT(IR_HIOP, t), val, |
600 | snap_pref(J, T, map, nent, seen, (irs+1)->op2)); | 650 | snap_pref(J, T, map, nent, seen, (irs+1)->op2)); |
@@ -632,7 +682,14 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, | |||
632 | IRType1 t = ir->t; | 682 | IRType1 t = ir->t; |
633 | RegSP rs = ir->prev; | 683 | RegSP rs = ir->prev; |
634 | if (irref_isk(ref)) { /* Restore constant slot. */ | 684 | if (irref_isk(ref)) { /* Restore constant slot. */ |
635 | lj_ir_kvalue(J->L, o, ir); | 685 | if (ir->o == IR_KPTR) { |
686 | o->u64 = (uint64_t)(uintptr_t)ir_kptr(ir); | ||
687 | } else { | ||
688 | lj_assertJ(!(ir->o == IR_KKPTR || ir->o == IR_KNULL), | ||
689 | "restore of const from IR %04d with bad op %d", | ||
690 | ref - REF_BIAS, ir->o); | ||
691 | lj_ir_kvalue(J->L, o, ir); | ||
692 | } | ||
636 | return; | 693 | return; |
637 | } | 694 | } |
638 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) | 695 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) |
@@ -641,22 +698,24 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, | |||
641 | int32_t *sps = &ex->spill[regsp_spill(rs)]; | 698 | int32_t *sps = &ex->spill[regsp_spill(rs)]; |
642 | if (irt_isinteger(t)) { | 699 | if (irt_isinteger(t)) { |
643 | setintV(o, *sps); | 700 | setintV(o, *sps); |
644 | #if !LJ_SOFTFP | 701 | #if !LJ_SOFTFP32 |
645 | } else if (irt_isnum(t)) { | 702 | } else if (irt_isnum(t)) { |
646 | o->u64 = *(uint64_t *)sps; | 703 | o->u64 = *(uint64_t *)sps; |
647 | #endif | 704 | #endif |
648 | } else if (LJ_64 && irt_islightud(t)) { | 705 | #if LJ_64 && !LJ_GC64 |
706 | } else if (irt_islightud(t)) { | ||
649 | /* 64 bit lightuserdata which may escape already has the tag bits. */ | 707 | /* 64 bit lightuserdata which may escape already has the tag bits. */ |
650 | o->u64 = *(uint64_t *)sps; | 708 | o->u64 = *(uint64_t *)sps; |
709 | #endif | ||
651 | } else { | 710 | } else { |
652 | lua_assert(!irt_ispri(t)); /* PRI refs never have a spill slot. */ | 711 | lj_assertJ(!irt_ispri(t), "PRI ref with spill slot"); |
653 | setgcrefi(o->gcr, *sps); | 712 | setgcV(J->L, o, (GCobj *)(uintptr_t)*(GCSize *)sps, irt_toitype(t)); |
654 | setitype(o, irt_toitype(t)); | ||
655 | } | 713 | } |
656 | } else { /* Restore from register. */ | 714 | } else { /* Restore from register. */ |
657 | Reg r = regsp_reg(rs); | 715 | Reg r = regsp_reg(rs); |
658 | if (ra_noreg(r)) { | 716 | if (ra_noreg(r)) { |
659 | lua_assert(ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT); | 717 | lj_assertJ(ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT, |
718 | "restore from IR %04d has no reg", ref - REF_BIAS); | ||
660 | snap_restoreval(J, T, ex, snapno, rfilt, ir->op1, o); | 719 | snap_restoreval(J, T, ex, snapno, rfilt, ir->op1, o); |
661 | if (LJ_DUALNUM) setnumV(o, (lua_Number)intV(o)); | 720 | if (LJ_DUALNUM) setnumV(o, (lua_Number)intV(o)); |
662 | return; | 721 | return; |
@@ -665,21 +724,26 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, | |||
665 | #if !LJ_SOFTFP | 724 | #if !LJ_SOFTFP |
666 | } else if (irt_isnum(t)) { | 725 | } else if (irt_isnum(t)) { |
667 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); | 726 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); |
727 | #elif LJ_64 /* && LJ_SOFTFP */ | ||
728 | } else if (irt_isnum(t)) { | ||
729 | o->u64 = ex->gpr[r-RID_MIN_GPR]; | ||
668 | #endif | 730 | #endif |
669 | } else if (LJ_64 && irt_islightud(t)) { | 731 | #if LJ_64 && !LJ_GC64 |
670 | /* 64 bit lightuserdata which may escape already has the tag bits. */ | 732 | } else if (irt_is64(t)) { |
733 | /* 64 bit values that already have the tag bits. */ | ||
671 | o->u64 = ex->gpr[r-RID_MIN_GPR]; | 734 | o->u64 = ex->gpr[r-RID_MIN_GPR]; |
735 | #endif | ||
736 | } else if (irt_ispri(t)) { | ||
737 | setpriV(o, irt_toitype(t)); | ||
672 | } else { | 738 | } else { |
673 | if (!irt_ispri(t)) | 739 | setgcV(J->L, o, (GCobj *)ex->gpr[r-RID_MIN_GPR], irt_toitype(t)); |
674 | setgcrefi(o->gcr, ex->gpr[r-RID_MIN_GPR]); | ||
675 | setitype(o, irt_toitype(t)); | ||
676 | } | 740 | } |
677 | } | 741 | } |
678 | } | 742 | } |
679 | 743 | ||
680 | #if LJ_HASFFI | 744 | #if LJ_HASFFI |
681 | /* Restore raw data from the trace exit state. */ | 745 | /* Restore raw data from the trace exit state. */ |
682 | static void snap_restoredata(GCtrace *T, ExitState *ex, | 746 | static void snap_restoredata(jit_State *J, GCtrace *T, ExitState *ex, |
683 | SnapNo snapno, BloomFilter rfilt, | 747 | SnapNo snapno, BloomFilter rfilt, |
684 | IRRef ref, void *dst, CTSize sz) | 748 | IRRef ref, void *dst, CTSize sz) |
685 | { | 749 | { |
@@ -687,9 +751,10 @@ static void snap_restoredata(GCtrace *T, ExitState *ex, | |||
687 | RegSP rs = ir->prev; | 751 | RegSP rs = ir->prev; |
688 | int32_t *src; | 752 | int32_t *src; |
689 | uint64_t tmp; | 753 | uint64_t tmp; |
754 | UNUSED(J); | ||
690 | if (irref_isk(ref)) { | 755 | if (irref_isk(ref)) { |
691 | if (ir->o == IR_KNUM || ir->o == IR_KINT64) { | 756 | if (ir_isk64(ir)) { |
692 | src = mref(ir->ptr, int32_t); | 757 | src = (int32_t *)&ir[1]; |
693 | } else if (sz == 8) { | 758 | } else if (sz == 8) { |
694 | tmp = (uint64_t)(uint32_t)ir->i; | 759 | tmp = (uint64_t)(uint32_t)ir->i; |
695 | src = (int32_t *)&tmp; | 760 | src = (int32_t *)&tmp; |
@@ -709,8 +774,9 @@ static void snap_restoredata(GCtrace *T, ExitState *ex, | |||
709 | Reg r = regsp_reg(rs); | 774 | Reg r = regsp_reg(rs); |
710 | if (ra_noreg(r)) { | 775 | if (ra_noreg(r)) { |
711 | /* Note: this assumes CNEWI is never used for SOFTFP split numbers. */ | 776 | /* Note: this assumes CNEWI is never used for SOFTFP split numbers. */ |
712 | lua_assert(sz == 8 && ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT); | 777 | lj_assertJ(sz == 8 && ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT, |
713 | snap_restoredata(T, ex, snapno, rfilt, ir->op1, dst, 4); | 778 | "restore from IR %04d has no reg", ref - REF_BIAS); |
779 | snap_restoredata(J, T, ex, snapno, rfilt, ir->op1, dst, 4); | ||
714 | *(lua_Number *)dst = (lua_Number)*(int32_t *)dst; | 780 | *(lua_Number *)dst = (lua_Number)*(int32_t *)dst; |
715 | return; | 781 | return; |
716 | } | 782 | } |
@@ -726,11 +792,13 @@ static void snap_restoredata(GCtrace *T, ExitState *ex, | |||
726 | #else | 792 | #else |
727 | if (LJ_BE && sz == 4) src++; | 793 | if (LJ_BE && sz == 4) src++; |
728 | #endif | 794 | #endif |
729 | } | 795 | } else |
730 | #endif | 796 | #endif |
797 | if (LJ_64 && LJ_BE && sz == 4) src++; | ||
731 | } | 798 | } |
732 | } | 799 | } |
733 | lua_assert(sz == 1 || sz == 2 || sz == 4 || sz == 8); | 800 | lj_assertJ(sz == 1 || sz == 2 || sz == 4 || sz == 8, |
801 | "restore from IR %04d with bad size %d", ref - REF_BIAS, sz); | ||
734 | if (sz == 4) *(int32_t *)dst = *src; | 802 | if (sz == 4) *(int32_t *)dst = *src; |
735 | else if (sz == 8) *(int64_t *)dst = *(int64_t *)src; | 803 | else if (sz == 8) *(int64_t *)dst = *(int64_t *)src; |
736 | else if (sz == 1) *(int8_t *)dst = (int8_t)*src; | 804 | else if (sz == 1) *(int8_t *)dst = (int8_t)*src; |
@@ -743,24 +811,27 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, | |||
743 | SnapNo snapno, BloomFilter rfilt, | 811 | SnapNo snapno, BloomFilter rfilt, |
744 | IRIns *ir, TValue *o) | 812 | IRIns *ir, TValue *o) |
745 | { | 813 | { |
746 | lua_assert(ir->o == IR_TNEW || ir->o == IR_TDUP || | 814 | lj_assertJ(ir->o == IR_TNEW || ir->o == IR_TDUP || |
747 | ir->o == IR_CNEW || ir->o == IR_CNEWI); | 815 | ir->o == IR_CNEW || ir->o == IR_CNEWI, |
816 | "sunk allocation with bad op %d", ir->o); | ||
748 | #if LJ_HASFFI | 817 | #if LJ_HASFFI |
749 | if (ir->o == IR_CNEW || ir->o == IR_CNEWI) { | 818 | if (ir->o == IR_CNEW || ir->o == IR_CNEWI) { |
750 | CTState *cts = ctype_cts(J->L); | 819 | CTState *cts = ctype_cts(J->L); |
751 | CTypeID id = (CTypeID)T->ir[ir->op1].i; | 820 | CTypeID id = (CTypeID)T->ir[ir->op1].i; |
752 | CTSize sz = lj_ctype_size(cts, id); | 821 | CTSize sz; |
753 | GCcdata *cd = lj_cdata_new(cts, id, sz); | 822 | CTInfo info = lj_ctype_info(cts, id, &sz); |
823 | GCcdata *cd = lj_cdata_newx(cts, id, sz, info); | ||
754 | setcdataV(J->L, o, cd); | 824 | setcdataV(J->L, o, cd); |
755 | if (ir->o == IR_CNEWI) { | 825 | if (ir->o == IR_CNEWI) { |
756 | uint8_t *p = (uint8_t *)cdataptr(cd); | 826 | uint8_t *p = (uint8_t *)cdataptr(cd); |
757 | lua_assert(sz == 4 || sz == 8); | 827 | lj_assertJ(sz == 4 || sz == 8, "sunk cdata with bad size %d", sz); |
758 | if (LJ_32 && sz == 8 && ir+1 < T->ir + T->nins && (ir+1)->o == IR_HIOP) { | 828 | if (LJ_32 && sz == 8 && ir+1 < T->ir + T->nins && (ir+1)->o == IR_HIOP) { |
759 | snap_restoredata(T, ex, snapno, rfilt, (ir+1)->op2, LJ_LE?p+4:p, 4); | 829 | snap_restoredata(J, T, ex, snapno, rfilt, (ir+1)->op2, |
830 | LJ_LE ? p+4 : p, 4); | ||
760 | if (LJ_BE) p += 4; | 831 | if (LJ_BE) p += 4; |
761 | sz = 4; | 832 | sz = 4; |
762 | } | 833 | } |
763 | snap_restoredata(T, ex, snapno, rfilt, ir->op2, p, sz); | 834 | snap_restoredata(J, T, ex, snapno, rfilt, ir->op2, p, sz); |
764 | } else { | 835 | } else { |
765 | IRIns *irs, *irlast = &T->ir[T->snap[snapno].ref]; | 836 | IRIns *irs, *irlast = &T->ir[T->snap[snapno].ref]; |
766 | for (irs = ir+1; irs < irlast; irs++) | 837 | for (irs = ir+1; irs < irlast; irs++) |
@@ -768,8 +839,11 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, | |||
768 | IRIns *iro = &T->ir[T->ir[irs->op1].op2]; | 839 | IRIns *iro = &T->ir[T->ir[irs->op1].op2]; |
769 | uint8_t *p = (uint8_t *)cd; | 840 | uint8_t *p = (uint8_t *)cd; |
770 | CTSize szs; | 841 | CTSize szs; |
771 | lua_assert(irs->o == IR_XSTORE && T->ir[irs->op1].o == IR_ADD); | 842 | lj_assertJ(irs->o == IR_XSTORE, "sunk store with bad op %d", irs->o); |
772 | lua_assert(iro->o == IR_KINT || iro->o == IR_KINT64); | 843 | lj_assertJ(T->ir[irs->op1].o == IR_ADD, |
844 | "sunk store with bad add op %d", T->ir[irs->op1].o); | ||
845 | lj_assertJ(iro->o == IR_KINT || iro->o == IR_KINT64, | ||
846 | "sunk store with bad const offset op %d", iro->o); | ||
773 | if (irt_is64(irs->t)) szs = 8; | 847 | if (irt_is64(irs->t)) szs = 8; |
774 | else if (irt_isi8(irs->t) || irt_isu8(irs->t)) szs = 1; | 848 | else if (irt_isi8(irs->t) || irt_isu8(irs->t)) szs = 1; |
775 | else if (irt_isi16(irs->t) || irt_isu16(irs->t)) szs = 2; | 849 | else if (irt_isi16(irs->t) || irt_isu16(irs->t)) szs = 2; |
@@ -778,14 +852,16 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, | |||
778 | p += (int64_t)ir_k64(iro)->u64; | 852 | p += (int64_t)ir_k64(iro)->u64; |
779 | else | 853 | else |
780 | p += iro->i; | 854 | p += iro->i; |
781 | lua_assert(p >= (uint8_t *)cdataptr(cd) && | 855 | lj_assertJ(p >= (uint8_t *)cdataptr(cd) && |
782 | p + szs <= (uint8_t *)cdataptr(cd) + sz); | 856 | p + szs <= (uint8_t *)cdataptr(cd) + sz, |
857 | "sunk store with offset out of range"); | ||
783 | if (LJ_32 && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) { | 858 | if (LJ_32 && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) { |
784 | lua_assert(szs == 4); | 859 | lj_assertJ(szs == 4, "sunk store with bad size %d", szs); |
785 | snap_restoredata(T, ex, snapno, rfilt, (irs+1)->op2, LJ_LE?p+4:p,4); | 860 | snap_restoredata(J, T, ex, snapno, rfilt, (irs+1)->op2, |
861 | LJ_LE ? p+4 : p, 4); | ||
786 | if (LJ_BE) p += 4; | 862 | if (LJ_BE) p += 4; |
787 | } | 863 | } |
788 | snap_restoredata(T, ex, snapno, rfilt, irs->op2, p, szs); | 864 | snap_restoredata(J, T, ex, snapno, rfilt, irs->op2, p, szs); |
789 | } | 865 | } |
790 | } | 866 | } |
791 | } else | 867 | } else |
@@ -800,10 +876,12 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, | |||
800 | if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { | 876 | if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { |
801 | IRIns *irk = &T->ir[irs->op1]; | 877 | IRIns *irk = &T->ir[irs->op1]; |
802 | TValue tmp, *val; | 878 | TValue tmp, *val; |
803 | lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE || | 879 | lj_assertJ(irs->o == IR_ASTORE || irs->o == IR_HSTORE || |
804 | irs->o == IR_FSTORE); | 880 | irs->o == IR_FSTORE, |
881 | "sunk store with bad op %d", irs->o); | ||
805 | if (irk->o == IR_FREF) { | 882 | if (irk->o == IR_FREF) { |
806 | lua_assert(irk->op2 == IRFL_TAB_META); | 883 | lj_assertJ(irk->op2 == IRFL_TAB_META, |
884 | "sunk store with bad field %d", irk->op2); | ||
807 | snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp); | 885 | snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp); |
808 | /* NOBARRIER: The table is new (marked white). */ | 886 | /* NOBARRIER: The table is new (marked white). */ |
809 | setgcref(t->metatable, obj2gco(tabV(&tmp))); | 887 | setgcref(t->metatable, obj2gco(tabV(&tmp))); |
@@ -814,7 +892,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, | |||
814 | val = lj_tab_set(J->L, t, &tmp); | 892 | val = lj_tab_set(J->L, t, &tmp); |
815 | /* NOBARRIER: The table is new (marked white). */ | 893 | /* NOBARRIER: The table is new (marked white). */ |
816 | snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, val); | 894 | snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, val); |
817 | if (LJ_SOFTFP && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) { | 895 | if (LJ_SOFTFP32 && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) { |
818 | snap_restoreval(J, T, ex, snapno, rfilt, (irs+1)->op2, &tmp); | 896 | snap_restoreval(J, T, ex, snapno, rfilt, (irs+1)->op2, &tmp); |
819 | val->u32.hi = tmp.u32.lo; | 897 | val->u32.hi = tmp.u32.lo; |
820 | } | 898 | } |
@@ -832,11 +910,15 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
832 | SnapShot *snap = &T->snap[snapno]; | 910 | SnapShot *snap = &T->snap[snapno]; |
833 | MSize n, nent = snap->nent; | 911 | MSize n, nent = snap->nent; |
834 | SnapEntry *map = &T->snapmap[snap->mapofs]; | 912 | SnapEntry *map = &T->snapmap[snap->mapofs]; |
835 | SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1]; | 913 | #if !LJ_FR2 || defined(LUA_USE_ASSERT) |
836 | int32_t ftsz0; | 914 | SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1-LJ_FR2]; |
915 | #endif | ||
916 | #if !LJ_FR2 | ||
917 | ptrdiff_t ftsz0; | ||
918 | #endif | ||
837 | TValue *frame; | 919 | TValue *frame; |
838 | BloomFilter rfilt = snap_renamefilter(T, snapno); | 920 | BloomFilter rfilt = snap_renamefilter(T, snapno); |
839 | const BCIns *pc = snap_pc(map[nent]); | 921 | const BCIns *pc = snap_pc(&map[nent]); |
840 | lua_State *L = J->L; | 922 | lua_State *L = J->L; |
841 | 923 | ||
842 | /* Set interpreter PC to the next PC to get correct error messages. */ | 924 | /* Set interpreter PC to the next PC to get correct error messages. */ |
@@ -849,8 +931,10 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
849 | } | 931 | } |
850 | 932 | ||
851 | /* Fill stack slots with data from the registers and spill slots. */ | 933 | /* Fill stack slots with data from the registers and spill slots. */ |
852 | frame = L->base-1; | 934 | frame = L->base-1-LJ_FR2; |
935 | #if !LJ_FR2 | ||
853 | ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */ | 936 | ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */ |
937 | #endif | ||
854 | for (n = 0; n < nent; n++) { | 938 | for (n = 0; n < nent; n++) { |
855 | SnapEntry sn = map[n]; | 939 | SnapEntry sn = map[n]; |
856 | if (!(sn & SNAP_NORESTORE)) { | 940 | if (!(sn & SNAP_NORESTORE)) { |
@@ -869,18 +953,27 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
869 | continue; | 953 | continue; |
870 | } | 954 | } |
871 | snap_restoreval(J, T, ex, snapno, rfilt, ref, o); | 955 | snap_restoreval(J, T, ex, snapno, rfilt, ref, o); |
872 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && tvisint(o)) { | 956 | if (LJ_SOFTFP32 && (sn & SNAP_SOFTFPNUM) && tvisint(o)) { |
873 | TValue tmp; | 957 | TValue tmp; |
874 | snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp); | 958 | snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp); |
875 | o->u32.hi = tmp.u32.lo; | 959 | o->u32.hi = tmp.u32.lo; |
960 | #if !LJ_FR2 | ||
876 | } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { | 961 | } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { |
877 | /* Overwrite tag with frame link. */ | 962 | /* Overwrite tag with frame link. */ |
878 | o->fr.tp.ftsz = snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0; | 963 | setframe_ftsz(o, snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0); |
879 | L->base = o+1; | 964 | L->base = o+1; |
965 | #endif | ||
966 | } else if ((sn & SNAP_KEYINDEX)) { | ||
967 | /* A IRT_INT key index slot is restored as a number. Undo this. */ | ||
968 | o->u32.lo = (uint32_t)(LJ_DUALNUM ? intV(o) : lj_num2int(numV(o))); | ||
969 | o->u32.hi = LJ_KEYINDEX; | ||
880 | } | 970 | } |
881 | } | 971 | } |
882 | } | 972 | } |
883 | lua_assert(map + nent == flinks); | 973 | #if LJ_FR2 |
974 | L->base += (map[nent+LJ_BE] & 0xff); | ||
975 | #endif | ||
976 | lj_assertJ(map + nent == flinks, "inconsistent frames in snapshot"); | ||
884 | 977 | ||
885 | /* Compute current stack top. */ | 978 | /* Compute current stack top. */ |
886 | switch (bc_op(*pc)) { | 979 | switch (bc_op(*pc)) { |