Skip to content

Commit 1fcc070

Browse files
committed
For Cachegrind, aggregate all jemalloc functions into a single entry.
Because a single entry like this: ``` 120,365,108 (8.7%) <all-jemalloc-files>:<all-jemalloc-functions> ``` is much more helpful than dozens of entries like this: ``` 1,900,760 (0.9%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/include/jemalloc/internal/rtree.h:free 9,296,168 (0.7%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/include/jemalloc/internal/jemalloc_internal_inlines_c.h:malloc 7,926,636 (0.6%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/src/jemalloc.c:free 7,905,743 (0.6%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/include/jemalloc/internal/cache_bin.h:free 7,834,577 (0.6%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/include/jemalloc/internal/cache_bin.h:malloc 5,425,997 (0.4%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/src/arena.c:_rjem_je_arena_ralloc 4,268,616 (0.3%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/src/jemalloc.c:do_rallocx 3,539,679 (0.3%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/src/arena.c:_rjem_je_arena_ralloc_no_move 3,093,308 (0.2%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/include/jemalloc/internal/sz.h:malloc 2,393,337 (0.2%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/src/arena.c:_rjem_je_arena_cache_bin_fill_small 2,371,694 (0.2%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/include/jemalloc/internal/rtree.h:tcache_bin_flush_edatas_lookup.constprop.0 2,309,382 (0.2%) /home/njn/dev/rust2/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/build/jemalloc-sys-1e20251078fe5355/out/build/src/jemalloc.c:malloc ... ``` (And in reality, those jemalloc function entries are interleaved with many non-jemalloc entries, making them even harder to read.)
1 parent 3f38f44 commit 1fcc070

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

collector/src/execute/profiler.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::io::BufRead;
66
use std::io::Write;
77
use std::path::Path;
88
use std::process::Command;
9-
use std::{fs, process};
9+
use std::{fs, io, process};
1010

1111
// Tools usable with the profiling subcommands, and named on the command line.
1212
#[derive(Clone, Copy, Debug, PartialEq, clap::ValueEnum)]
@@ -226,7 +226,46 @@ impl<'a> Processor for ProfileProcessor<'a> {
226226
let cgout_file = filepath(self.output_dir, &out_file("cgout"));
227227
let cgann_file = filepath(self.output_dir, &out_file("cgann"));
228228

229-
fs::copy(&tmp_cgout_file, &cgout_file)?;
229+
// It's useful to filter all `file:function` entries from
230+
// jemalloc into a single fake
231+
// `<all-jemalloc-files>:<all-jemalloc-functions>` entry. That
232+
// way the cost of all allocations is visible in one line,
233+
// rather than spread across many small entries.
234+
//
235+
// The downside is that we don't get any annotations within
236+
// jemalloc source files, but this is no real loss, given that
237+
// jemalloc is basically a black box whose code we never look
238+
// at anyway. DHAT is the best way to profile allocations.
239+
let file = fs::File::open(&tmp_cgout_file)?;
240+
let reader = io::BufReader::new(file);
241+
let mut cgout = fs::File::create(&cgout_file).unwrap();
242+
let mut in_jemalloc_file = false;
243+
244+
// A Cachegrind profile contains `fn=<function-name>` lines,
245+
// `fl=<filename>` lines, and everything else. We just need to
246+
// modify the `fn=` and `fl=` lines that refer to jemalloc
247+
// code.
248+
for line in reader.lines() {
249+
let line = line?;
250+
if line.starts_with("fl=") {
251+
// All jemalloc filenames have `/jemalloc/` or
252+
// something like `/jemalloc-sys-1e20251078fe5355` in
253+
// them.
254+
in_jemalloc_file = line.contains("/jemalloc");
255+
if in_jemalloc_file {
256+
writeln!(cgout, "fl=<all-jemalloc-files>")?;
257+
continue;
258+
}
259+
} else if line.starts_with("fn=") {
260+
// Any function within a jemalloc file is a jemalloc
261+
// function.
262+
if in_jemalloc_file {
263+
writeln!(cgout, "fn=<all-jemalloc-functions>")?;
264+
continue;
265+
}
266+
}
267+
writeln!(cgout, "{}", line)?;
268+
}
230269

231270
let mut cg_annotate_cmd = Command::new("cg_annotate");
232271
cg_annotate_cmd

0 commit comments

Comments
 (0)