FFI: Fix snapshot substitution in SPLIT pass.

This commit is contained in:
Mike Pall 2013-03-23 14:51:23 +01:00
parent d147eedac9
commit 172bd95365

View File

@ -195,6 +195,19 @@ static IRRef split_ptr(jit_State *J, IRIns *oir, IRRef ref)
return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs));
}
/* Substitute references of a snapshot. */
static void split_subst_snap(jit_State *J, SnapShot *snap, IRIns *oir)
{
SnapEntry *map = &J->cur.snapmap[snap->mapofs];
MSize n, nent = snap->nent;
for (n = 0; n < nent; n++) {
SnapEntry sn = map[n];
IRIns *ir = &oir[snap_ref(sn)];
if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
map[n] = ((sn & 0xffff0000) | ir->prev);
}
}
/* Transform the old IR to the new IR. */
static void split_ir(jit_State *J)
{
@ -203,7 +216,8 @@ static void split_ir(jit_State *J)
MSize need = (irlen+1)*(sizeof(IRIns) + sizeof(IRRef1));
IRIns *oir = (IRIns *)lj_str_needbuf(J->L, &G(J->L)->tmpbuf, need);
IRRef1 *hisubst;
IRRef ref;
IRRef ref, snref;
SnapShot *snap;
/* Copy old IR to buffer. */
memcpy(oir, IR(nk), irlen*sizeof(IRIns));
@ -230,12 +244,20 @@ static void split_ir(jit_State *J)
}
/* Process old IR instructions. */
snap = J->cur.snap;
snref = snap->ref;
for (ref = REF_FIRST; ref < nins; ref++) {
IRIns *ir = &oir[ref];
IRRef nref = lj_ir_nextins(J);
IRIns *nir = IR(nref);
IRRef hi = 0;
if (ref >= snref) {
snap->ref = nref;
split_subst_snap(J, snap++, oir);
snref = snap < &J->cur.snap[J->cur.nsnap] ? snap->ref : ~(IRRef)0;
}
/* Copy-substitute old instruction to new instruction. */
nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev;
nir->op2 = ir->op2 < nk ? ir->op2 : oir[ir->op2].prev;
@ -635,6 +657,10 @@ static void split_ir(jit_State *J)
}
hisubst[ref] = hi; /* Store hiword substitution. */
}
if (snref == nins) { /* Substitution for last snapshot. */
snap->ref = J->cur.nins;
split_subst_snap(J, snap, oir);
}
/* Add PHI marks. */
for (ref = J->cur.nins-1; ref >= REF_FIRST; ref--) {
@ -643,24 +669,6 @@ static void split_ir(jit_State *J)
if (!irref_isk(ir->op1)) irt_setphi(IR(ir->op1)->t);
if (ir->op2 > J->loopref) irt_setphi(IR(ir->op2)->t);
}
/* Substitute snapshot maps. */
oir[nins].prev = J->cur.nins; /* Substitution for last snapshot. */
{
SnapNo i, nsnap = J->cur.nsnap;
for (i = 0; i < nsnap; i++) {
SnapShot *snap = &J->cur.snap[i];
SnapEntry *map = &J->cur.snapmap[snap->mapofs];
MSize n, nent = snap->nent;
snap->ref = snap->ref == REF_FIRST ? REF_FIRST : oir[snap->ref].prev;
for (n = 0; n < nent; n++) {
SnapEntry sn = map[n];
IRIns *ir = &oir[snap_ref(sn)];
if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
map[n] = ((sn & 0xffff0000) | ir->prev);
}
}
}
}
/* Protected callback for split pass. */