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:
Luke Gorrie 2016-10-17 22:37:50 +02:00
parent 606d270826
commit e3a442e6ec
4 changed files with 46 additions and 9 deletions

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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. */