Skip to content

Commit 9305a03

Browse files
refactor: add helper functions for artifacts saving
1 parent 61b29d1 commit 9305a03

2 files changed

Lines changed: 204 additions & 155 deletions

File tree

src/executor/wall_time/perf/mod.rs

Lines changed: 14 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,27 @@ use crate::executor::helpers::run_with_sudo::run_with_sudo;
1010
use crate::executor::helpers::run_with_sudo::wrap_with_sudo;
1111
use crate::executor::shared::fifo::FifoBenchmarkData;
1212
use crate::executor::shared::fifo::RunnerFifo;
13-
use crate::executor::valgrind::helpers::ignored_objects_path::get_objects_path_to_ignore;
14-
use crate::executor::wall_time::perf::debug_info::debug_info_by_path;
1513
use crate::executor::wall_time::perf::jit_dump::harvest_perf_jit_for_pids;
1614
use crate::executor::wall_time::perf::perf_executable::get_working_perf_executable;
1715
use crate::prelude::*;
1816
use anyhow::Context;
1917
use fifo::PerfFifo;
20-
use libc::pid_t;
2118
use parse_perf_file::MemmapRecordsOutput;
2219
use perf_executable::get_compression_flags;
2320
use perf_executable::get_event_flags;
24-
use rayon::prelude::*;
2521
use runner_shared::artifacts::ArtifactExt;
2622
use runner_shared::artifacts::ExecutionTimestamps;
27-
use runner_shared::debug_info::DebugInfoPidMapping;
2823
use runner_shared::fifo::Command as FifoCommand;
2924
use runner_shared::fifo::IntegrationMode;
3025
use runner_shared::metadata::PerfMetadata;
31-
use runner_shared::perf_map::SymbolPidMapping;
32-
use runner_shared::unwind_data::UnwindDataPidMapping;
3326
use std::path::Path;
3427
use std::path::PathBuf;
35-
use std::{cell::OnceCell, collections::HashMap, process::ExitStatus};
28+
use std::{cell::OnceCell, process::ExitStatus};
3629

3730
mod jit_dump;
3831
mod naming;
3932
mod parse_perf_file;
33+
mod save_artifacts;
4034
mod setup;
4135

4236
pub mod debug_info;
@@ -337,112 +331,19 @@ impl BenchmarkData {
337331
.extend(mappings);
338332
}
339333

340-
// Assign a semantic key to each unique symbol path for on-disk filenames
341-
debug!("Saving symbols ({} unique entries)", symbols_by_path.len());
342-
let symbol_path_to_key: HashMap<&Path, String> = symbols_by_path
343-
.keys()
344-
.map(|path| {
345-
(
346-
path.as_path(),
347-
naming::path_to_semantic_key(&path.to_string_lossy()),
348-
)
349-
})
350-
.collect();
351-
352-
symbols_by_path.par_iter().for_each(|(path, module)| {
353-
let key = &symbol_path_to_key[path.as_path()];
354-
module.save_to(path_ref, key).unwrap();
355-
});
356-
357-
let symbol_pid_mappings_by_pid: HashMap<i32, Vec<SymbolPidMapping>> =
358-
pid_symbol_mappings_by_pid
359-
.iter()
360-
.map(|(pid, mappings)| {
361-
let converted = mappings
362-
.iter()
363-
.filter_map(|m| {
364-
Some(SymbolPidMapping {
365-
perf_map_key: symbol_path_to_key.get(m.path.as_path())?.clone(),
366-
load_bias: m.load_bias,
367-
})
368-
})
369-
.sorted_by_key(|m| m.perf_map_key.clone())
370-
.collect();
371-
(*pid, converted)
372-
})
373-
.collect();
374-
375-
// Collect debug info once per unique ELF path (deduplicated)
376-
debug!("Saving debug_info");
377-
let debug_info_by_elf_path = debug_info_by_path(&symbols_by_path);
378-
let (debug_info, debug_info_path_to_key): (HashMap<String, _>, HashMap<PathBuf, String>) = {
379-
let entries: Vec<_> = debug_info_by_elf_path.into_iter().collect();
380-
let key_map: HashMap<PathBuf, String> = entries
381-
.iter()
382-
.map(|(path, _)| {
383-
(
384-
path.clone(),
385-
naming::path_to_semantic_key(&path.to_string_lossy()),
386-
)
387-
})
388-
.collect();
389-
let infos: HashMap<String, _> = entries
390-
.into_iter()
391-
.map(|(path, info)| (naming::path_to_semantic_key(&path.to_string_lossy()), info))
392-
.collect();
393-
(infos, key_map)
394-
};
395-
let debug_info_pid_mappings_by_pid: HashMap<i32, Vec<DebugInfoPidMapping>> =
396-
pid_symbol_mappings_by_pid
397-
.iter()
398-
.map(|(pid, mappings)| {
399-
let converted = mappings
400-
.iter()
401-
.filter_map(|m| {
402-
Some(DebugInfoPidMapping {
403-
debug_info_key: debug_info_path_to_key.get(&m.path)?.clone(),
404-
load_bias: m.load_bias,
405-
})
406-
})
407-
.sorted_by_key(|m| m.debug_info_key.clone())
408-
.collect();
409-
(*pid, converted)
410-
})
411-
.collect();
412-
413-
// Assign a semantic key to each unique path for on-disk filenames,
414-
// then build the per-pid metadata referencing those keys.
415-
debug!(
416-
"Saving unwind data ({} unique entries)",
417-
unwind_data_by_path.len()
418-
);
419-
let unwind_path_to_key: HashMap<&str, String> = unwind_data_by_path
420-
.keys()
421-
.map(|path| (path.as_str(), naming::path_to_semantic_key(path)))
422-
.collect();
334+
let symbol_pid_mappings_by_pid =
335+
save_artifacts::save_symbols(path_ref, &symbols_by_path, &pid_symbol_mappings_by_pid);
423336

