Inline-Lua
view release on metacpan or search on metacpan
ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/lj_record.c view on Meta::CPAN
static int rec_profile_need(jit_State *J, GCproto *pt, const BCIns *pc)
{
GCproto *ppt;
lj_assertJ(J->prof_mode == 'f' || J->prof_mode == 'l',
"bad profiler mode %c", J->prof_mode);
if (!pt)
return 0;
ppt = J->prev_pt;
J->prev_pt = pt;
if (pt != ppt && ppt) {
J->prev_line = -1;
return 1;
}
if (J->prof_mode == 'l') {
BCLine line = lj_debug_line(pt, proto_bcpos(pt, pc));
BCLine pline = J->prev_line;
J->prev_line = line;
if (pline != line)
return 1;
}
return 0;
}
static void rec_profile_ins(jit_State *J, const BCIns *pc)
{
if (J->prof_mode && rec_profile_need(J, J->pt, pc)) {
emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
lj_snap_add(J);
}
}
static void rec_profile_ret(jit_State *J)
{
if (J->prof_mode == 'f') {
emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
J->prev_pt = NULL;
lj_snap_add(J);
}
}
#endif
/* -- Record calls and returns -------------------------------------------- */
/* Specialize to the runtime value of the called function or its prototype. */
static TRef rec_call_specialize(jit_State *J, GCfunc *fn, TRef tr)
{
TRef kfunc;
if (isluafunc(fn)) {
GCproto *pt = funcproto(fn);
/* Too many closures created? Probably not a monomorphic function. */
if (pt->flags >= PROTO_CLC_POLY) { /* Specialize to prototype instead. */
TRef trpt = emitir(IRT(IR_FLOAD, IRT_PGC), tr, IRFL_FUNC_PC);
emitir(IRTG(IR_EQ, IRT_PGC), trpt, lj_ir_kptr(J, proto_bc(pt)));
(void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); /* Prevent GC of proto. */
return tr;
}
} else {
/* Don't specialize to non-monomorphic builtins. */
switch (fn->c.ffid) {
case FF_coroutine_wrap_aux:
case FF_string_gmatch_aux:
/* NYI: io_file_iter doesn't have an ffid, yet. */
{ /* Specialize to the ffid. */
TRef trid = emitir(IRT(IR_FLOAD, IRT_U8), tr, IRFL_FUNC_FFID);
emitir(IRTGI(IR_EQ), trid, lj_ir_kint(J, fn->c.ffid));
}
return tr;
default:
/* NYI: don't specialize to non-monomorphic C functions. */
break;
}
}
/* Otherwise specialize to the function (closure) value itself. */
kfunc = lj_ir_kfunc(J, fn);
emitir(IRTG(IR_EQ, IRT_FUNC), tr, kfunc);
return kfunc;
}
/* Record call setup. */
static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
{
RecordIndex ix;
TValue *functv = &J->L->base[func];
TRef kfunc, *fbase = &J->base[func];
ptrdiff_t i;
(void)getslot(J, func); /* Ensure func has a reference. */
for (i = 1; i <= nargs; i++)
(void)getslot(J, func+LJ_FR2+i); /* Ensure all args have a reference. */
if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */
ix.tab = fbase[0];
copyTV(J->L, &ix.tabv, functv);
if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
lj_trace_err(J, LJ_TRERR_NOMM);
for (i = ++nargs; i > LJ_FR2; i--) /* Shift arguments up. */
fbase[i+LJ_FR2] = fbase[i+LJ_FR2-1];
#if LJ_FR2
fbase[2] = fbase[0];
#endif
fbase[0] = ix.mobj; /* Replace function. */
functv = &ix.mobjv;
}
kfunc = rec_call_specialize(J, funcV(functv), fbase[0]);
#if LJ_FR2
fbase[0] = kfunc;
fbase[1] = TREF_FRAME;
#else
fbase[0] = kfunc | TREF_FRAME;
#endif
J->maxslot = (BCReg)nargs;
}
/* Record call. */
void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs)
{
rec_call_setup(J, func, nargs);
/* Bump frame. */
J->framedepth++;
J->base += func+1+LJ_FR2;
J->baseslot += func+1+LJ_FR2;
if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
( run in 1.461 second using v1.01-cache-2.11-cpan-0d23b851a93 )