Skip to content

Commit

Permalink
Support "one-liner" usage of jit.vmprofile.open()
Browse files Browse the repository at this point in the history
Make simple usage of VMProfile more convenient.

For example:

    jit.vmprofile.open("bigloop")   for i = 1, 1e9 do end
    jit.vmprofile.open("shortloop") for i = 1, 1e6 do end

This involves two changes to the jit.vmprofile API:

Preload the jit.vmprofile library, so that no require() is needed.

Make the default behavior of jit.vmprofile.open(filename) include
selecting the profile and enabling the timer. This way a single call
with a filename will enable live profiling to disk.

The slightly awkward aspect is that the jit.vmprofile.open() changes
are not quite backwards compatible. The old behavior was to not select
the new profile nor enable the timer (on the assumption that this will
be done separately.) This behavior can be accessed using new optional
arguments boolean arguments `noselect` and `noopen`:

    jit.vmprofile(filename, [noselect, noopen])
  • Loading branch information
lukego committed Dec 20, 2017
1 parent 02d596c commit fd0e49d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 52 deletions.
18 changes: 7 additions & 11 deletions src/lib_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,14 @@ LJLIB_CF(jit_opt_start)

LJLIB_CF(jit_vmprofile_open)
{
if (L->base < L->top && tvisstr(L->base)) {
return luaJIT_vmprofile_open(L, strdata(lj_lib_checkstr(L, 1)));
int nargs = (int)(L->top - L->base);
int nostart = nargs >= 3 ? boolV(L->base+2) : 0;
int noselect = nargs >= 2 ? boolV(L->base+1) : 0;
const char *filename = nargs >= 1 ? strdata(lj_lib_checkstr(L, 1)) : NULL;
if (filename) {
return luaJIT_vmprofile_open(L, filename, noselect, nostart);
} else {
lj_err_argtype(L, 1, "filename");
return 0;
}
}

Expand Down Expand Up @@ -250,12 +253,6 @@ LJLIB_CF(jit_vmprofile_stop)

#include "lj_libdef.h"

static int luaopen_jit_vmprofile(lua_State *L)
{
LJ_LIB_REG(L, NULL, jit_vmprofile);
return 1;
}

/* -- JIT compiler initialization ----------------------------------------- */

/* Default values for JIT parameters. */
Expand Down Expand Up @@ -313,8 +310,7 @@ LUALIB_API int luaopen_jit(lua_State *L)
lua_pushinteger(L, LUAJIT_VERSION_NUM);
lua_pushliteral(L, LUAJIT_VERSION);
LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
lj_lib_prereg(L, LUA_JITLIBNAME ".vmprofile", luaopen_jit_vmprofile,
tabref(L->env));
LJ_LIB_REG(L, "jit.vmprofile", jit_vmprofile);
LJ_LIB_REG(L, "jit.opt", jit_opt);
L->top -= 2;
return 1;
Expand Down
80 changes: 46 additions & 34 deletions src/lj_vmprofile.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,10 @@ static struct {
struct sigaction oldsa;
} state;

/* -- State that the application can manage via FFI ----------------------- */
static int started;

static VMProfile *profile; /* Current counters */

/* How much memory to allocate for profiler counters. */
int vmprofile_get_profile_size() {
return sizeof(VMProfile);
}

/* Open a counter file on disk and returned the mmapped data structure. */
void *vmprofile_open_file(const char *filename)
{
int fd;
void *ptr = MAP_FAILED;
if (((fd = open(filename, O_RDWR|O_CREAT, 0666)) != -1) &&
((ftruncate(fd, sizeof(VMProfile))) != -1) &&
((ptr = mmap(NULL, sizeof(VMProfile), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0)) != MAP_FAILED)) {
memset(ptr, 0, sizeof(VMProfile));
}
if (fd != -1) close(fd);
return ptr == MAP_FAILED ? NULL : ptr;
}

/* Set the memory where the next samples will be counted.
Size of the memory must match vmprofile_get_profile_size(). */
void vmprofile_set_profile(void *counters) {
profile = (VMProfile*)counters;
profile->magic = 0x1d50f007;
profile->major = 4;
profile->minor = 0;
}

/* -- Signal handler ------------------------------------------------------ */

/* Signal handler: bumps one counter. */
Expand Down Expand Up @@ -133,13 +104,56 @@ static void stop_timer()
sigaction(SIGPROF, NULL, &state.oldsa);
}