424-
unwind_data_by_path.par_iter().for_each(|(path, entry)| {
425-
let key = &unwind_path_to_key[path.as_str()];
426-
entry.save_to(path_ref, key).unwrap();
427-
});
337+
let (debug_info, debug_info_pid_mappings_by_pid) =
338+
save_artifacts::save_debug_info(&symbols_by_path, &pid_symbol_mappings_by_pid);
428339

429-
let unwind_data_pid_mappings_by_pid: HashMap<pid_t, Vec<UnwindDataPidMapping>> =
430-
pid_unwind_data_mappings_by_pid
431-
.into_iter()
432-
.map(|(pid, mappings)| {
433-
let converted = mappings
434-
.into_iter()
435-
.map(|m| UnwindDataPidMapping {
436-
unwind_data_key: unwind_path_to_key[m.path.as_str()].clone(),
437-
timestamp: m.timestamp,
438-
avma_range: m.avma_range,
439-
base_avma: m.base_avma,
440-
})
441-
.sorted_by_key(|m| m.unwind_data_key.clone())
442-
.collect();
443-
(pid, converted)
444-
})
445-
.collect();
340+
let unwind_data_pid_mappings_by_pid = save_artifacts::save_unwind_data(
341+
path_ref,
342+
&unwind_data_by_path,
343+
pid_unwind_data_mappings_by_pid,
344+
);
345+
346+
let ignored_modules = save_artifacts::collect_ignored_modules(&pid_symbol_mappings_by_pid);
446347

447348
debug!("Saving metadata");
448349
#[allow(deprecated)]
@@ -454,49 +355,7 @@ impl BenchmarkData {
454355
.clone()
455356
.ok_or(BenchmarkDataSaveError::MissingIntegration)?,
456357
uri_by_ts: self.marker_result.uri_by_ts.clone(),
457-
ignored_modules: {
458-
let mut to_ignore = vec![];
459-
460-
// Check if any of the ignored modules has been loaded in the process
461-
for ignore_path in get_objects_path_to_ignore() {
462-
let ignore_pathbuf = PathBuf::from(&ignore_path);
463-
for pid_mappings in pid_symbol_mappings_by_pid.values() {
464-
if let Some(m) = pid_mappings.iter().find(|m| m.path == ignore_pathbuf) {
465-
let (Some(&(base_addr, _)), Some(&(_, end_addr))) = (
466-
m.mappings.iter().min_by_key(|(base, _)| base),
467-
m.mappings.iter().max_by_key(|(_, end)| end),
468-
) else {
469-
continue;
470-
};
471-
472-
to_ignore.push((ignore_path.clone(), base_addr, end_addr));
473-
}
474-
}
475-
}
476-
477-
// When python is statically linked, we'll not find it in the ignored modules. Add it manually:
478-
for pid_mappings in pid_symbol_mappings_by_pid.values() {
479-
for m in pid_mappings {
480-
let is_python = m
481-
.path
482-
.file_name()
483-
.map(|name| name.to_string_lossy().starts_with("python"))
484-
.unwrap_or(false);
485-
if !is_python {
486-
continue;
487-
}
488-
let (Some(&(base_addr, _)), Some(&(_, end_addr))) = (
489-
m.mappings.iter().min_by_key(|(base, _)| base),
490-
m.mappings.iter().max_by_key(|(_, end)| end),
491-
) else {
492-
continue;
493-
};
494-
to_ignore.push((m.path.to_string_lossy().into(), base_addr, end_addr));
495-
}
496-
}
497-
498-
to_ignore
499-
},
358+
ignored_modules,
500359
markers: self.marker_result.markers.clone(),
501360
debug_info,
502361
debug_info_pid_mappings_by_pid,

0 commit comments

Comments
 (0)