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 04C11445323 for ; Tue, 21 Jul 2020 14:35:06 +0300 (MSK) From: Sergey Kaplun Date: Tue, 21 Jul 2020 14:34:50 +0300 Message-Id: <20200721113451.25817-2-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 1/2] metrics: add counters for metrics interested in 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 counters for: - amount of table, cdata and udata objects, - GC invokations by GC states, - strhash misses or hits, - amount of freed or allocated memory, - amount of aborted traces and restored snapshots. C and Lua API will be added in the next patch. Part of tarantool/tarantool#5187 --- src/lj_cdata.c | 2 ++ src/lj_cdata.h | 2 ++ src/lj_gc.c | 4 ++++ src/lj_gc.h | 6 +----- src/lj_jit.h | 7 +++++++ src/lj_obj.h | 25 +++++++++++++++++++++++++ src/lj_snap.c | 1 + src/lj_state.c | 13 ++++++++++++- src/lj_str.c | 5 +++++ src/lj_tab.c | 2 ++ src/lj_trace.c | 5 ++++- src/lj_udata.c | 2 ++ 12 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 68e16d7..0dd8553 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c @@ -46,6 +46,7 @@ GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz, CTSize align) cd->marked |= 0x80; cd->gct = ~LJ_TCDATA; cd->ctypeid = id; + g->gc.cdatanum++; return cd; } @@ -82,6 +83,7 @@ void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) } else { lj_mem_free(g, memcdatav(cd), sizecdatav(cd)); } + g->gc.cdatanum--; } void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj, uint32_t it) diff --git a/src/lj_cdata.h b/src/lj_cdata.h index 5bb0f5d..66b023b 100644 --- a/src/lj_cdata.h +++ b/src/lj_cdata.h @@ -45,6 +45,7 @@ static LJ_AINLINE GCcdata *lj_cdata_new(CTState *cts, CTypeID id, CTSize sz) cd = (GCcdata *)lj_mem_newgco(cts->L, sizeof(GCcdata) + sz); cd->gct = ~LJ_TCDATA; cd->ctypeid = ctype_check(cts, id); + G(cts->L)->gc.cdatanum++; return cd; } @@ -54,6 +55,7 @@ static LJ_AINLINE GCcdata *lj_cdata_new_(lua_State *L, CTypeID id, CTSize sz) GCcdata *cd = (GCcdata *)lj_mem_newgco(L, sizeof(GCcdata) + sz); cd->gct = ~LJ_TCDATA; cd->ctypeid = id; + G(L)->gc.cdatanum++; return cd; } diff --git a/src/lj_gc.c b/src/lj_gc.c index 1c8e6ce..44c8aa1 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -634,6 +634,7 @@ static void atomic(global_State *g, lua_State *L) static size_t gc_onestep(lua_State *L) { global_State *g = G(L); + g->gc.state_count[g->gc.state]++; switch (g->gc.state) { case GCSpause: gc_mark_start(g); /* Start a new GC cycle by marking all GC roots. */ @@ -857,6 +858,8 @@ void *lj_mem_realloc(lua_State *L, void *p, GCSize osz, GCSize nsz) lua_assert((nsz == 0) == (p == NULL)); lua_assert(checkptrGC(p)); g->gc.total = (g->gc.total - osz) + nsz; + g->gc.allocated += nsz; + g->gc.freed += osz; return p; } @@ -869,6 +872,7 @@ void * LJ_FASTCALL lj_mem_newgco(lua_State *L, GCSize size) lj_err_mem(L); lua_assert(checkptrGC(o)); g->gc.total += size; + g->gc.allocated += size; setgcrefr(o->gch.nextgc, g->gc.root); setgcref(g->gc.root, o); newwhite(g, o); diff --git a/src/lj_gc.h b/src/lj_gc.h index 669bbe9..2051220 100644 --- a/src/lj_gc.h +++ b/src/lj_gc.h @@ -8,11 +8,6 @@ #include "lj_obj.h" -/* Garbage collector states. Order matters. */ -enum { - GCSpause, GCSpropagate, GCSatomic, GCSsweepstring, GCSsweep, GCSfinalize -}; - /* Bitmasks for marked field of GCobj. */ #define LJ_GC_WHITE0 0x01 #define LJ_GC_WHITE1 0x02 @@ -117,6 +112,7 @@ LJ_FUNC void *lj_mem_grow(lua_State *L, void *p, static LJ_AINLINE void lj_mem_free(global_State *g, void *p, size_t osize) { g->gc.total -= (GCSize)osize; + g->gc.freed += osize; g->allocf(g->allocd, p, osize, 0); } diff --git a/src/lj_jit.h b/src/lj_jit.h index 7eb3d2a..960a02b 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -475,6 +475,13 @@ typedef struct jit_State { size_t szmcarea; /* Size of current mcode area. */ size_t szallmcarea; /* Total size of all allocated mcode areas. */ + size_t nsnaprestore; /* Overall number of snap restores for all traces + ** "belonging" to the given jit_State + ** since the last call to luaM_metrics(). */ + size_t ntraceabort; /* Overall number of abort traces + ** "belonging" to the given jit_State + ** since the last call to luaM_metrics(). */ + TValue errinfo; /* Additional info element for trace errors. */ #if LJ_HASPROFILE diff --git a/src/lj_obj.h b/src/lj_obj.h index f368578..1fee04f 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -571,13 +571,28 @@ typedef enum { #define basemt_obj(g, o) ((g)->gcroot[GCROOT_BASEMT+itypemap(o)]) #define mmname_str(g, mm) (strref((g)->gcroot[GCROOT_MMNAME+(mm)])) +/* Garbage collector states. Order matters. */ +enum { + GCSpause, + GCSpropagate, + GCSatomic, + GCSsweepstring, + GCSsweep, + GCSfinalize, + GCSlast +}; + typedef struct GCState { GCSize total; /* Memory currently allocated. */ + size_t freed; /* Memory freed since last luaM_metrics() call. */ + size_t allocated; /* Memory allocated since last luaM_metrics() call. */ GCSize threshold; /* Memory threshold. */ uint8_t currentwhite; /* Current white color. */ uint8_t state; /* GC state. */ uint8_t nocdatafin; /* No cdata finalizer called. */ uint8_t unused2; + size_t state_count[GCSlast]; /* Count of GC invocations with different states + ** since previous call of luaM_metrics(). */ MSize sweepstr; /* Sweep position in string table. */ GCRef root; /* List of all collectable objects. */ MRef sweep; /* Sweep position in root list. */ @@ -589,6 +604,12 @@ typedef struct GCState { GCSize estimate; /* Estimate of memory actually in use. */ MSize stepmul; /* Incremental GC step granularity. */ MSize pause; /* Pause between successive GC cycles. */ + + size_t tabnum; /* Current amount of table objects. */ + size_t udatanum; /* Current amount of udata objects. */ +#ifdef LJ_HASFFI + size_t cdatanum; /* Current amount of cdata objects. */ +#endif } GCState; /* Global state, shared by all threads of a Lua universe. */ @@ -602,6 +623,10 @@ typedef struct global_State { BloomFilter next[2]; } strbloom; #endif + size_t strhash_hit; /* New string has been found in the storage + ** since last luaM_metrics() call. */ + size_t strhash_miss; /* New string has been added to the storage + ** since last luaM_metrics() call. */ lua_Alloc allocf; /* Memory allocator. */ void *allocd; /* Memory allocator data. */ GCState gc; /* Garbage collector. */ diff --git a/src/lj_snap.c b/src/lj_snap.c index 7554caf..4cf27e7 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -904,6 +904,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) L->top = frame + snap->nslots; break; } + J->nsnaprestore++; return pc; } diff --git a/src/lj_state.c b/src/lj_state.c index 632dd07..b71ebae 100644 --- a/src/lj_state.c +++ b/src/lj_state.c @@ -204,6 +204,16 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) setgcref(g->uvhead.prev, obj2gco(&g->uvhead)); setgcref(g->uvhead.next, obj2gco(&g->uvhead)); g->strmask = ~(MSize)0; + + memset(g->gc.state_count, 0, GCSlast * sizeof(g->gc.state_count[0])); + g->strhash_hit = 0; + g->strhash_miss = 0; + g->gc.tabnum = 0; + g->gc.udatanum = 0; +#if LJ_HASFFI + g->gc.cdatanum = 0; +#endif + setnilV(registry(L)); setnilV(&g->nilnode.val); setnilV(&g->nilnode.key); @@ -214,7 +224,8 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) g->gc.state = GCSpause; setgcref(g->gc.root, obj2gco(L)); setmref(g->gc.sweep, &g->gc.root); - g->gc.total = sizeof(GG_State); + g->gc.allocated = g->gc.total = sizeof(GG_State); + g->gc.freed = 0; g->gc.pause = LUAI_GCPAUSE; g->gc.stepmul = LUAI_GCMUL; lj_dispatch_init((GG_State *)L); diff --git a/src/lj_str.c b/src/lj_str.c index 24e90ca..8ff955e 100644 --- a/src/lj_str.c +++ b/src/lj_str.c @@ -222,6 +222,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) str_fastcmp(str, strdata(sx), len) == 0) { /* Resurrect if dead. Can only happen with fixstring() (keywords). */ if (isdead(g, o)) flipwhite(o); + g->strhash_hit++; return sx; /* Return existing string. */ } o = gcnext(o); @@ -234,6 +235,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) memcmp(str, strdata(sx), len) == 0) { /* Resurrect if dead. Can only happen with fixstring() (keywords). */ if (isdead(g, o)) flipwhite(o); + g->strhash_hit++; return sx; /* Return existing string. */ } o = gcnext(o); @@ -266,6 +268,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) if (sx->hash == fh && sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) { /* Resurrect if dead. Can only happen with fixstring() (keywords). */ if (isdead(g, o)) flipwhite(o); + g->strhash_hit++; return sx; /* Return existing string. */ } o = gcnext(o); @@ -276,6 +279,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) if (sx->hash == fh && sx->len == len && memcmp(str, strdata(sx), len) == 0) { /* Resurrect if dead. Can only happen with fixstring() (keywords). */ if (isdead(g, o)) flipwhite(o); + g->strhash_hit++; return sx; /* Return existing string. */ } o = gcnext(o); @@ -293,6 +297,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) } } #endif + g->strhash_miss++; /* Nope, create a new string. */ s = lj_mem_newt(L, sizeof(GCstr)+len+1, GCstr); newwhite(g, s); diff --git a/src/lj_tab.c b/src/lj_tab.c index ff216f3..c5f358e 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c @@ -141,6 +141,7 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits) } if (hbits) newhpart(L, t, hbits); + G(L)->gc.tabnum++; return t; } @@ -240,6 +241,7 @@ void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t) lj_mem_free(g, t, sizetabcolo((uint32_t)t->colo & 0x7f)); else lj_mem_freet(g, t); + g->gc.tabnum--; } /* -- Table resizing ------------------------------------------------------ */ diff --git a/src/lj_trace.c b/src/lj_trace.c index d85b47f..b17bde3 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -538,8 +538,10 @@ static int trace_downrec(jit_State *J) /* Restart recording at the return instruction. */ lua_assert(J->pt != NULL); lua_assert(bc_isret(bc_op(*J->pc))); - if (bc_op(*J->pc) == BC_RETM) + if (bc_op(*J->pc) == BC_RETM) { + J->ntraceabort++; return 0; /* NYI: down-recursion with RETM. */ + } J->parent = 0; J->exitno = 0; J->state = LJ_TRACE_RECORD; @@ -616,6 +618,7 @@ static int trace_abort(jit_State *J) return trace_downrec(J); else if (e == LJ_TRERR_MCODEAL) lj_trace_flushall(L); + J->ntraceabort++; return 0; } diff --git a/src/lj_udata.c b/src/lj_udata.c index bd0321b..70c722a 100644 --- a/src/lj_udata.c +++ b/src/lj_udata.c @@ -24,11 +24,13 @@ GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env) /* Chain to userdata list (after main thread). */ setgcrefr(ud->nextgc, mainthread(g)->nextgc); setgcref(mainthread(g)->nextgc, obj2gco(ud)); + g->gc.udatanum++; return ud; } void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud) { + g->gc.udatanum--; lj_mem_free(g, ud, sizeudata(ud)); } -- 2.24.1