Skip to content

Commit

Permalink
Merge pull request snabbco#186 from lukego/fix-jit-traces-alloc
Browse files Browse the repository at this point in the history
lj_trace.c: Fix and simplify allocation of J->trace
  • Loading branch information
lukego authored Aug 14, 2018
2 parents 5d235e6 + d09927b commit 52e2977
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 28 deletions.
6 changes: 4 additions & 2 deletions src/lj_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,11 @@ typedef struct GCtrace {
uint8_t unused1;
} GCtrace;

#define TRACE_MAX 65535

#define gco2trace(o) check_exp((o)->gch.gct == ~LJ_TTRACE, (GCtrace *)(o))
#define traceref(J, n) \
check_exp((n)>0 && (MSize)(n)<J->sizetrace, (GCtrace *)gcref(J->trace[(n)]))
check_exp((n)>0 && (MSize)(n)<TRACE_MAX, (GCtrace *)gcref(J->trace[(n)]))

LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCtrace, gclist));

Expand Down Expand Up @@ -359,7 +361,7 @@ typedef struct jit_State {

GCRef *trace; /* Array of traces. */
TraceNo freetrace; /* Start of scan for next free trace. */
MSize sizetrace; /* Size of trace array. */
uint16_t ntraces; /* Number of traces created since last flush. */
IRRef1 ktrace; /* Reference to KGC with GCtrace. */

IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */
Expand Down
6 changes: 4 additions & 2 deletions src/lj_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static void close_state(lua_State *L)
lj_mem_free(g, J->snapmapbuf, sizeof(SnapEntry)*65536);
lj_mem_free(g, J->snapbuf, sizeof(SnapShot)*65536);
lj_mem_free(g, J->irbuf, 65536*sizeof(IRIns));
lj_mem_free(g, J->trace, TRACE_MAX * sizeof(GCRef *));
#if 0
/* XXX Fix deallocation so that this assertion succeeds. */
lua_assert(g->gc.total == sizeof(GG_State));
Expand Down Expand Up @@ -224,9 +225,10 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
J->bclog = (BCRecLog *)lj_mem_new(L, sizeof(BCRecLog)*J->maxbclog);
J->nbclog = 0;
J->irbuf = (IRIns *)lj_mem_new(L, sizeof(IRIns)*65536);
if (J->irbuf == NULL || J->snapbuf == NULL ||
J->bclog == NULL || J->snapmapbuf == NULL)
J->trace = (GCRef *)lj_mem_new(L, TRACE_MAX * sizeof(GCRef *));
if (!(J->irbuf && J->snapbuf && J->bclog && J->snapmapbuf && J->trace))
return NULL;
memset(J->trace, 0, TRACE_MAX * sizeof(GCRef *));
lj_dispatch_init((GG_State *)L);
L->status = LUA_ERRERR+1; /* Avoid touching the stack upon memory error. */
if (lj_vm_cpcall(L, NULL, NULL, cpluaopen) != 0) {
Expand Down
43 changes: 19 additions & 24 deletions src/lj_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,14 @@ void lj_trace_err_info(jit_State *J, TraceError e)
/* Find a free trace number. */
static TraceNo trace_findfree(jit_State *J)
{
MSize osz, lim;
if (J->freetrace == 0)
J->freetrace = 1;
for (; J->freetrace < J->sizetrace; J->freetrace++)
/* Search for a free slot. */
for (; J->freetrace < TRACE_MAX; J->freetrace++)
if (traceref(J, J->freetrace) == NULL)
return J->freetrace++;
/* Need to grow trace array. */
lim = (MSize)J->param[JIT_P_maxtrace] + 1;
if (lim < 2) lim = 2; else if (lim > 65535) lim = 65535;
osz = J->sizetrace;
if (osz >= lim)
return 0; /* Too many traces. */
lj_mem_growvec(J->L, J->trace, J->sizetrace, lim, GCRef);
for (; osz < J->sizetrace; osz++)
setgcrefnull(J->trace[osz]);
return J->freetrace;
/* No free slot in trace array. */
return 0;
}

#define TRACE_APPENDVEC(field, szfield, tp) \
Expand Down Expand Up @@ -223,7 +215,7 @@ static void trace_flushroot(jit_State *J, GCtrace *T)
/* Flush a trace. Only root traces are considered. */
void lj_trace_flush(jit_State *J, TraceNo traceno)
{
if (traceno > 0 && traceno < J->sizetrace) {
if (traceno > 0 && traceno < TRACE_MAX) {
GCtrace *T = traceref(J, traceno);
if (T && T->root == 0)
trace_flushroot(J, T);
Expand All @@ -246,17 +238,20 @@ int lj_trace_flushall(lua_State *L)
if ((J2G(J)->hookmask & HOOK_GC))
return 1;
lj_auditlog_trace_flushall(J);
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
GCtrace *T = traceref(J, i);
if (T) {
if (T->root == 0)
trace_flushroot(J, T);
lj_gdbjit_deltrace(J, T);
T->traceno = T->link = 0; /* Blacklist the link for cont_stitch. */
setgcrefnull(J->trace[i]);
if (J->trace) {
for (i = (ptrdiff_t)TRACE_MAX-1; i > 0; i--) {
GCtrace *T = traceref(J, i);
if (T) {
if (T->root == 0)
trace_flushroot(J, T);
lj_gdbjit_deltrace(J, T);
T->traceno = T->link = 0; /* Blacklist the link for cont_stitch. */
setgcrefnull(J->trace[i]);
}
}
}
J->cur.traceno = 0;
J->ntraces = 0;
J->freetrace = 0;
g->lasttrace = 0;
/* Unpatch blacklisted byte codes. */
Expand Down Expand Up @@ -306,12 +301,11 @@ void lj_trace_freestate(global_State *g)
#ifdef LUA_USE_ASSERT
{ /* This assumes all traces have already been freed. */
ptrdiff_t i;
for (i = 1; i < (ptrdiff_t)J->sizetrace; i++)
for (i = 1; i < (ptrdiff_t)TRACE_MAX-1; i++)
lua_assert(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL);
}
#endif
lj_mcode_free(J);
lj_mem_freevec(g, J->trace, J->sizetrace, GCRef);
}

/* -- Penalties and blacklisting ------------------------------------------ */
Expand Down Expand Up @@ -381,7 +375,7 @@ static void trace_start(jit_State *J)

/* Get a new trace number. */
traceno = trace_findfree(J);
if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */
if (traceno == 0 || J->ntraces >= J->param[JIT_P_maxtrace]) { /* No free trace? */
lua_assert((J2G(J)->hookmask & HOOK_GC) == 0);
lj_trace_flushall(J->L);
J->state = LJ_TRACE_IDLE; /* Silently ignored. */
Expand Down Expand Up @@ -469,6 +463,7 @@ static void trace_stop(jit_State *J)
lj_mcode_commit(J, J->cur.mcode);
J->postproc = LJ_POST_NONE;
trace_save(J, T);
J->ntraces++;

/* Clear any penalty after successful recording. */
for (i = 0; i < PENALTY_SLOTS; i++)
Expand Down

0 comments on commit 52e2977

Please sign in to comment.