[Tarantool-patches] [PATCH luajit 1/2] memprof: refactor symbol resolution
Maxim Kokryashkin
max.kokryashkin at gmail.com
Mon Aug 28 18:23:35 MSK 2023
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
More information about the Tarantool-patches
mailing list