From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp37.i.mail.ru (smtp37.i.mail.ru [94.100.177.97]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id F3B6F445320 for ; Tue, 21 Jul 2020 14:35:09 +0300 (MSK) From: Sergey Kaplun Date: Tue, 21 Jul 2020 14:34:51 +0300 Message-Id: <20200721113451.25817-3-skaplun@tarantool.org> In-Reply-To: <20200721113451.25817-1-skaplun@tarantool.org> References: <20200721113451.25817-1-skaplun@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH 2/2] metrics: add C and Lua API List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Igor Munkin , Sergey Ostanevich Cc: tarantool-patches@dev.tarantool.org This patch adds C and Lua API for luajit metrics. Metrics include GC statistic, JIT information, strhash hit/miss counters and amount of different objects. C API provides with aditional header that contains structure `luam_metrics` and `luaM_metrics` function definition. Lua userspace expanded with builtin library (named `misc`) with corresponding method `getmetrics`. Metrics are divided by the two types: global and incremental. Global metrics are collected throughout the platform uptime. Incremental metrics are reset after each `luaM_metrics()` call. Part of tarantool/tarantool#5187 --- Makefile | 2 +- src/Makefile | 5 +-- src/Makefile.dep | 3 ++ src/lib_init.c | 2 ++ src/lib_misc.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ src/lj_misc_capi.c | 82 ++++++++++++++++++++++++++++++++++++++++++ src/lmisclib.h | 71 ++++++++++++++++++++++++++++++++++++ src/luaconf.h | 1 + 8 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 src/lib_misc.c create mode 100644 src/lj_misc_capi.c create mode 100644 src/lmisclib.h diff --git a/Makefile b/Makefile index 0f93308..4a56917 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ FILE_A= libluajit.a FILE_SO= libluajit.so FILE_MAN= luajit.1 FILE_PC= luajit.pc -FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h +FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h lmisclib.h FILES_JITLIB= bc.lua bcsave.lua dump.lua p.lua v.lua zone.lua \ dis_x86.lua dis_x64.lua dis_arm.lua dis_arm64.lua \ dis_arm64be.lua dis_ppc.lua dis_mips.lua dis_mipsel.lua \ diff --git a/src/Makefile b/src/Makefile index 827d4a4..fac69bc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -480,13 +480,14 @@ LJVM_BOUT= $(LJVM_S) LJVM_MODE= elfasm LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ - lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o + lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o \ + lib_misc.o LJLIB_C= $(LJLIB_O:.o=.c) LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \ lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \ lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_strscan.o \ - lj_strfmt.o lj_strfmt_num.o lj_api.o lj_profile.o \ + lj_strfmt.o lj_strfmt_num.o lj_api.o lj_misc_capi.o lj_profile.o \ lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \ lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \ lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \ diff --git a/src/Makefile.dep b/src/Makefile.dep index 2b1cb5e..1c3d8bd 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -41,6 +41,9 @@ lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \ lj_tab.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h +lib_misc.o: lib_misc.c lua.h lmisclib.h luaconf.h lj_obj.h lj_tab.h lj_str.h \ + lj_arch.h lj_lib.h lj_vm.h lj_libdef.h +lj_misc_capi.o: lj_misc_capi.c lua.h lmisclib.h luaconf.h lj_obj.h lj_arch.h lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \ diff --git a/src/lib_init.c b/src/lib_init.c index 2ed370e..664aa7d 100644 --- a/src/lib_init.c +++ b/src/lib_init.c @@ -12,6 +12,7 @@ #include "lua.h" #include "lauxlib.h" #include "lualib.h" +#include "lmisclib.h" #include "lj_arch.h" @@ -26,6 +27,7 @@ static const luaL_Reg lj_lib_load[] = { { LUA_DBLIBNAME, luaopen_debug }, { LUA_BITLIBNAME, luaopen_bit }, { LUA_JITLIBNAME, luaopen_jit }, + { LUAM_MISCLIBNAME, luaopen_misc }, { NULL, NULL } }; diff --git a/src/lib_misc.c b/src/lib_misc.c new file mode 100644 index 0000000..d23c2db --- /dev/null +++ b/src/lib_misc.c @@ -0,0 +1,89 @@ +/* + * Lua interface to tarantool-specific extensions to the public Lua/C API. + * + * Major portions taken verbatim or adapted from the LuaVela interpreter. + * Copyright (C) 2015-2019 IPONWEB Ltd. +*/ + +#define lib_misc_c +#define LUA_LIB + +#include "lua.h" +#include "lmisclib.h" + +#include "lj_obj.h" +#include "lj_str.h" +#include "lj_tab.h" +#include "lj_ff.h" +#include "lj_lib.h" + +/* ------------------------------------------------------------------------ */ + +static LJ_AINLINE void setnumfield(struct lua_State *L, GCtab *t, + const char *name, int64_t val) +{ + GCstr *key = lj_str_new(L, name, strlen(name)); + setnumV(lj_tab_setstr(L, t, key), (double)val); +} + +static LJ_AINLINE void settabfield(struct lua_State *L, GCtab *t, + const char *name, GCtab *val) +{ + GCstr *key = lj_str_new(L, name, strlen(name)); + settabV(L, lj_tab_setstr(L, t, key), val); +} + +#define LJLIB_MODULE_misc + +LJLIB_CF(misc_getmetrics) +{ + lua_createtable(L, 0, 7); + GCtab *glob_m = tabV(L->top - 1); + lua_createtable(L, 0, 12); + GCtab *inc_m = tabV(L->top - 1); + lua_createtable(L, 0, 2); + GCtab *m = tabV(L->top - 1); + + struct luam_Metrics metrics; + luaM_metrics(L, &metrics); + + setnumfield(L, glob_m, "strnum", metrics.strnum); + setnumfield(L, glob_m, "tabnum", metrics.tabnum); + setnumfield(L, glob_m, "udatanum", metrics.udatanum); + setnumfield(L, glob_m, "cdatanum", metrics.cdatanum); + + setnumfield(L, glob_m, "gc_total", metrics.gc_total); + + setnumfield(L, glob_m, "jit_mcode_size", metrics.jit_mcode_size); + setnumfield(L, glob_m, "jit_trace_num", metrics.jit_trace_num); + + setnumfield(L, inc_m, "gc_freed", metrics.gc_freed); + setnumfield(L, inc_m, "gc_allocated", metrics.gc_allocated); + + setnumfield(L, inc_m, "gc_steps_pause", metrics.gc_steps_pause); + setnumfield(L, inc_m, "gc_steps_propagate", metrics.gc_steps_propagate); + setnumfield(L, inc_m, "gc_steps_atomic", metrics.gc_steps_atomic); + setnumfield(L, inc_m, "gc_steps_sweepstring", + metrics.gc_steps_sweepstring); + setnumfield(L, inc_m, "gc_steps_sweep", metrics.gc_steps_sweep); + setnumfield(L, inc_m, "gc_steps_finalize", metrics.gc_steps_finalize); + + setnumfield(L, inc_m, "jit_snap_restore", metrics.jit_snap_restore); + setnumfield(L, inc_m, "jit_trace_abort", metrics.jit_trace_abort); + + setnumfield(L, inc_m, "strhash_hit", metrics.strhash_hit); + setnumfield(L, inc_m, "strhash_miss", metrics.strhash_miss); + settabfield(L, m, "global", glob_m); + settabfield(L, m, "incremental", inc_m); + return 1; +} + +/* ------------------------------------------------------------------------ */ + +#include "lj_libdef.h" + +LUALIB_API int luaopen_misc(struct lua_State *L) +{ + LJ_LIB_REG(L, LUAM_MISCLIBNAME, misc); + return 1; +} diff --git a/src/lj_misc_capi.c b/src/lj_misc_capi.c new file mode 100644 index 0000000..5f99064 --- /dev/null +++ b/src/lj_misc_capi.c @@ -0,0 +1,82 @@ +/* +** Tarantool-specific extensions to the public Lua/C API. +** +** Major portions taken verbatim or adapted from the LuaVela. +** Copyright (C) 2015-2019 IPONWEB Ltd. +*/ + +#include "lua.h" +#include "lmisclib.h" + +#include "lj_obj.h" +#include "lj_gc.h" +#include "lj_dispatch.h" + +#if LJ_HASJIT +#include "lj_jit.h" +#endif + +LUAM_API struct luam_Metrics * +luaM_metrics(lua_State *L, struct luam_Metrics *dst) +{ + memset(dst, 0, sizeof(*dst)); + global_State *g = G(L); + GCState *gc = &g->gc; +#if LJ_HASJIT + jit_State *J = G2J(g); +#endif + + dst->strhash_hit = g->strhash_hit; + g->strhash_hit = 0; + dst->strhash_miss = g->strhash_miss; + g->strhash_miss = 0; + + dst->strnum = g->strnum; + dst->tabnum = gc->tabnum; + dst->udatanum = gc->udatanum; +#if LJ_HASFFI + dst->cdatanum = gc->cdatanum; +#else + dst->cdatanum = 0; +#endif + + dst->gc_total = gc->total; + dst->gc_freed = gc->freed; + gc->freed = 0; + dst->gc_allocated = gc->allocated; + gc->allocated = 0; + + dst->gc_steps_pause = gc->state_count[GCSpause]; + gc->state_count[GCSpause] = 0; + + dst->gc_steps_propagate = gc->state_count[GCSpropagate]; + gc->state_count[GCSpropagate] = 0; + + dst->gc_steps_atomic = gc->state_count[GCSatomic]; + gc->state_count[GCSatomic] = 0; + + dst->gc_steps_sweepstring = gc->state_count[GCSsweepstring]; + gc->state_count[GCSsweepstring] = 0; + + dst->gc_steps_sweep = gc->state_count[GCSsweep]; + gc->state_count[GCSsweep] = 0; + + dst->gc_steps_finalize = gc->state_count[GCSfinalize]; + gc->state_count[GCSfinalize] = 0; + +#if LJ_HASJIT + dst->jit_snap_restore = J->nsnaprestore; + J->nsnaprestore = 0; + dst->jit_trace_abort = J->ntraceabort; + J->ntraceabort = 0; + + dst->jit_mcode_size = J->szallmcarea; + dst->jit_trace_num = J->freetrace; +#else + dst->jit_snap_restore = 0; + dst->jit_mcode_size = 0; + dst->jit_trace_num = 0; +#endif + + return dst; +} diff --git a/src/lmisclib.h b/src/lmisclib.h new file mode 100644 index 0000000..8d63038 --- /dev/null +++ b/src/lmisclib.h @@ -0,0 +1,71 @@ +/* + * Major portions taken verbatim or adapted from the LuaVela. + * Copyright (C) 2015-2019 IPONWEB Ltd. + */ + +#ifndef _LMISCLIB_H_INCLUDED +#define _LMISCLIB_H_INCLUDED + +#include "lua.h" + +/* API for obtaining various metrics from the platform. */ + +struct luam_Metrics { + /* + * New string has been found in the storage since last + * luaM_metrics() call. + */ + size_t strhash_hit; + /* + * New string has been added to the storage since last + * luaM_metrics() call. + */ + size_t strhash_miss; + + size_t strnum; /* Current amount of string objects. */ + size_t tabnum; /* Current amount of table objects. */ + size_t udatanum; /* Current amount of udata objects. */ + size_t cdatanum; /* Current amount of cdata objects. */ + + /* Memory currently allocated. */ + size_t gc_total; + /* Memory freed since last luaM_metrics() call. */ + size_t gc_freed; + /* Memory allocated since last luaM_metrics() call. */ + size_t gc_allocated; + + /* + * Count of GC invocations with different states + * since previous call of luaM_metrics(). + */ + size_t gc_steps_pause; + size_t gc_steps_propagate; + size_t gc_steps_atomic; + size_t gc_steps_sweepstring; + size_t gc_steps_sweep; + size_t gc_steps_finalize; + + /* + * Overall number of snap restores for all traces + * "belonging" to the given jit_State since the last call + * to luaM_metrics(). + */ + size_t jit_snap_restore; + /* + * Overall number of abort traces "belonging" to the given + * jit_State since the last call to luaM_metrics(). + */ + size_t jit_trace_abort; + /* Total size of all allocated machine code areas. */ + size_t jit_mcode_size; + /* Current amount of JIT traces. */ + unsigned int jit_trace_num; +}; + +LUAM_API struct luam_Metrics *luaM_metrics(lua_State *L, + struct luam_Metrics *dst); + +#define LUAM_MISCLIBNAME "misc" +LUALIB_API int luaopen_misc(lua_State *L); + +#endif /* _LMISCLIB_H_INCLUDED */ diff --git a/src/luaconf.h b/src/luaconf.h index 60cb928..cf01e36 100644 --- a/src/luaconf.h +++ b/src/luaconf.h @@ -144,6 +144,7 @@ #endif #define LUALIB_API LUA_API +#define LUAM_API LUA_API /* Support for internal assertions. */ #if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK) -- 2.24.1