Allocate the final GCtrace* prior to assembly.

This commit is contained in:
Peter Cawley 2016-05-10 01:07:16 +01:00
parent 5855f6540a
commit 5687444c59
4 changed files with 67 additions and 36 deletions

View File

@ -625,9 +625,8 @@ static void ra_addrename(ASMState *as, Reg down, IRRef ref, SnapNo snapno)
IRRef ren; IRRef ren;
lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), ref, snapno); lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), ref, snapno);
ren = tref_ref(lj_ir_emit(as->J)); ren = tref_ref(lj_ir_emit(as->J));
as->ir = as->T->ir; /* The IR may have been reallocated. */ as->J->cur.ir[ren].r = (uint8_t)down;
IR(ren)->r = (uint8_t)down; as->J->cur.ir[ren].s = SPS_NONE;
IR(ren)->s = SPS_NONE;
} }
/* Rename register allocation and emit move. */ /* Rename register allocation and emit move. */
@ -948,7 +947,7 @@ static void asm_snap_prep(ASMState *as)
} else { } else {
/* Process any renames above the highwater mark. */ /* Process any renames above the highwater mark. */
for (; as->snaprename < as->T->nins; as->snaprename++) { for (; as->snaprename < as->T->nins; as->snaprename++) {
IRIns *ir = IR(as->snaprename); IRIns *ir = as->T->ir + as->snaprename;
if (asm_snap_checkrename(as, ir->op1)) if (asm_snap_checkrename(as, ir->op1))
ir->op2 = REF_BIAS-1; /* Kill rename. */ ir->op2 = REF_BIAS-1; /* Kill rename. */
} }
@ -1965,12 +1964,8 @@ static void asm_setup_regsp(ASMState *as)
/* REF_BASE is used for implicit references to the BASE register. */ /* REF_BASE is used for implicit references to the BASE register. */
lastir->prev = REGSP_HINT(RID_BASE); lastir->prev = REGSP_HINT(RID_BASE);
ir = IR(nins-1);
if (ir->o == IR_RENAME) {
do { ir--; nins--; } while (ir->o == IR_RENAME);
T->nins = nins; /* Remove any renames left over from ASM restart. */
}
as->snaprename = nins; as->snaprename = nins;
as->snapref = nins; as->snapref = nins;
as->snapno = T->nsnap; as->snapno = T->nsnap;
@ -2202,13 +2197,14 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
MCode *origtop; MCode *origtop;
/* Ensure an initialized instruction beyond the last one for HIOP checks. */ /* Ensure an initialized instruction beyond the last one for HIOP checks. */
J->cur.nins = lj_ir_nextins(J); /* This also allows one RENAME to be added without reallocating curfinal. */
J->cur.ir[J->cur.nins].o = IR_NOP; as->orignins = lj_ir_nextins(J);
J->cur.ir[as->orignins].o = IR_NOP;
/* Setup initial state. Copy some fields to reduce indirections. */ /* Setup initial state. Copy some fields to reduce indirections. */
as->J = J; as->J = J;
as->T = T; as->T = T;
as->ir = T->ir; J->curfinal = lj_trace_alloc(J->L, T);
as->flags = J->flags; as->flags = J->flags;
as->loopref = J->loopref; as->loopref = J->loopref;
as->realign = NULL; as->realign = NULL;
@ -2221,12 +2217,14 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
as->mclim = as->mcbot + MCLIM_REDZONE; as->mclim = as->mcbot + MCLIM_REDZONE;
asm_setup_target(as); asm_setup_target(as);
do { for (;;) {
as->mcp = as->mctop; as->mcp = as->mctop;
#ifdef LUA_USE_ASSERT #ifdef LUA_USE_ASSERT
as->mcp_prev = as->mcp; as->mcp_prev = as->mcp;
#endif #endif
as->curins = T->nins; as->ir = J->curfinal->ir;
as->curins = J->cur.nins = as->orignins;
RA_DBG_START(); RA_DBG_START();
RA_DBGX((as, "===== STOP =====")); RA_DBGX((as, "===== STOP ====="));
@ -2254,22 +2252,38 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
checkmclim(as); checkmclim(as);
asm_ir(as, ir); asm_ir(as, ir);
} }
} while (as->realign); /* Retry in case the MCode needs to be realigned. */
/* Emit head of trace. */ if (as->realign && J->curfinal->nins >= T->nins)
RA_DBG_REF(); continue; /* Retry in case the MCode needs to be realigned. */
checkmclim(as);
if (as->gcsteps > 0) { /* Emit head of trace. */
as->curins = as->T->snap[0].ref; RA_DBG_REF();
asm_snap_prep(as); /* The GC check is a guard. */ checkmclim(as);
asm_gc_check(as); if (as->gcsteps > 0) {
as->curins = as->T->snap[0].ref;
asm_snap_prep(as); /* The GC check is a guard. */
asm_gc_check(as);
}
ra_evictk(as);
if (as->parent)
asm_head_side(as);
else
asm_head_root(as);
asm_phi_fixup(as);
/* Commit renames. */
if (J->curfinal->nins < T->nins) {
lj_trace_free(J2G(J), J->curfinal);
J->curfinal = NULL; /* In case lj_trace_alloc OOMs. */
J->curfinal = lj_trace_alloc(J->L, T);
} else {
lua_assert(J->curfinal->nk == T->nk);
memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins,
(T->nins - as->orignins) * sizeof(IRIns));
T->nins = J->curfinal->nins;
break;
}
} }
ra_evictk(as);
if (as->parent)
asm_head_side(as);
else
asm_head_root(as);
asm_phi_fixup(as);
RA_DBGX((as, "===== START ====")); RA_DBGX((as, "===== START ===="));
RA_DBG_FLUSH(); RA_DBG_FLUSH();

