From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id F003C6ECC0; Wed, 8 Dec 2021 20:22:14 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org F003C6ECC0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1638984135; bh=7v0uDNa5sh4Na+G77zt0VRNpYv6JfmeFTHR6weeEitA=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=ezxPpxZ9u5+7X+BlrFy/apcrUO5MO8yVPZc3S4l7hB0IJT4yh0HSu/UKIEzFVjVyE 8PgzSS1XKDvc1+2cuM/S3/zX6WtdF3mMZu7aqr7db+g/725sPB0q3ZZ3jA2XPqviB4 o2dvDcPC0xEGVBCEwF8w7LzRYN79rVbaZUQajY+M= 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 AD5B76ECC0 for ; Wed, 8 Dec 2021 20:22:12 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org AD5B76ECC0 Received: by smtp37.i.mail.ru with esmtpa (envelope-from ) id 1mv0dv-0002Kq-Gh; Wed, 08 Dec 2021 20:22:12 +0300 To: tarantool-patches@dev.tarantool.org, imun@tarantool.org, skaplun@tarantool.org Date: Wed, 8 Dec 2021 20:22:07 +0300 Message-Id: <20211208172207.80148-1-m.shishatskiy@tarantool.org> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD99F281DB1F96F126D5CD2422FFA38728B7FF4AB45A2A3143600894C459B0CD1B9CAD4FDD9B0ECBE8132CC4BE07E0756FBFE59498B1FE3732702AB01EBACA1B0D0 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE737BB76880A4CA9A4EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637396DC6A577C1088B8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D88F9EAC0811E56CFA7F7F19EAD991E983117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BAA867293B0326636D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE140C956E756FBB7A8F49F126DDB898E8D8FC6C240DEA7642DBF02ECDB25306B2B78CF848AE20165D0A6AB1C7CE11FEE324D079F6B4507B169735652A29929C6CC4224003CC836476EA7A3FFF5B025636E2021AF6380DFAD1A18204E546F3947CB11811A4A51E3B096D1867E19FE1407959CC434672EE6371089D37D7C0E48F6C8AA50765F7900637FB177F6A8366F17BEFF80C71ABB335746BA297DBC24807EABDAD6C7F3747799A X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C644EC96CB385211404AEDA3042978102901B7D73070A45E59C2B6934AE262D3EE7EAB7254005DCED2B0D99E5FC5BAFA192E1F3B950BCE21616EB5DE968479BF5B2CF3E77A3BD9B2CBDC6A1CF3F042BAD6DF99611D93F60EFBAA8CD687FCDB2EB699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34C1D376EF32BB089621A41D2810DB736166AEA04B3D4815DB2D51D9F1052D72AA05E1CF5F461A697A1D7E09C32AA3244CE4B0543CDF75ECECF634AE26019E7F0AC86C126E7119A0FE927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojnkZtajpA89WWx9UtPwrZkQ== X-Mailru-Sender: EFA0F3A8419EF2164CA45BB7A3684F2A335B44A382E8BD6DE0BD07C852475EFF14D23FB96A9F340B2376072A51849BFFE66B5C1DBFD5D09D5E022D45988A037B448E0EA96F20AB3672D6B4FCE48DF648AE208404248635DF X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit v2] memprof: enrich symtab when new trace is allocated X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Mikhail Shishatskiy via Tarantool-patches Reply-To: Mikhail Shishatskiy Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Since symtab can be enriched with new prototypes, it can be enriched with new traces as well. This feature can help to investigate trace-generation-heavy apps with memprof. This patch introduces the functionality described above by adding a `prof_epoch` counter to the `GCtrace` structure. If the profiler meets allocation from a trace, it checks if the trace was already streamed to the symtab. If not, a symtab entry is dumped inside an : | event-symtab := event-header sym? | sym := sym-lua | sym-trace | sym-trace := trace-no sym-addr line-no Since this patch, traces are no longer identified by address, as all the name collisions are resolved with symbols epochs. Also, the API of changed: function `parse_sym_trace` is now public in order to use it from the module. Follows up tarantool/tarantool#5815 --- CI: https://github.com/tarantool/tarantool/tree/shishqa/enrich-symtab-when-trace-is-allocated-v2 branch: https://github.com/tarantool/luajit/tree/shishqa/enrich-symtab-when-trace-is-allocated-v2 src/lj_jit.h | 8 +++++++ src/lj_memprof.c | 22 +++++++++++++------ src/lj_memprof.h | 5 +++-- src/lj_trace.c | 3 +++ .../misclib-memprof-lapi.test.lua | 13 +++++------ tools/memprof/parse.lua | 3 ++- tools/utils/symtab.lua | 14 ++++-------- 7 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/lj_jit.h b/src/lj_jit.h index d82292f8..766892aa 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -254,7 +254,15 @@ typedef struct GCtrace { uint8_t sinktags; /* Trace has SINK tags. */ uint8_t topslot; /* Top stack slot already checked to be allocated. */ uint8_t linktype; /* Type of link. */ +#if LJ_HASMEMPROF + /* + ** Epoch indicating if this trace was dumped to the symbol table for the + ** current profiling session. + */ + uint8_t prof_epoch; +#else uint8_t unused1; +#endif #ifdef LUAJIT_USE_GDBJIT void *gdbjit_entry; /* GDB JIT entry. */ #endif diff --git a/src/lj_memprof.c b/src/lj_memprof.c index c154de93..367fbe2b 100644 --- a/src/lj_memprof.c +++ b/src/lj_memprof.c @@ -30,7 +30,8 @@ static const unsigned char ljs_header[] = {'l', 'j', 's', LJS_CURRENT_VERSION, #if LJ_HASJIT -static void dump_symtab_trace(struct lj_wbuf *out, const GCtrace *trace) +static void dump_symtab_trace(struct lj_wbuf *out, GCtrace *trace, + const global_State *g) { GCproto *pt = &gcref(trace->startpt)->pt; BCLine lineno = 0; @@ -41,9 +42,7 @@ static void dump_symtab_trace(struct lj_wbuf *out, const GCtrace *trace) lineno = lj_debug_line(pt, proto_bcpos(pt, startpc)); - lj_wbuf_addbyte(out, SYMTAB_TRACE); lj_wbuf_addu64(out, (uint64_t)trace->traceno); - lj_wbuf_addu64(out, (uint64_t)trace->mcode); /* ** The information about the prototype, associated with the ** trace's start has already been dumped, as it is anchored @@ -53,11 +52,14 @@ static void dump_symtab_trace(struct lj_wbuf *out, const GCtrace *trace) */ lj_wbuf_addu64(out, (uintptr_t)pt); lj_wbuf_addu64(out, (uint64_t)lineno); + + trace->prof_epoch = g->prof_epoch; } #else -static void dump_symtab_trace(struct lj_wbuf *out, const GCtrace *trace) +static void dump_symtab_trace(struct lj_wbuf *out, const GCtrace *trace, + const global_State *g) { UNUSED(out); UNUSED(trace); @@ -93,7 +95,8 @@ static void dump_symtab(struct lj_wbuf *out, const struct global_State *g) break; } case (~LJ_TTRACE): { - dump_symtab_trace(out, gco2trace(o)); + lj_wbuf_addbyte(out, SYMTAB_TRACE); + dump_symtab_trace(out, gco2trace(o), g); break; } default: @@ -222,10 +225,15 @@ static void memprof_write_trace(struct memprof *mp, uint8_t aevent) const global_State *g = mp->g; const jit_State *J = G2J(g); const TraceNo traceno = g->vmstate; - const GCtrace *trace = traceref(J, traceno); + GCtrace *trace = traceref(J, traceno); + + if (LJ_UNLIKELY(trace->prof_epoch != g->prof_epoch)) { + lj_wbuf_addbyte(out, AEVENT_SYMTAB | ASOURCE_TRACE); + dump_symtab_trace(out, trace, g); + } + lj_wbuf_addbyte(out, aevent | ASOURCE_TRACE); lj_wbuf_addu64(out, (uint64_t)traceno); - lj_wbuf_addu64(out, (uintptr_t)trace->mcode); } #else diff --git a/src/lj_memprof.h b/src/lj_memprof.h index 150e6b32..0b06eb5b 100644 --- a/src/lj_memprof.h +++ b/src/lj_memprof.h @@ -27,7 +27,7 @@ ** reserved := ** sym := sym-lua | sym-trace | sym-final ** sym-lua := sym-header sym-addr sym-chunk sym-line -** sym-trace := sym-header trace-no trace-addr sym-addr sym-line +** sym-trace := sym-header trace-no sym-addr sym-line ** sym-header := ** sym-addr := ** sym-chunk := string @@ -78,8 +78,9 @@ ** loc-lua := sym-addr line-no ** loc-c := sym-addr ** loc-trace := trace-no trace-addr -** sym := sym-lua +** sym := sym-lua | sym-trace ** sym-lua := sym-addr sym-chunk sym-line +** sym-trace := trace-no sym-addr line-no ** sym-addr := ** sym-chunk := string ** sym-line := diff --git a/src/lj_trace.c b/src/lj_trace.c index 86563cdb..3fc6fc14 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -163,6 +163,9 @@ static void trace_save(jit_State *J, GCtrace *T) #ifdef LUAJIT_USE_PERFTOOLS perftools_addtrace(T); #endif +#if LJ_HASMEMPROF + T->prof_epoch = 0; +#endif } void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T) diff --git a/test/tarantool-tests/misclib-memprof-lapi.test.lua b/test/tarantool-tests/misclib-memprof-lapi.test.lua index 1c74b4d7..b7822563 100644 --- a/test/tarantool-tests/misclib-memprof-lapi.test.lua +++ b/test/tarantool-tests/misclib-memprof-lapi.test.lua @@ -267,7 +267,7 @@ test:test("jit-output", function(subtest) return end - subtest:plan(3) + subtest:plan(4) jit.opt.start(3, "hotloop=10") jit.flush() @@ -282,13 +282,12 @@ test:test("jit-output", function(subtest) -- See also https://github.com/tarantool/tarantool/issues/5679. subtest:ok(alloc[0] == nil) - -- Run already generated traces. - symbols, events = generate_parsed_output(default_payload) - - alloc = fill_ev_type(events, symbols, "alloc") - -- We expect, that loop will be compiled into a trace. - subtest:ok(check_alloc_report(alloc, { traceno = 1, line = 37 }, 20)) + -- 10 allocations in interpreter mode, 1 allocation for a trace + -- recording and assembling and next 9 allocations will happen + -- inside the trace. + subtest:ok(check_alloc_report(alloc, { line = 39, linedefined = 32 }, 11)) + subtest:ok(check_alloc_report(alloc, { traceno = 1, line = 37 }, 9)) -- See same checks with jit.off(). subtest:ok(check_alloc_report(alloc, { line = 34, linedefined = 32 }, 2)) diff --git a/tools/memprof/parse.lua b/tools/memprof/parse.lua index 38f76f00..fb4fcf3c 100644 --- a/tools/memprof/parse.lua +++ b/tools/memprof/parse.lua @@ -77,7 +77,6 @@ local function parse_location(reader, asource, symbols) line = reader:read_uleb128() elseif asource == ASOURCE_TRACE then traceno = reader:read_uleb128() - addr = reader:read_uleb128() else error("Unknown asource "..asource) end @@ -144,6 +143,8 @@ end local function parse_symtab(reader, asource, _, _, symbols) if asource == ASOURCE_LFUNC then symtab.parse_sym_lfunc(reader, symbols) + elseif asource == ASOURCE_TRACE then + symtab.parse_sym_trace(reader, symbols) end end diff --git a/tools/utils/symtab.lua b/tools/utils/symtab.lua index 133a0fc7..fced4c20 100644 --- a/tools/utils/symtab.lua +++ b/tools/utils/symtab.lua @@ -59,9 +59,8 @@ function M.parse_sym_lfunc(reader, symtab) }) end -local function parse_sym_trace(reader, symtab) +function M.parse_sym_trace(reader, symtab) local traceno = reader:read_uleb128() - local trace_addr = reader:read_uleb128() local sym_addr = reader:read_uleb128() local sym_line = reader:read_uleb128() @@ -70,14 +69,13 @@ local function parse_sym_trace(reader, symtab) end table.insert(symtab.trace[traceno], { - addr = trace_addr, start = M.new_loc(symtab, sym_addr, sym_line, 0) }) end local parsers = { [SYMTAB_LFUNC] = M.parse_sym_lfunc, - [SYMTAB_TRACE] = parse_sym_trace, + [SYMTAB_TRACE] = M.parse_sym_trace, } function M.parse(reader) @@ -131,18 +129,14 @@ end local function demangle_trace(symtab, loc) local traceno = loc.traceno - local addr = loc.addr assert(traceno ~= 0, "Location is a trace") - local trace_str = string_format("TRACE [%d] %#x", traceno, addr) + local trace_str = string_format("TRACE [%d]", traceno) local epochs = symtab.trace[traceno] local trace = epochs and epochs[loc.epoch] - -- If trace, which was remembered in the symtab, has not - -- been flushed, associate it with a proto, where trace - -- recording started. - if trace and trace.addr == addr then + if trace then assert(trace.start.traceno == 0, "Trace start is not a trace") return trace_str.." started at "..M.demangle(symtab, trace.start) end -- 2.33.1