Add frame and continuation flags to TRef and SnapEntry.

This commit is contained in:
Mike Pall 2010-01-27 02:17:56 +01:00
parent 05d67cf566
commit d216cdb2b9
5 changed files with 56 additions and 38 deletions

View File

@ -2467,14 +2467,15 @@ static void asm_gc_sync(ASMState *as, SnapShot *snap, Reg base)
SnapEntry *map = &as->T->snapmap[snap->mapofs];
MSize n, nent = snap->nent;
for (n = 0; n < nent; n++) {
IRRef ref = snap_ref(map[n]);
if (!irref_isk(ref)) {
int32_t ofs = 8*(int32_t)(snap_slot(map[n])-1);
IRIns *ir = IR(ref);
if (ir->o == IR_FRAME) {
SnapEntry sn = map[n];
IRRef ref = snap_ref(sn);
/* NYI: sync the frame, bump base, set topslot, clear new slots. */
if ((sn & (SNAP_CONT|SNAP_FRAME)))
lj_trace_err(as->J, LJ_TRERR_NYIGCF);
} else if (irt_isgcv(ir->t)) {
if (!irref_isk(ref)) {
IRIns *ir = IR(ref);
if (irt_isgcv(ir->t)) {
int32_t ofs = 8*(int32_t)(snap_slot(sn)-1);
Reg src = ra_alloc1(as, ref, allow);
emit_movtomro(as, src, base, ofs);
emit_movmroi(as, base, ofs+4, irt_toitype(ir->t));
@ -2975,20 +2976,19 @@ static void asm_tail_sync(ASMState *as)
/* Must check all frames to find topslot (outer can be larger than inner). */
for (n = 0; n < nent; n++) {
IRRef ref = snap_ref(map[n]);
BCReg s = snap_slot(map[n]);
if (!irref_isk(ref)) {
IRIns *ir = IR(ref);
if (ir->o == IR_FRAME && irt_isfunc(ir->t)) {
SnapEntry sn = map[n];
if ((sn & SNAP_FRAME)) {
IRIns *ir = IR(snap_ref(sn));
GCfunc *fn = ir_kfunc(IR(ir->op2));
lua_assert(ir->o == IR_FRAME && irt_isfunc(ir->t));
if (isluafunc(fn)) {
BCReg s = snap_slot(sn);
BCReg fs = s + funcproto(fn)->framesize;
if (fs > topslot) topslot = fs;
newbase = s;
}
}
}
}
as->topslot = topslot; /* Used in asm_head_side(). */
if (as->T->link == TRACE_INTERP) {

View File

@ -422,18 +422,29 @@ enum {
#define irref_isk(ref) ((ref) < REF_BIAS)
/* Tagged IR references. */
/* Tagged IR references (32 bit).
**
** +-------+-------+---------------+
** | irt | flags | ref |
** +-------+-------+---------------+
**
** The tag holds a copy of the IRType and speeds up IR type checks.
*/
typedef uint32_t TRef;
#define TREF(ref, t) (cast(TRef, (ref) + ((t)<<16)))
#define TREF_REFMASK 0x0000ffff
#define TREF_FRAME 0x00010000
#define TREF_CONT 0x00020000
#define tref_ref(tr) (cast(IRRef1, (tr)))
#define tref_t(tr) (cast(IRType, (tr)>>16))
#define tref_type(tr) (cast(IRType, ((tr)>>16) & IRT_TYPE))
#define TREF(ref, t) ((TRef)((ref) + ((t)<<24)))
#define tref_ref(tr) ((IRRef1)(tr))
#define tref_t(tr) ((IRType)((tr)>>24))
#define tref_type(tr) ((IRType)(((tr)>>24) & IRT_TYPE))
#define tref_typerange(tr, first, last) \
((((tr)>>16) & IRT_TYPE) - (TRef)(first) <= (TRef)(last-first))
((((tr)>>24) & IRT_TYPE) - (TRef)(first) <= (TRef)(last-first))
#define tref_istype(tr, t) (((tr) & (IRT_TYPE<<16)) == ((t)<<16))
#define tref_istype(tr, t) (((tr) & (IRT_TYPE<<24)) == ((t)<<24))
#define tref_isnil(tr) (tref_istype((tr), IRT_NIL))
#define tref_isfalse(tr) (tref_istype((tr), IRT_FALSE))
#define tref_istrue(tr) (tref_istype((tr), IRT_TRUE))

View File

@ -123,9 +123,14 @@ typedef struct SnapShot {
/* Compressed snapshot entry. */
typedef uint32_t SnapEntry;
#define SNAP_FRAME 0x010000 /* Slot has frame link. */
#define SNAP_FRAME 0x010000 /* Frame slot. */
#define SNAP_CONT 0x020000 /* Continuation slot. */
LJ_STATIC_ASSERT(SNAP_FRAME == TREF_FRAME);
LJ_STATIC_ASSERT(SNAP_CONT == TREF_CONT);
#define SNAP(slot, flags, ref) ((SnapEntry)((slot) << 24) + (flags) + (ref))
#define SNAP(slot, flags, ref) (((SnapEntry)(slot) << 24) + (flags) + (ref))
#define SNAP_TR(slot, tr) \
(((SnapEntry)(slot) << 24) + ((tr) & (TREF_CONT|TREF_FRAME|TREF_REFMASK)))
#define SNAP_MKPC(pc) ((SnapEntry)u32ptr(pc))
#define SNAP_MKFTSZ(ftsz) ((SnapEntry)(ftsz))
#define snap_ref(sn) ((sn) & 0xffff)

View File

@ -424,7 +424,7 @@ static BCReg rec_mm_prep(jit_State *J, ASMFunction cont)
#else
trcont = lj_ir_kptr(J, (void *)cont);
#endif
J->base[top] = emitir(IRTG(IR_FRAME, IRT_PTR), trcont, trcont);
J->base[top] = emitir(IRTG(IR_FRAME, IRT_PTR), trcont, trcont) | TREF_CONT;
for (s = J->maxslot; s < top; s++)
J->base[s] = TREF_NIL;
return top+1;
@ -1608,7 +1608,7 @@ static int rec_call(jit_State *J, BCReg func, int cres, int nargs)
}
/* Specialize to the runtime value of the called function. */
res[0] = emitir(IRTG(IR_FRAME, IRT_FUNC), res[0], lj_ir_kfunc(J, rd.fn));
res[0] = emitir(IRTG(IR_FRAME, IRT_FUNC), res[0], lj_ir_kfunc(J, rd.fn)) | TREF_FRAME;
if (isluafunc(rd.fn)) { /* Record call to Lua function. */
GCproto *pt = funcproto(rd.fn);
@ -2164,8 +2164,9 @@ static void rec_setup_side(jit_State *J, Trace *T)
BloomFilter seen = 0;
/* Emit IR for slots inherited from parent snapshot. */
for (n = 0; n < nent; n++) {
IRRef ref = snap_ref(map[n]);
BCReg s = snap_slot(map[n]);
SnapEntry sn = map[n];
IRRef ref = snap_ref(sn);
BCReg s = snap_slot(sn);
IRIns *ir = &T->ir[ref];
TRef tr;
/* The bloom filter avoids O(nent^2) overhead for de-duping slots. */
@ -2196,10 +2197,10 @@ static void rec_setup_side(jit_State *J, Trace *T)
J->framedepth++;
}
tr = lj_ir_kfunc(J, ir_kfunc(&T->ir[ir->op2]));
tr = emitir_raw(IRT(IR_FRAME, IRT_FUNC), tr, tr);
tr = emitir_raw(IRT(IR_FRAME, IRT_FUNC), tr, tr) | TREF_FRAME;
} else {
tr = lj_ir_kptr(J, mref(T->ir[ir->op2].ptr, void));
tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr);
tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr) | TREF_CONT;
}
break;
case IR_SLOAD: /* Inherited SLOADs don't need a guard or type check. */

View File

@ -50,20 +50,19 @@ void lj_snap_grow_map_(jit_State *J, MSize need)
/* -- Snapshot generation ------------------------------------------------- */
/* NYI: IR_FRAME should be eliminated, too. */
/* Add all modified slots to the snapshot. */
static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots)
{
BCReg s;
MSize n = 0;
for (s = 0; s < nslots; s++) {
IRRef ref = tref_ref(J->slot[s]);
TRef tr = J->slot[s];
IRRef ref = tref_ref(tr);
if (ref) {
IRIns *ir = IR(ref);
if (!(ir->o == IR_SLOAD && ir->op1 == s &&
!(ir->op2 & IRSLOAD_INHERIT)))
map[n++] = SNAP(s, ir->o == IR_FRAME ? SNAP_FRAME : 0, ref);
map[n++] = SNAP_TR(s, tr);
}
}
return n;
@ -226,8 +225,9 @@ void lj_snap_restore(jit_State *J, void *exptr)
/* Fill stack slots with data from the registers and spill slots. */
frame = L->base-1;
for (n = 0; n < nent; n++) {
IRRef ref = snap_ref(map[n]);
BCReg s = snap_slot(map[n]);
SnapEntry sn = map[n];
IRRef ref = snap_ref(sn);
BCReg s = snap_slot(sn);
TValue *o = &frame[s]; /* Stack slots are relative to start frame. */
IRIns *ir = &T->ir[ref];
if (irref_isk(ref)) { /* Restore constant slot. */
@ -260,6 +260,7 @@ void lj_snap_restore(jit_State *J, void *exptr)
setitype(o, irt_toitype(t));
}
} else { /* Restore frame slot. */
lua_assert((sn & (SNAP_CONT|SNAP_FRAME)));
lua_assert(ir->o == IR_FRAME);
/* This works for both PTR and FUNC IR_FRAME. */
setgcrefp(o->fr.func, mref(T->ir[ir->op2].ptr, void));