View File

@ -349,6 +349,7 @@ typedef struct FoldState {
/* JIT compiler state. */ /* JIT compiler state. */
typedef struct jit_State { typedef struct jit_State {
GCtrace cur; /* Current trace. */ GCtrace cur; /* Current trace. */
GCtrace *curfinal; /* Final address of current trace (set during asm). */
lua_State *L; /* Current Lua state. */ lua_State *L; /* Current Lua state. */
const BCIns *pc; /* Current PC. */ const BCIns *pc; /* Current PC. */

View File

@ -117,15 +117,26 @@ static void perftools_addtrace(GCtrace *T)
} }
#endif #endif
/* Allocate space for copy of trace. */ /* Allocate space for copy of T. */
static GCtrace *trace_save_alloc(jit_State *J) GCtrace* LJ_FASTCALL lj_trace_alloc(lua_State *L, GCtrace *T)
{ {
size_t sztr = ((sizeof(GCtrace)+7)&~7); size_t sztr = ((sizeof(GCtrace)+7)&~7);
size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); size_t szins = (T->nins-T->nk)*sizeof(IRIns);
size_t sz = sztr + szins + size_t sz = sztr + szins +
J->cur.nsnap*sizeof(SnapShot) + T->nsnap*sizeof(SnapShot) +
J->cur.nsnapmap*sizeof(SnapEntry); T->nsnapmap*sizeof(SnapEntry);
return lj_mem_newt(J->L, (MSize)sz, GCtrace); GCtrace *T2 = lj_mem_newt(L, (MSize)sz, GCtrace);
char *p = (char *)T2 + sztr;
T2->gct = ~LJ_TTRACE;
T2->marked = 0;
T2->traceno = 0;
T2->ir = (IRIns *)p - T->nk;
T2->nins = T->nins;
T2->nk = T->nk;
T2->nsnap = T->nsnap;
T2->nsnapmap = T->nsnapmap;
memcpy(p, T->ir + T->nk, szins);
return T2;
} }
/* Save current trace by copying and compacting it. */ /* Save current trace by copying and compacting it. */
@ -140,11 +151,11 @@ static void trace_save(jit_State *J, GCtrace *T)
newwhite(J2G(J), T); newwhite(J2G(J), T);
T->gct = ~LJ_TTRACE; T->gct = ~LJ_TTRACE;
T->ir = (IRIns *)p - J->cur.nk; T->ir = (IRIns *)p - J->cur.nk;
memcpy(p, J->cur.ir+J->cur.nk, szins);
p += szins; p += szins;
TRACE_APPENDVEC(snap, nsnap, SnapShot) TRACE_APPENDVEC(snap, nsnap, SnapShot)
TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
J->cur.traceno = 0; J->cur.traceno = 0;
J->curfinal = NULL;
setgcrefp(J->trace[T->traceno], T); setgcrefp(J->trace[T->traceno], T);
lj_gc_barriertrace(J2G(J), T->traceno); lj_gc_barriertrace(J2G(J), T->traceno);
lj_gdbjit_addtrace(J, T); lj_gdbjit_addtrace(J, T);
@ -439,7 +450,7 @@ static void trace_stop(jit_State *J)
BCOp op = bc_op(J->cur.startins); BCOp op = bc_op(J->cur.startins);
GCproto *pt = &gcref(J->cur.startpt)->pt; GCproto *pt = &gcref(J->cur.startpt)->pt;
TraceNo traceno = J->cur.traceno; TraceNo traceno = J->cur.traceno;
GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */ GCtrace *T = J->curfinal;
lua_State *L; lua_State *L;
switch (op) { switch (op) {
@ -527,6 +538,10 @@ static int trace_abort(jit_State *J)
J->postproc = LJ_POST_NONE; J->postproc = LJ_POST_NONE;
lj_mcode_abort(J); lj_mcode_abort(J);
if (J->curfinal) {
lj_trace_free(J2G(J), J->curfinal);
J->curfinal = NULL;
}
if (tvisnumber(L->top-1)) if (tvisnumber(L->top-1))
e = (TraceError)numberVint(L->top-1); e = (TraceError)numberVint(L->top-1);
if (e == LJ_TRERR_MCODELM) { if (e == LJ_TRERR_MCODELM) {

View File

@ -23,6 +23,7 @@ LJ_FUNC_NORET void lj_trace_err(jit_State *J, TraceError e);
LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e); LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e);
/* Trace management. */ /* Trace management. */
LJ_FUNC GCtrace* LJ_FASTCALL lj_trace_alloc(lua_State *L, GCtrace *T);
LJ_FUNC void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T); LJ_FUNC void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T);
LJ_FUNC void lj_trace_reenableproto(GCproto *pt); LJ_FUNC void lj_trace_reenableproto(GCproto *pt);
LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt); LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt);