mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Reorganize trace linking and track link types.
This commit is contained in:
parent
3dbae4ffc2
commit
deeb8196c4
14
lib/dump.lua
14
lib/dump.lua
@ -504,13 +504,15 @@ local function dump_trace(what, tr, func, pc, otr, oex)
|
|||||||
if what == "abort" then
|
if what == "abort" then
|
||||||
out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
|
out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
|
||||||
else
|
else
|
||||||
local link = traceinfo(tr).link
|
local info = traceinfo(tr)
|
||||||
if link == tr then
|
local link, ltype = info.link, info.linktype
|
||||||
link = "loop"
|
if link == tr or link == 0 then
|
||||||
elseif link == 0 then
|
out:write(" -> ", ltype, "\n")
|
||||||
link = "interpreter"
|
elseif ltype == "root" then
|
||||||
end
|
|
||||||
out:write(" -> ", link, "\n")
|
out:write(" -> ", link, "\n")
|
||||||
|
else
|
||||||
|
out:write(" -> ", link, " ", ltype, "\n")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
|
if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
|
||||||
else
|
else
|
||||||
|
17
lib/v.lua
17
lib/v.lua
@ -22,7 +22,7 @@
|
|||||||
--
|
--
|
||||||
-- The output from the first example should look like this:
|
-- The output from the first example should look like this:
|
||||||
--
|
--
|
||||||
-- [TRACE 1 (command line):1]
|
-- [TRACE 1 (command line):1 loop]
|
||||||
-- [TRACE 2 (1/3) (command line):1 -> 1]
|
-- [TRACE 2 (1/3) (command line):1 -> 1]
|
||||||
--
|
--
|
||||||
-- The first number in each line is the internal trace number. Next are
|
-- The first number in each line is the internal trace number. Next are
|
||||||
@ -111,15 +111,20 @@ local function dump_trace(what, tr, func, pc, otr, oex)
|
|||||||
startex, startloc, fmterr(otr, oex)))
|
startex, startloc, fmterr(otr, oex)))
|
||||||
end
|
end
|
||||||
elseif what == "stop" then
|
elseif what == "stop" then
|
||||||
local link = traceinfo(tr).link
|
local info = traceinfo(tr)
|
||||||
if link == 0 then
|
local link, ltype = info.link, info.linktype
|
||||||
|
if ltype == "interpreter" then
|
||||||
out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
|
out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
|
||||||
tr, startex, startloc))
|
tr, startex, startloc))
|
||||||
elseif link == tr then
|
elseif link == tr or link == 0 then
|
||||||
out:write(format("[TRACE %3s %s%s]\n", tr, startex, startloc))
|
out:write(format("[TRACE %3s %s%s %s]\n",
|
||||||
else
|
tr, startex, startloc, ltype))
|
||||||
|
elseif ltype == "root" then
|
||||||
out:write(format("[TRACE %3s %s%s -> %d]\n",
|
out:write(format("[TRACE %3s %s%s -> %d]\n",
|
||||||
tr, startex, startloc, link))
|
tr, startex, startloc, link))
|
||||||
|
else
|
||||||
|
out:write(format("[TRACE %3s %s%s -> %d %s]\n",
|
||||||
|
tr, startex, startloc, link, ltype))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
out:write(format("[TRACE %s]\n", what))
|
out:write(format("[TRACE %s]\n", what))
|
||||||
|
@ -276,18 +276,26 @@ static GCtrace *jit_checktrace(lua_State *L)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Names of link types. ORDER LJ_TRLINK */
|
||||||
|
static const char *const jit_trlinkname[] = {
|
||||||
|
"none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
|
||||||
|
"interpreter", "return"
|
||||||
|
};
|
||||||
|
|
||||||
/* local info = jit.util.traceinfo(tr) */
|
/* local info = jit.util.traceinfo(tr) */
|
||||||
LJLIB_CF(jit_util_traceinfo)
|
LJLIB_CF(jit_util_traceinfo)
|
||||||
{
|
{
|
||||||
GCtrace *T = jit_checktrace(L);
|
GCtrace *T = jit_checktrace(L);
|
||||||
if (T) {
|
if (T) {
|
||||||
GCtab *t;
|
GCtab *t;
|
||||||
lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */
|
lua_createtable(L, 0, 8); /* Increment hash size if fields are added. */
|
||||||
t = tabV(L->top-1);
|
t = tabV(L->top-1);
|
||||||
setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1);
|
setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1);
|
||||||
setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk);
|
setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk);
|
||||||
setintfield(L, t, "link", T->link);
|
setintfield(L, t, "link", T->link);
|
||||||
setintfield(L, t, "nexit", T->nsnap);
|
setintfield(L, t, "nexit", T->nsnap);
|
||||||
|
setstrV(L, L->top++, lj_str_newz(L, jit_trlinkname[T->linktype]));
|
||||||
|
lua_setfield(L, -2, "linktype");
|
||||||
/* There are many more fields. Add them only when needed. */
|
/* There are many more fields. Add them only when needed. */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1305,7 +1305,7 @@ static void asm_tail_link(ASMState *as)
|
|||||||
checkmclim(as);
|
checkmclim(as);
|
||||||
ra_allocref(as, REF_BASE, RID2RSET(RID_BASE));
|
ra_allocref(as, REF_BASE, RID2RSET(RID_BASE));
|
||||||
|
|
||||||
if (as->T->link == TRACE_INTERP) {
|
if (as->T->link == 0) {
|
||||||
/* Setup fixed registers for exit to interpreter. */
|
/* Setup fixed registers for exit to interpreter. */
|
||||||
const BCIns *pc = snap_pc(as->T->snapmap[snap->mapofs + snap->nent]);
|
const BCIns *pc = snap_pc(as->T->snapmap[snap->mapofs + snap->nent]);
|
||||||
int32_t mres;
|
int32_t mres;
|
||||||
|
@ -1681,8 +1681,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
|
|||||||
p[-2] = (ARMI_ADD^k) | ARMF_D(RID_SP) | ARMF_N(RID_SP);
|
p[-2] = (ARMI_ADD^k) | ARMF_D(RID_SP) | ARMF_N(RID_SP);
|
||||||
}
|
}
|
||||||
/* Patch exit branch. */
|
/* Patch exit branch. */
|
||||||
target = lnk == TRACE_INTERP ? (MCode *)lj_vm_exit_interp :
|
target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
|
||||||
traceref(as->J, lnk)->mcode;
|
|
||||||
p[-1] = ARMI_B|(((target-p)-1)&0x00ffffffu);
|
p[-1] = ARMI_B|(((target-p)-1)&0x00ffffffu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2418,8 +2418,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Patch exit branch. */
|
/* Patch exit branch. */
|
||||||
target = lnk == TRACE_INTERP ? (MCode *)lj_vm_exit_interp :
|
target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
|
||||||
traceref(as->J, lnk)->mcode;
|
|
||||||
*(int32_t *)(p-4) = jmprel(p, target);
|
*(int32_t *)(p-4) = jmprel(p, target);
|
||||||
p[-5] = XI_JMP;
|
p[-5] = XI_JMP;
|
||||||
/* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */
|
/* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */
|
||||||
|
14
src/lj_jit.h
14
src/lj_jit.h
@ -174,13 +174,23 @@ typedef uint32_t ExitNo;
|
|||||||
typedef uint32_t TraceNo; /* Used to pass around trace numbers. */
|
typedef uint32_t TraceNo; /* Used to pass around trace numbers. */
|
||||||
typedef uint16_t TraceNo1; /* Stored trace number. */
|
typedef uint16_t TraceNo1; /* Stored trace number. */
|
||||||
|
|
||||||
#define TRACE_INTERP 0 /* Fallback to interpreter. */
|
/* Type of link. ORDER LJ_TRLINK */
|
||||||
|
typedef enum {
|
||||||
|
LJ_TRLINK_NONE, /* Incomplete trace. No link, yet. */
|
||||||
|
LJ_TRLINK_ROOT, /* Link to other root trace. */
|
||||||
|
LJ_TRLINK_LOOP, /* Loop to same trace. */
|
||||||
|
LJ_TRLINK_TAILREC, /* Tail-recursion. */
|
||||||
|
LJ_TRLINK_UPREC, /* Up-recursion. */
|
||||||
|
LJ_TRLINK_DOWNREC, /* Down-recursion. */
|
||||||
|
LJ_TRLINK_INTERP, /* Fallback to interpreter. */
|
||||||
|
LJ_TRLINK_RETURN /* Return to interpreter. */
|
||||||
|
} TraceLink;
|
||||||
|
|
||||||
/* Trace object. */
|
/* Trace object. */
|
||||||
typedef struct GCtrace {
|
typedef struct GCtrace {
|
||||||
GCHeader;
|
GCHeader;
|
||||||
uint8_t topslot; /* Top stack slot already checked to be allocated. */
|
uint8_t topslot; /* Top stack slot already checked to be allocated. */
|
||||||
uint8_t unused1;
|
uint8_t linktype; /* Type of link. */
|
||||||
IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */
|
IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */
|
||||||
GCRef gclist;
|
GCRef gclist;
|
||||||
IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */
|
IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */
|
||||||
|
@ -212,9 +212,10 @@ static void canonicalize_slots(jit_State *J)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Stop recording. */
|
/* Stop recording. */
|
||||||
static void rec_stop(jit_State *J, TraceNo lnk)
|
static void rec_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
|
||||||
{
|
{
|
||||||
lj_trace_end(J);
|
lj_trace_end(J);
|
||||||
|
J->cur.linktype = (uint8_t)linktype;
|
||||||
J->cur.link = (uint16_t)lnk;
|
J->cur.link = (uint16_t)lnk;
|
||||||
/* Looping back at the same stack level? */
|
/* Looping back at the same stack level? */
|
||||||
if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
|
if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
|
||||||
@ -522,7 +523,7 @@ static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev)
|
|||||||
/* Same loop? */
|
/* Same loop? */
|
||||||
if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */
|
if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */
|
||||||
lj_trace_err(J, LJ_TRERR_LLEAVE);
|
lj_trace_err(J, LJ_TRERR_LLEAVE);
|
||||||
rec_stop(J, J->cur.traceno); /* Root trace forms a loop. */
|
rec_stop(J, LJ_TRLINK_LOOP, J->cur.traceno); /* Looping root trace. */
|
||||||
} else if (ev != LOOPEV_LEAVE) { /* Entering inner loop? */
|
} else if (ev != LOOPEV_LEAVE) { /* Entering inner loop? */
|
||||||
/* It's usually better to abort here and wait until the inner loop
|
/* It's usually better to abort here and wait until the inner loop
|
||||||
** is traced. But if the inner loop repeatedly didn't loop back,
|
** is traced. But if the inner loop repeatedly didn't loop back,
|
||||||
@ -553,8 +554,9 @@ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
|
|||||||
} else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */
|
} else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */
|
||||||
J->instunroll = 0; /* Cannot continue across a compiled loop op. */
|
J->instunroll = 0; /* Cannot continue across a compiled loop op. */
|
||||||
if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
|
if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
|
||||||
lnk = J->cur.traceno; /* Can form an extra loop. */
|
rec_stop(J, LJ_TRLINK_LOOP, J->cur.traceno); /* Form an extra loop. */
|
||||||
rec_stop(J, lnk); /* Link to the loop. */
|
else
|
||||||
|
rec_stop(J, LJ_TRLINK_ROOT, lnk); /* Link to the loop. */
|
||||||
} /* Side trace continues across a loop that's left or not entered. */
|
} /* Side trace continues across a loop that's left or not entered. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,7 +680,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
|
|||||||
if (check_downrec_unroll(J, pt)) {
|
if (check_downrec_unroll(J, pt)) {
|
||||||
J->maxslot = (BCReg)(rbase + gotresults);
|
J->maxslot = (BCReg)(rbase + gotresults);
|
||||||
lj_snap_purge(J);
|
lj_snap_purge(J);
|
||||||
rec_stop(J, J->cur.traceno); /* Down-recursion. */
|
rec_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno); /* Down-recursion. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lj_snap_add(J);
|
lj_snap_add(J);
|
||||||
@ -1292,7 +1294,10 @@ static void check_call_unroll(jit_State *J)
|
|||||||
if (J->pc == J->startpc) {
|
if (J->pc == J->startpc) {
|
||||||
if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
|
if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
|
||||||
J->pc++;
|
J->pc++;
|
||||||
rec_stop(J, J->cur.traceno); /* Up-recursion or tail-recursion. */
|
if (J->framedepth + J->retdepth == 0)
|
||||||
|
rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Tail-recursion. */
|
||||||
|
else
|
||||||
|
rec_stop(J, LJ_TRLINK_UPREC, J->cur.traceno); /* Up-recursion. */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (count > J->param[JIT_P_callunroll])
|
if (count > J->param[JIT_P_callunroll])
|
||||||
@ -1350,8 +1355,9 @@ static void rec_func_jit(jit_State *J, TraceNo lnk)
|
|||||||
rec_func_setup(J);
|
rec_func_setup(J);
|
||||||
J->instunroll = 0; /* Cannot continue across a compiled function. */
|
J->instunroll = 0; /* Cannot continue across a compiled function. */
|
||||||
if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
|
if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
|
||||||
lnk = J->cur.traceno; /* Can form an extra tail-recursive loop. */
|
rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Extra tail-recursion. */
|
||||||
rec_stop(J, lnk); /* Link to the function. */
|
else
|
||||||
|
rec_stop(J, LJ_TRLINK_ROOT, lnk); /* Link to the function. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Vararg handling ----------------------------------------------------- */
|
/* -- Vararg handling ----------------------------------------------------- */
|
||||||
@ -1863,7 +1869,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
case BC_JFORI:
|
case BC_JFORI:
|
||||||
lua_assert(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL);
|
lua_assert(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL);
|
||||||
if (rec_for(J, pc, 0) != LOOPEV_LEAVE) /* Link to existing loop. */
|
if (rec_for(J, pc, 0) != LOOPEV_LEAVE) /* Link to existing loop. */
|
||||||
rec_stop(J, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
|
rec_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
|
||||||
/* Continue tracing if the loop is not entered. */
|
/* Continue tracing if the loop is not entered. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2121,8 +2127,9 @@ void lj_record_setup(jit_State *J)
|
|||||||
sidecheck:
|
sidecheck:
|
||||||
if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] ||
|
if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] ||
|
||||||
T->snap[J->exitno].count >= J->param[JIT_P_hotexit] +
|
T->snap[J->exitno].count >= J->param[JIT_P_hotexit] +
|
||||||
J->param[JIT_P_tryside])
|
J->param[JIT_P_tryside]) {
|
||||||
rec_stop(J, TRACE_INTERP);
|
rec_stop(J, LJ_TRLINK_INTERP, 0);
|
||||||
|
}
|
||||||
} else { /* Root trace. */
|
} else { /* Root trace. */
|
||||||
J->cur.root = 0;
|
J->cur.root = 0;
|
||||||
J->cur.startins = *J->pc;
|
J->cur.startins = *J->pc;
|
||||||
|
@ -509,6 +509,7 @@ static int trace_abort(jit_State *J)
|
|||||||
if (traceno) {
|
if (traceno) {
|
||||||
ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
|
ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
|
||||||
J->cur.link = 0;
|
J->cur.link = 0;
|
||||||
|
J->cur.linktype = LJ_TRLINK_NONE;
|
||||||
lj_vmevent_send(L, TRACE,
|
lj_vmevent_send(L, TRACE,
|
||||||
TValue *frame;
|
TValue *frame;
|
||||||
const BCIns *pc;
|
const BCIns *pc;
|
||||||
@ -590,6 +591,7 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
|
|||||||
lj_opt_dce(J);
|
lj_opt_dce(J);
|
||||||
if (lj_opt_loop(J)) { /* Loop optimization failed? */
|
if (lj_opt_loop(J)) { /* Loop optimization failed? */
|
||||||
J->cur.link = 0;
|
J->cur.link = 0;
|
||||||
|
J->cur.linktype = LJ_TRLINK_NONE;
|
||||||
J->loopref = J->cur.nins;
|
J->loopref = J->cur.nins;
|
||||||
J->state = LJ_TRACE_RECORD; /* Try to continue recording. */
|
J->state = LJ_TRACE_RECORD; /* Try to continue recording. */
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user