Tarantool development patches archive
 help / color / mirror / Atom feed
From: Maxim Kokryashkin via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: tarantool-patches@dev.tarantool.org, skaplun@tarantool.org,
	sergeyb@tarantool.org
Subject: [Tarantool-patches] [PATCH luajit 1/2] memprof: refactor symbol resolution
Date: Mon, 28 Aug 2023 18:23:35 +0300	[thread overview]
Message-ID: <acbce4444d9b3b769a59f99cec8b0ad7f0488acb.1693236068.git.m.kokryashkin@tarantool.org> (raw)
In-Reply-To: <cover.1693236068.git.m.kokryashkin@tarantool.org>

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


  reply	other threads:[~2023-08-28 15:24 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-28 15:23 [Tarantool-patches] [PATCH luajit 0/2] profilers: purge generations Maxim Kokryashkin via Tarantool-patches
2023-08-28 15:23 ` Maxim Kokryashkin via Tarantool-patches [this message]
2023-09-03 10:14   ` [Tarantool-patches] [PATCH luajit 1/2] memprof: refactor symbol resolution Sergey Kaplun via Tarantool-patches
2023-09-04  5:44     ` Maxim Kokryashkin via Tarantool-patches
2023-09-05 11:47   ` Sergey Bronnikov via Tarantool-patches
2023-09-08 11:04     ` Maxim Kokryashkin via Tarantool-patches
2023-10-06 14:52       ` Sergey Bronnikov via Tarantool-patches
2023-08-28 15:23 ` [Tarantool-patches] [PATCH luajit 2/2] profilers: purge generation mechanism Maxim Kokryashkin via Tarantool-patches
2023-09-03 10:21   ` Sergey Kaplun via Tarantool-patches
2023-09-04  5:47     ` Maxim Kokryashkin via Tarantool-patches
2023-09-05 11:53   ` Sergey Bronnikov via Tarantool-patches
2023-09-12 10:26     ` Maxim Kokryashkin via Tarantool-patches
2023-09-14  9:47       ` Sergey Bronnikov via Tarantool-patches
2023-09-18  9:18         ` Maxim Kokryashkin via Tarantool-patches
2023-10-06 14:43           ` Sergey Bronnikov via Tarantool-patches
2023-10-06 14:45             ` Sergey Bronnikov via Tarantool-patches
2023-10-06 14:40       ` Sergey Bronnikov via Tarantool-patches
2023-10-06 14:52       ` Sergey Bronnikov via Tarantool-patches
2023-11-13 18:48       ` Igor Munkin via Tarantool-patches
2023-11-23  6:32 ` [Tarantool-patches] [PATCH luajit 0/2] profilers: purge generations Igor Munkin via Tarantool-patches

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=acbce4444d9b3b769a59f99cec8b0ad7f0488acb.1693236068.git.m.kokryashkin@tarantool.org \
    --to=tarantool-patches@dev.tarantool.org \
    --cc=max.kokryashkin@gmail.com \
    --cc=sergeyb@tarantool.org \
    --cc=skaplun@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH luajit 1/2] memprof: refactor symbol resolution' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox