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_vm.h"
|
||||||
#include "lj_vmevent.h"
|
#include "lj_vmevent.h"
|
||||||
#include "lj_lib.h"
|
#include "lj_lib.h"
|
||||||
|
#include "lj_def.h"
|
||||||
|
|
||||||
#include "luajit.h"
|
#include "luajit.h"
|
||||||
|
|
||||||
@ -650,6 +651,27 @@ LJLIB_CF(jit_traceprofile_tracestats)
|
|||||||
return 0;
|
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)
|
LJLIB_CF(jit_traceprofile_start)
|
||||||
{
|
{
|
||||||
int interval = lj_lib_checkint(L, 1);
|
int interval = lj_lib_checkint(L, 1);
|
||||||
|
@ -23,16 +23,9 @@
|
|||||||
#include "lj_trace.h"
|
#include "lj_trace.h"
|
||||||
#include "lj_traceprofile.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 {
|
typedef struct TraceProfileState {
|
||||||
global_State *g; /* VM state that started the profiler. */
|
global_State *g; /* VM state that started the profiler. */
|
||||||
struct sigaction oldsa;
|
struct sigaction oldsa;
|
||||||
int events; /* Number of events (signals) handled. */
|
|
||||||
uint64_t vmstate[LJ_TRACEPROF_VMST__MAX]; /* Counter per VM state */
|
uint64_t vmstate[LJ_TRACEPROF_VMST__MAX]; /* Counter per VM state */
|
||||||
} TraceProfileState;
|
} TraceProfileState;
|
||||||
|
|
||||||
@ -43,7 +36,7 @@ static void traceprofile_signal(int sig, siginfo_t *si, void *data)
|
|||||||
global_State *g = state.g;
|
global_State *g = state.g;
|
||||||
intptr_t ip = (intptr_t)((ucontext_t*)data)->uc_mcontext.gregs[REG_RIP];
|
intptr_t ip = (intptr_t)((ucontext_t*)data)->uc_mcontext.gregs[REG_RIP];
|
||||||
int st = g->vmstate;
|
int st = g->vmstate;
|
||||||
state.events++;
|
state.vmstate[LJ_TRACEPROF_VMST_TOTAL]++;
|
||||||
assert((st >= 0) || (~st < LJ_VMST__MAX));
|
assert((st >= 0) || (~st < LJ_VMST__MAX));
|
||||||
if (st >= 0) {
|
if (st >= 0) {
|
||||||
lua_State *L = gco2th(gcref(g->cur_L));
|
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 >= 0) && (rel_ip < T->szmcode)) {
|
||||||
if (rel_ip < T->mcloop) {
|
if (rel_ip < T->mcloop) {
|
||||||
T->prof.nonloop++; /* Sample is in non-loop mcode. */
|
T->prof.nonloop++; /* Sample is in non-loop mcode. */
|
||||||
|
state.vmstate[LJ_TRACEPROF_VMST_TRACE_NONLOOP]++;
|
||||||
} else {
|
} else {
|
||||||
T->prof.loop++; /* Sample is in loop mcode. */
|
T->prof.loop++; /* Sample is in loop mcode. */
|
||||||
|
state.vmstate[LJ_TRACEPROF_VMST_TRACE_LOOP]++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
T->prof.other++; /* Sample is outside the trace mcode. */
|
T->prof.other++; /* Sample is outside the trace mcode. */
|
||||||
|
state.vmstate[LJ_TRACEPROF_VMST_TRACE_OTHER]++;
|
||||||
}
|
}
|
||||||
state.vmstate[LJ_TRACEPROF_VMST_TRACE]++;
|
|
||||||
} else {
|
} else {
|
||||||
state.vmstate[~st]++;
|
state.vmstate[~st]++;
|
||||||
}
|
}
|
||||||
@ -100,5 +95,14 @@ LUA_API void luaJIT_traceprofile_stop(lua_State *L)
|
|||||||
traceprofile_stop_timer();
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -6,6 +6,15 @@
|
|||||||
#ifndef _LJ_TRACEPROFILE_H
|
#ifndef _LJ_TRACEPROFILE_H
|
||||||
#define _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 {
|
typedef struct TraceProfile {
|
||||||
uint64_t nonloop; /* Samples taken in non-loop mcode */
|
uint64_t nonloop; /* Samples taken in non-loop mcode */
|
||||||
uint64_t loop; /* Samples taken in loop mcode */
|
uint64_t loop; /* Samples taken in loop mcode */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#define _LUAJIT_H
|
#define _LUAJIT_H
|
||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
#include "lj_def.h"
|
||||||
|
|
||||||
#define LUAJIT_VERSION "LuaJIT 2.1.0-beta2"
|
#define LUAJIT_VERSION "LuaJIT 2.1.0-beta2"
|
||||||
#define LUAJIT_VERSION_NUM 20100 /* Version 2.1.0 = 02.01.00. */
|
#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. */
|
/* Trace profiling API. */
|
||||||
LUA_API void luaJIT_traceprofile_start(lua_State *L, int interval);
|
LUA_API void luaJIT_traceprofile_start(lua_State *L, int interval);
|
||||||
LUA_API void luaJIT_traceprofile_stop(lua_State *L);
|
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. */
|
/* Enforce (dynamic) linker error for version mismatches. Call from main. */
|
||||||
|
Loading…
Reference in New Issue
Block a user