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 F3EC65C454B; Mon, 28 Aug 2023 18:24:13 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org F3EC65C454B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1693236254; bh=hIx7NJxVmYxapwOVXTFU7cCZod3gpu5XdeK693mgvYM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=amVGWV1heoMHI+G0C0lXEbz1k4Ua+xSCWh8MN9BjapNG15pcBIlzV337bt95Xqp8l vVzqHdjaNomNWGyw/6wl7JKhd54PQ9mSU3cE+uWnw9+Z9z/wlpHsI2qnsYnmpwyt+I 4Ufwmtg9P2NlctQuMEyhBAWVc9LbVAcMkk8wGptc= Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.41]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 944F15C454B for ; Mon, 28 Aug 2023 18:23:45 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 944F15C454B Received: by mail-lf1-f41.google.com with SMTP id 2adb3069b0e04-500b6456c7eso2153090e87.2 for ; Mon, 28 Aug 2023 08:23:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693236225; x=1693841025; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7MlI3c+1htpR2GqCCj8dLP3n47rvQWLltUrX7yVvgek=; b=P8qyf8gxFvh6tS74AkWxoY/gX1h6uVzbEE49odlcmWve0+GIbv3elbJLZ2jOmIHdhk aWIwI3eoAP3Z1B6vIlEIRar82E1KOe+bwX7esM3LeMqOCBaZ2hm0vqi1QX1tc0CDDvk4 jJ3YtlYr0H24Eqw0gGMbn4O4ZQjQE1zvts2+/bOY9kg9IRFwAR81HaJaBa6vE58Nmiy3 cSzq5fC6pHe+56Ds/IkTdTDeUkQVukNgekOC6rFAz3BUnsI/vIYNpDX8OtR/mWhAO+5C pvSqAVY3WHnfUUhNXChf2EoptJpnC2S7GVrjxCGaqlg2hi7xKclIfkx/YIxviCn5kpPH Bmcg== X-Gm-Message-State: AOJu0YzEPc3ARq78tB2JYSXtwlv5XF5X0xkNqHBUM6QcZ4cH5TyTdB2z oA3MPUxnTPLC1lioRnOWONqG0IZdTAMNIA== X-Google-Smtp-Source: AGHT+IGY9QzKlMKF2RlUYn1B2T4g2w+L08z3MCDaB35rU3JXetuv42CyjX7UIMCfmNOzY/dIiG8K8w== X-Received: by 2002:a05:6512:3ca1:b0:500:7d05:552a with SMTP id h33-20020a0565123ca100b005007d05552amr20968546lfv.53.1693236224256; Mon, 28 Aug 2023 08:23:44 -0700 (PDT) Received: from fckxorg.mail.msk ([2a00:1148:b0ba:16:a3e8:bdc1:dbed:dbc8]) by smtp.gmail.com with ESMTPSA id t11-20020ac243ab000000b004fe36b790a1sm1622184lfl.128.2023.08.28.08.23.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Aug 2023 08:23:43 -0700 (PDT) X-Google-Original-From: Maxim Kokryashkin To: tarantool-patches@dev.tarantool.org, skaplun@tarantool.org, sergeyb@tarantool.org Date: Mon, 28 Aug 2023 18:23:35 +0300 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH luajit 1/2] memprof: refactor symbol resolution 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: Maxim Kokryashkin via Tarantool-patches Reply-To: Maxim Kokryashkin Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This patch refactors symbol resolution in memprof, so now they are resolved during the process of parsing. This makes the generation mechanism excessive since symtab updates are no longer affecting the previous events. Follows up tarantool/tarantool#8700 --- .../misclib-memprof-lapi.test.lua | 73 +++++-------------- tools/memprof/humanize.lua | 16 ++-- tools/memprof/parse.lua | 2 +- tools/memprof/process.lua | 8 +- 4 files changed, 31 insertions(+), 68 deletions(-) diff --git a/test/tarantool-tests/misclib-memprof-lapi.test.lua b/test/tarantool-tests/misclib-memprof-lapi.test.lua index 3cb5c8be..0eee4e21 100644 --- a/test/tarantool-tests/misclib-memprof-lapi.test.lua +++ b/test/tarantool-tests/misclib-memprof-lapi.test.lua @@ -78,7 +78,7 @@ local function generate_parsed_output(payload) -- We don't need it any more. os.remove(TMP_BINFILE) - return symbols, events + return events end local function form_source_line(line, source) @@ -86,44 +86,13 @@ local function form_source_line(line, source) end local function form_trace_line(traceno, line, source) - return ("TRACE [%d] %s:%d"):format(traceno, source or SRC_PATH, line) + return ("TRACE [%d] started at %s:%d"):format(traceno, source or SRC_PATH, line) end -local function fill_ev_type(events, symbols, event_type) - local ev_type = { - source = {}, - trace = {}, - } +local function fill_ev_type(events, event_type) + local ev_type = {} for _, event in pairs(events[event_type]) do - local addr = event.loc.addr - local traceno = event.loc.traceno - local gen = event.loc.gen - - if traceno ~= 0 and symbols.trace[traceno] then - local trace_loc = symbols.trace[traceno][gen].start - addr = trace_loc.addr - gen = trace_loc.gen - ev_type.trace[traceno] = { - name = form_trace_line( - traceno, trace_loc.line, symbols.lfunc[addr][gen].source - ), - num = event.num, - } - elseif addr == 0 then - ev_type.INTERNAL = { - name = "INTERNAL", - num = event.num, - } - elseif symbols.lfunc[addr] then - local source = symbols.lfunc[addr][gen].source - - ev_type.source[source] = ev_type.source[source] or {} - - ev_type.source[source][event.loc.line] = { - name = form_source_line(symbols.lfunc[addr][gen].linedefined, source), - num = event.num, - } - end + ev_type[event.loc] = event.num end return ev_type end @@ -135,17 +104,15 @@ local function check_alloc_report(alloc, location, nevents) local source = location.source or SRC_PATH if traceno then expected_name = form_trace_line(traceno, location.line, source) - event = alloc.trace[traceno] else - expected_name = form_source_line(location.linedefined, source) - event = alloc.source[source][location.line] + expected_name = form_source_line(location.line, source) end - assert(expected_name == event.name, ("got='%s', expected='%s'"):format( - event.name, + event = alloc[expected_name] + assert(event, ("expected='%s', but no such event exists"):format( expected_name )) - assert(event.num == nevents, ("got=%d, expected=%d"):format( - event.num, + assert(event == nevents, ("got=%d, expected=%d"):format( + event, nevents )) return true @@ -180,10 +147,10 @@ end) test:test("output", function(subtest) subtest:plan(7) - local symbols, events = generate_parsed_output(default_payload) + local events = generate_parsed_output(default_payload) - local alloc = fill_ev_type(events, symbols, "alloc") - local free = fill_ev_type(events, symbols, "free") + local alloc = fill_ev_type(events, "alloc") + local free = fill_ev_type(events, "free") -- Check allocation reports. The second argument is a line -- number of the allocation event itself. The third is a line @@ -196,11 +163,11 @@ test:test("output", function(subtest) subtest:ok(check_alloc_report(alloc, { line = 42, linedefined = 35 }, 20)) -- Collect all previous allocated objects. - subtest:ok(free.INTERNAL.num == 22) + subtest:ok(free.INTERNAL == 22) -- Tests for leak-only option. -- See also https://github.com/tarantool/tarantool/issues/5812. - local heap_delta = process.form_heap_delta(events, symbols) + local heap_delta = process.form_heap_delta(events) local tab_alloc_stats = heap_delta[form_source_line(37)] local str_alloc_stats = heap_delta[form_source_line(42)] subtest:ok(tab_alloc_stats.nalloc == tab_alloc_stats.nfree) @@ -248,12 +215,12 @@ test:test("symtab-enrich-str", function(subtest) return M ]] - local symbols, events = generate_parsed_output(function() + local events = generate_parsed_output(function() local strchunk = assert(load(payloadstr, "strchunk"))() strchunk.payload() end) - local alloc = fill_ev_type(events, symbols, "alloc") + local alloc = fill_ev_type(events, "alloc") subtest:ok(check_alloc_report( alloc, { source = "strchunk", line = 2, linedefined = 0 }, 1) @@ -275,13 +242,13 @@ test:test("jit-output", function(subtest) -- On this run traces are generated, JIT-related allocations -- will be recorded as well. - local symbols, events = generate_parsed_output(default_payload) + local events = generate_parsed_output(default_payload) - local alloc = fill_ev_type(events, symbols, "alloc") + local alloc = fill_ev_type(events, "alloc") -- Test for marking JIT-related allocations as internal. -- See also https://github.com/tarantool/tarantool/issues/5679. - subtest:is(alloc.source[form_source_line(0)], nil) + subtest:is(alloc[form_source_line(0)], nil) -- We expect, that loop will be compiled into a trace. -- 10 allocations in interpreter mode, 1 allocation for a trace diff --git a/tools/memprof/humanize.lua b/tools/memprof/humanize.lua index 267baa91..5b289ce3 100644 --- a/tools/memprof/humanize.lua +++ b/tools/memprof/humanize.lua @@ -3,11 +3,9 @@ -- Major portions taken verbatim or adapted from the LuaVela. -- Copyright (C) 2015-2019 IPONWEB Ltd. -local symtab = require "utils.symtab" - local M = {} -function M.render(events, symbols) +function M.render(events) local ids = {} for id, _ in pairs(events) do @@ -21,7 +19,7 @@ function M.render(events, symbols) for i = 1, #ids do local event = events[ids[i]] print(string.format("%s: %d events\t+%d bytes\t-%d bytes", - symtab.demangle(symbols, event.loc), + event.loc, event.num, event.alloc, event.free @@ -29,7 +27,7 @@ function M.render(events, symbols) local prim_loc = {} for _, heap_chunk in pairs(event.primary) do - table.insert(prim_loc, symtab.demangle(symbols, heap_chunk.loc)) + table.insert(prim_loc, heap_chunk.loc) end if #prim_loc ~= 0 then table.sort(prim_loc) @@ -42,17 +40,17 @@ function M.render(events, symbols) end end -function M.profile_info(events, symbols) +function M.profile_info(events) print("ALLOCATIONS") - M.render(events.alloc, symbols) + M.render(events.alloc) print("") print("REALLOCATIONS") - M.render(events.realloc, symbols) + M.render(events.realloc) print("") print("DEALLOCATIONS") - M.render(events.free, symbols) + M.render(events.free) print("") end diff --git a/tools/memprof/parse.lua b/tools/memprof/parse.lua index d865267b..1b6eceb4 100644 --- a/tools/memprof/parse.lua +++ b/tools/memprof/parse.lua @@ -79,7 +79,7 @@ local function parse_location(reader, asource, symbols) error("Unknown asource "..asource) end local loc = symtab.loc(symbols, args) - return symtab.id(loc), loc + return symtab.id(loc), symtab.demangle(symbols, loc) end local function parse_alloc(reader, asource, events, heap, symbols) diff --git a/tools/memprof/process.lua b/tools/memprof/process.lua index 0bcb965b..faf4be4e 100644 --- a/tools/memprof/process.lua +++ b/tools/memprof/process.lua @@ -2,9 +2,7 @@ local M = {} -local symtab = require "utils.symtab" - -function M.form_heap_delta(events, symbols) +function M.form_heap_delta(events) -- Auto resurrects source event lines for counting/reporting. local dheap = setmetatable({}, {__index = function(t, line) rawset(t, line, { @@ -17,7 +15,7 @@ function M.form_heap_delta(events, symbols) for _, event in pairs(events.alloc) do if event.loc then - local ev_line = symtab.demangle(symbols, event.loc) + local ev_line = event.loc if (event.alloc > 0) then dheap[ev_line].dbytes = dheap[ev_line].dbytes + event.alloc @@ -37,7 +35,7 @@ function M.form_heap_delta(events, symbols) -- that references the table with memory changed -- (may be empty). for _, heap_chunk in pairs(event.primary) do - local ev_line = symtab.demangle(symbols, heap_chunk.loc) + local ev_line = heap_chunk.loc if (heap_chunk.alloced > 0) then dheap[ev_line].dbytes = dheap[ev_line].dbytes + heap_chunk.alloced -- 2.41.0