Add trace stitching.
This commit is contained in:
@@ -360,7 +360,7 @@ static void trace_start(jit_State *J)
|
||||
TraceNo traceno;
|
||||
|
||||
if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
|
||||
if (J->parent == 0) {
|
||||
if (J->parent == 0 && J->exitno == 0) {
|
||||
/* Lazy bytecode patching to disable hotcount events. */
|
||||
lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
|
||||
bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF);
|
||||
@@ -453,6 +453,12 @@ static void trace_stop(jit_State *J)
|
||||
root->nextside = (TraceNo1)traceno;
|
||||
}
|
||||
break;
|
||||
case BC_CALLM:
|
||||
case BC_CALL:
|
||||
case BC_ITERC:
|
||||
/* Trace stitching: patch link of previous trace. */
|
||||
traceref(J, J->exitno)->link = traceno;
|
||||
break;
|
||||
default:
|
||||
lua_assert(0);
|
||||
break;
|
||||
@@ -502,8 +508,12 @@ static int trace_abort(jit_State *J)
|
||||
return 1; /* Retry ASM with new MCode area. */
|
||||
}
|
||||
/* Penalize or blacklist starting bytecode instruction. */
|
||||
if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins)))
|
||||
penalty_pc(J, &gcref(J->cur.startpt)->pt, mref(J->cur.startpc, BCIns), e);
|
||||
if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) {
|
||||
if (J->exitno == 0)
|
||||
penalty_pc(J, &gcref(J->cur.startpt)->pt, mref(J->cur.startpc, BCIns), e);
|
||||
else
|
||||
traceref(J, J->exitno)->link = J->exitno; /* Self-link is blacklisted. */
|
||||
}
|
||||
|
||||
/* Is there anything to abort? */
|
||||
traceno = J->cur.traceno;
|
||||
@@ -680,6 +690,20 @@ static void trace_hotside(jit_State *J, const BCIns *pc)
|
||||
}
|
||||
}
|
||||
|
||||
/* Stitch a new trace to the previous trace. */
|
||||
void LJ_FASTCALL lj_trace_stitch(jit_State *J, const BCIns *pc)
|
||||
{
|
||||
/* Only start a new trace if not recording or inside __gc call or vmevent. */
|
||||
if (J->state == LJ_TRACE_IDLE &&
|
||||
!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
|
||||
J->parent = 0; /* Have to treat it like a root trace. */
|
||||
/* J->exitno is set to the invoking trace. */
|
||||
J->state = LJ_TRACE_START;
|
||||
lj_trace_ins(J, pc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Tiny struct to pass data to protected call. */
|
||||
typedef struct ExitDataCP {
|
||||
jit_State *J;
|
||||
|
||||
Reference in New Issue
Block a user