From e3a442e6ec782fcf994023976d95635a368b7e8e Mon Sep 17 00:00:00 2001 From: Luke Gorrie Date: Mon, 17 Oct 2016 22:37:50 +0200 Subject: [PATCH] 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% --- src/lib_jit.c | 22 ++++++++++++++++++++++ src/lj_traceprofile.c | 22 +++++++++++++--------- src/lj_traceprofile.h | 9 +++++++++ src/luajit.h | 2 ++ 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/lib_jit.c b/src/lib_jit.c index 045ce11e..2d4b2af9 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c @@ -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); diff --git a/src/lj_traceprofile.c b/src/lj_traceprofile.c index 7ba0ef3b..dc998d95 100644 --- a/src/lj_traceprofile.c +++ b/src/lj_traceprofile.c @@ -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 diff --git a/src/lj_traceprofile.h b/src/lj_traceprofile.h index 152f7e32..38bfde78 100644 --- a/src/lj_traceprofile.h +++ b/src/lj_traceprofile.h @@ -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 */ diff --git a/src/luajit.h b/src/luajit.h index a1ba4b24..8974d0a9 100644 --- a/src/luajit.h +++ b/src/luajit.h @@ -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. */