mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
LJ_TRACEPROFILE: Added jit.traceprofile.vmstats()
This function returns counters for total events tallied in each VM state. Events during traces are aggregated into separate buckets for non-loop code, loop code, and other code (FFI calls). Can be used to print summaries like this: Interp C (LJ) GC Exit Record Opt ASM Nonloop Loop FFI 0.000% 0.150% 0.000% 0.000% 0.000% 0.000% 0.000% 23.802% 27.246% 48.802%
This commit is contained in:
parent
606d270826
commit
e3a442e6ec
@ -33,6 +33,7 @@
|
||||
#include "lj_vm.h"
|
||||
#include "lj_vmevent.h"
|
||||
#include "lj_lib.h"
|
||||
#include "lj_def.h"
|
||||
|
||||
#include "luajit.h"
|
||||
|
||||
@ -650,6 +651,27 @@ LJLIB_CF(jit_traceprofile_tracestats)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LJLIB_CF(jit_traceprofile_vmstats)
|
||||
{
|
||||
uint64_t *vmstats = luaJIT_traceprofile_vmstats(L);
|
||||
if (vmstats == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
setint64V(L->top++, vmstats[LJ_VMST_INTERP]);
|
||||
setint64V(L->top++, vmstats[LJ_VMST_C]);
|
||||
setint64V(L->top++, vmstats[LJ_VMST_GC]);
|
||||
setint64V(L->top++, vmstats[LJ_VMST_EXIT]);
|
||||
setint64V(L->top++, vmstats[LJ_VMST_RECORD]);
|
||||
setint64V(L->top++, vmstats[LJ_VMST_OPT]);
|
||||
setint64V(L->top++, vmstats[LJ_VMST_ASM]);
|
||||
setint64V(L->top++, vmstats[LJ_TRACEPROF_VMST_TRACE_NONLOOP]);
|
||||
setint64V(L->top++, vmstats[LJ_TRACEPROF_VMST_TRACE_LOOP]);
|
||||
setint64V(L->top++, vmstats[LJ_TRACEPROF_VMST_TRACE_OTHER]);
|
||||
setint64V(L->top++, vmstats[LJ_TRACEPROF_VMST_TOTAL]);
|
||||
return 11;
|
||||
}
|
||||
}
|
||||
|
||||
LJLIB_CF(jit_traceprofile_start)
|
||||
{
|
||||
int interval = lj_lib_checkint(L, 1);
|
||||
|
@ -23,16 +23,9 @@
|
||||
#include "lj_trace.h"
|
||||
#include "lj_traceprofile.h"
|
||||
|
||||
/* vmstate extended to represent running in a trace (any one) */
|
||||
enum {
|
||||
LJ_TRACEPROF_VMST_TRACE = LJ_VMST__MAX,
|
||||
LJ_TRACEPROF_VMST__MAX
|
||||
};
|
||||
|
||||
typedef struct TraceProfileState {
|
||||
global_State *g; /* VM state that started the profiler. */
|
||||
struct sigaction oldsa;
|
||||
int events; /* Number of events (signals) handled. */
|
||||
uint64_t vmstate[LJ_TRACEPROF_VMST__MAX]; /* Counter per VM state */
|
||||
} TraceProfileState;
|
||||
|
||||
@ -43,7 +36,7 @@ static void traceprofile_signal(int sig, siginfo_t *si, void *data)
|
||||
global_State *g = state.g;
|
||||
intptr_t ip = (intptr_t)((ucontext_t*)data)->uc_mcontext.gregs[REG_RIP];
|
||||
int st = g->vmstate;
|
||||
state.events++;
|
||||
state.vmstate[LJ_TRACEPROF_VMST_TOTAL]++;
|
||||
assert((st >= 0) || (~st < LJ_VMST__MAX));
|
||||
if (st >= 0) {
|
||||
lua_State *L = gco2th(gcref(g->cur_L));
|
||||
@ -54,13 +47,15 @@ static void traceprofile_signal(int sig, siginfo_t *si, void *data)
|
||||
if ((rel_ip >= 0) && (rel_ip < T->szmcode)) {
|
||||
if (rel_ip < T->mcloop) {
|
||||
T->prof.nonloop++; /* Sample is in non-loop mcode. */
|
||||
state.vmstate[LJ_TRACEPROF_VMST_TRACE_NONLOOP]++;
|
||||
} else {
|
||||
T->prof.loop++; /* Sample is in loop mcode. */
|
||||
state.vmstate[LJ_TRACEPROF_VMST_TRACE_LOOP]++;
|
||||
}
|
||||
} else {
|
||||
T->prof.other++; /* Sample is outside the trace mcode. */
|
||||
state.vmstate[LJ_TRACEPROF_VMST_TRACE_OTHER]++;
|
||||
}
|
||||
state.vmstate[LJ_TRACEPROF_VMST_TRACE]++;
|
||||
} else {
|
||||
state.vmstate[~st]++;
|
||||
}
|
||||
@ -100,5 +95,14 @@ LUA_API void luaJIT_traceprofile_stop(lua_State *L)
|
||||
traceprofile_stop_timer();
|
||||
}
|
||||
|
||||
LUA_API uint64_t *luaJIT_traceprofile_vmstats(lua_State *L)
|
||||
{
|
||||
if (state.g && L == gco2th(gcref(state.g->cur_L))) {
|
||||
return state.vmstate;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -6,6 +6,15 @@
|
||||
#ifndef _LJ_TRACEPROFILE_H
|
||||
#define _LJ_TRACEPROFILE_H
|
||||
|
||||
/* vmstate extended to represent running in a trace (any one) */
|
||||
typedef enum {
|
||||
LJ_TRACEPROF_VMST_TRACE_NONLOOP = LJ_VMST__MAX,
|
||||
LJ_TRACEPROF_VMST_TRACE_LOOP,
|
||||
LJ_TRACEPROF_VMST_TRACE_OTHER,
|
||||
LJ_TRACEPROF_VMST_TOTAL,
|
||||
LJ_TRACEPROF_VMST__MAX
|
||||
} TraceProfileVMState;
|
||||
|
||||
typedef struct TraceProfile {
|
||||
uint64_t nonloop; /* Samples taken in non-loop mcode */
|
||||
uint64_t loop; /* Samples taken in loop mcode */
|
||||
|
@ -29,6 +29,7 @@
|
||||
#define _LUAJIT_H
|
||||
|
||||
#include "lua.h"
|
||||
#include "lj_def.h"
|
||||
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.0-beta2"
|
||||
#define LUAJIT_VERSION_NUM 20100 /* Version 2.1.0 = 02.01.00. */
|
||||
@ -76,6 +77,7 @@ LUA_API const char *luaJIT_profile_dumpstack(lua_State *L, const char *fmt,
|
||||
/* Trace profiling API. */
|
||||
LUA_API void luaJIT_traceprofile_start(lua_State *L, int interval);
|
||||
LUA_API void luaJIT_traceprofile_stop(lua_State *L);
|
||||
LUA_API uint64_t *luaJIT_traceprofile_vmstats(lua_State *L);
|
||||
|
||||
|
||||
/* Enforce (dynamic) linker error for version mismatches. Call from main. */
|
||||
|
Loading…
Reference in New Issue
Block a user