/* -- State that the application can manage via FFI ----------------------- */

/* How much memory to allocate for profiler counters. */
int vmprofile_get_profile_size() {
return sizeof(VMProfile);
}

/* Open a counter file on disk and returned the mmapped data structure. */
void *vmprofile_open_file(const char *filename)
{
int fd;
void *ptr = MAP_FAILED;
if (((fd = open(filename, O_RDWR|O_CREAT, 0666)) != -1) &&
((ftruncate(fd, sizeof(VMProfile))) != -1) &&
((ptr = mmap(NULL, sizeof(VMProfile), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0)) != MAP_FAILED)) {
memset(ptr, 0, sizeof(VMProfile));
}
if (fd != -1) close(fd);
return ptr == MAP_FAILED ? NULL : ptr;
}

/* Set the memory where the next samples will be counted.
Size of the memory must match vmprofile_get_profile_size(). */
void vmprofile_set_profile(void *counters) {
profile = (VMProfile*)counters;
profile->magic = 0x1d50f007;
profile->major = 4;
profile->minor = 0;
}

void vmprofile_start(lua_State *L)
{
if (!started) {
memset(&state, 0, sizeof(state));
state.g = G(L);
start_timer(1); /* Sample every 1ms */
started = 1;
}
}

/* -- Lua API ------------------------------------------------------------- */

LUA_API int luaJIT_vmprofile_open(lua_State *L, const char *str)
LUA_API int luaJIT_vmprofile_open(lua_State *L, const char *str, int noselect, int nostart)
{
void *ptr;
if ((ptr = vmprofile_open_file(str)) != NULL) {
setlightudV(L->base, checklightudptr(L, ptr));
if (!noselect) vmprofile_set_profile(ptr);
if (!nostart) vmprofile_start(L);
} else {
setnilV(L->base);
}
Expand All @@ -161,9 +175,7 @@ LUA_API int luaJIT_vmprofile_select(lua_State *L, void *ud)

LUA_API int luaJIT_vmprofile_start(lua_State *L)
{
memset(&state, 0, sizeof(state));
state.g = G(L);
start_timer(1); /* Sample every 1ms */
vmprofile_start(L);
return 0;
}

Expand Down
10 changes: 4 additions & 6 deletions src/luajit.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,12 +465,10 @@ static int runargs(lua_State *L, char **argv, int argn)
case 'b': /* LuaJIT extension. */
return dobytecode(L, argv+i);
case 'p': {
void *ptr;
if ((ptr = vmprofile_open_file(argv[++i])) != NULL) {
vmprofile_set_profile(ptr);
luaJIT_vmprofile_start(L);
} else {
fprintf(stderr, "unable to open vmprofile\n");
char *filename = argv[++i];
luaJIT_vmprofile_open(L, filename, 0, 0);
if (lua_isnil(L, -1)) {
fprintf(stderr, "unable to open vmprofile: %s\n", filename);
fflush(stderr);
}
break;
Expand Down
2 changes: 1 addition & 1 deletion src/luajit.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);

/* VM profiling API. */
LUA_API int luaJIT_vmprofile_start(lua_State *L);
LUA_API int luaJIT_vmprofile_open(lua_State *L, const char *str);
LUA_API int luaJIT_vmprofile_open(lua_State *L, const char *str, int noselect, int nostart);
LUA_API int luaJIT_vmprofile_select(lua_State *L, void *ud);
LUA_API int luaJIT_vmprofile_close(lua_State *L, void *ud);
LUA_API int luaJIT_vmprofile_stop(lua_State *L);
Expand Down

0 comments on commit fd0e49d

Please sign in to comment.