diff --git a/src/lib_jit.c b/src/lib_jit.c index d019b252d0..7411328970 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c @@ -204,16 +204,42 @@ LJLIB_CF(jit_opt_start) #define LJLIB_MODULE_jit_vmprofile +LJLIB_CF(jit_vmprofile_open) +{ + if (L->base < L->top && tvisstr(L->base)) { + return luaJIT_vmprofile_open(L, strdata(lj_lib_checkstr(L, 1))); + } else { + lj_err_argtype(L, 1, "filename"); + return 0; + } +} + +LJLIB_CF(jit_vmprofile_close) +{ + if (L->base < L->top && tvislightud(L->base)) { + return luaJIT_vmprofile_close(L, lightudV(L->base)); + } else { + lj_err_argtype(L, 1, "vmprofile"); + } +} + +LJLIB_CF(jit_vmprofile_select) +{ + if (L->base < L->top && tvislightud(L->base)) { + return luaJIT_vmprofile_select(L, lightudV(L->base)); + } else { + lj_err_argtype(L, 1, "vmprofile"); + } +} + LJLIB_CF(jit_vmprofile_start) { - luaJIT_vmprofile_start(L); - return 0; + return luaJIT_vmprofile_start(L); } LJLIB_CF(jit_vmprofile_stop) { - luaJIT_vmprofile_stop(L); - return 0; + return luaJIT_vmprofile_stop(L); } #include "lj_libdef.h" @@ -234,7 +260,6 @@ JIT_PARAMDEF(JIT_PARAMINIT) 0 }; - /* Arch-dependent CPU detection. */ static uint32_t jit_cpudetect(lua_State *L) { diff --git a/src/lj_vmprofile.c b/src/lj_vmprofile.c index 3f625761e7..bb35e9bc54 100644 --- a/src/lj_vmprofile.c +++ b/src/lj_vmprofile.c @@ -9,12 +9,18 @@ #define _GNU_SOURCE 1 #include #include +#include +#include #include +#include +#include +#include #include #include #include #undef _GNU_SOURCE +#include "lj_err.h" #include "lj_obj.h" #include "lj_dispatch.h" #include "lj_jit.h" @@ -99,15 +105,49 @@ static void stop_timer() /* -- Lua API ------------------------------------------------------------- */ -LUA_API void luaJIT_vmprofile_start(lua_State *L) +LUA_API int luaJIT_vmprofile_open(lua_State *L, const char *str) +{ + int fd; + void *ptr; + if (((fd = open(str, 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)); + setlightudV(L->base, checklightudptr(L, ptr)); + } else { + setnilV(L->base); + } + if (fd != -1) { + close(fd); + } + return 1; +} + +LUA_API int luaJIT_vmprofile_close(lua_State *L, void *ud) +{ + munmap(ud, sizeof(VMProfile)); + return 0; +} + +LUA_API int luaJIT_vmprofile_select(lua_State *L, void *ud) +{ + setlightudV(L->base, checklightudptr(L, profile)); + profile = (VMProfile *)ud; + return 1; +} + +LUA_API int luaJIT_vmprofile_start(lua_State *L) { memset(&state, 0, sizeof(state)); state.g = G(L); start_timer(1); /* Sample every 1ms */ + return 0; } -LUA_API void luaJIT_vmprofile_stop(lua_State *L) +LUA_API int luaJIT_vmprofile_stop(lua_State *L) { stop_timer(); + return 0; } diff --git a/src/luajit.h b/src/luajit.h index 597b3e1f27..30baabb2a9 100644 --- a/src/luajit.h +++ b/src/luajit.h @@ -65,8 +65,11 @@ enum { LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode); /* VM profiling API. */ -LUA_API void luaJIT_vmprofile_start(lua_State *L); -LUA_API void luaJIT_vmprofile_stop(lua_State *L); +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_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); /* Enforce (dynamic) linker error for version mismatches. Call from main. */ LUA_API void LUAJIT_VERSION_SYM(void); diff --git a/testsuite/test/index b/testsuite/test/index index bd4081e39e..41afbcf99c 100644 --- a/testsuite/test/index +++ b/testsuite/test/index @@ -4,3 +4,4 @@ bc +luajit>=2 computations.lua trace +jit opt +jit +raptorjit diff --git a/testsuite/test/raptorjit/index b/testsuite/test/raptorjit/index new file mode 100644 index 0000000000..1a3dcd3271 --- /dev/null +++ b/testsuite/test/raptorjit/index @@ -0,0 +1 @@ +vmprofile.lua diff --git a/testsuite/test/raptorjit/vmprofile.lua b/testsuite/test/raptorjit/vmprofile.lua new file mode 100644 index 0000000000..ae9bb30a41 --- /dev/null +++ b/testsuite/test/raptorjit/vmprofile.lua @@ -0,0 +1,34 @@ +local vmprofile = require("jit.vmprofile") + +do --- vmprofile start and stop + vmprofile.start() + vmprofile.stop() +end + + +do --- vmprofile multiple starts + for i = 1, 1000 do vmprofile.start() end + vmprofile.stop() +end + +do --- vmprofile multiple profiles + vmprofile.start() + local a = vmprofile.open("a.vmprofile") + local b = vmprofile.open("b.vmprofile") + vmprofile.select(a) + for i = 1, 1e8 do end + vmprofile.select(b) + for i = 1, 1e8 do end + vmprofile.select(a) + for i = 1, 1e8 do end + vmprofile.stop() + vmprofile.close(a) + vmprofile.close(b) + -- simple sanity check that the profiles have different contents. + -- e.g. to make sure there was at least one sample taken somewhere. + assert(io.open("a.vmprofile", "r"):read("*a") ~= + io.open("b.vmprofile", "r"):read("*a"), + "check that profiles have different contents") + os.remove("a.vmprofile") + os.remove("b.vmprofile") +end