From 38e286c23815fb8b72a0aac4bf7ddfd406e27d89 Mon Sep 17 00:00:00 2001 From: Francisco Javier Honduvilla Coto Date: Tue, 11 Jun 2024 12:26:17 +0100 Subject: [PATCH] wip --- src/lib.rs | 1 + src/proto/profile.rs | 105 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b1878ae..cb3125c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,3 +8,4 @@ pub mod profiler; pub mod unwind_info; pub mod usym; pub mod util; +pub mod proto; diff --git a/src/proto/profile.rs b/src/proto/profile.rs index ff516bc..cad4500 100644 --- a/src/proto/profile.rs +++ b/src/proto/profile.rs @@ -1,22 +1,9 @@ include!(concat!(env!("OUT_DIR"), "/perftools.profiles.rs")); -/// Memory mapping. -impl Mapping { - fn new() -> Self { - Mapping { - id: 0, - memory_start: 0, - memory_limit: 0, - file_offset: 0, - filename: 0, - build_id: 0, - has_functions: false, - has_filenames: false, - has_line_numbers: false, - has_inline_frames: false, - } - } -} +use std::collections::HashSet; +use std::collections::HashMap; +use std::collections::hash_map::Entry; + /// Function and line. impl Location { fn new() -> Self { @@ -40,9 +27,14 @@ impl Sample { } } -impl Profile { - fn new() -> Self { - Profile { +struct Pprof { + known_mappings: HashSet, + mappings: Vec, + known_strings: HashMap, + string_table: Vec, +} + + /* Profile { sample_type: vec![], sample: vec![], mapping: vec![], @@ -57,8 +49,68 @@ impl Profile { period: 0, comment: vec![], default_sample_type: 0, + } */ + + +impl Pprof { + fn new() -> Self { + Self { + known_mappings: HashSet::new(), + mappings: Vec::new(), + known_strings: HashMap::new(), + string_table: Vec::new(), } } + + fn id_for_string(&mut self, string: &str) -> i64 { + // The first element in the string table must be the empty string. + if self.string_table.is_empty() { + self.known_strings.insert("".to_string(), 0); + self.string_table.push("".to_string()); + } + + match self.known_strings.entry(string.to_string()) { + Entry::Occupied(o) => { + return *o.get(); + }, + Entry::Vacant(v) => { + let len = self.string_table.len() as i64; + v.insert(len); + self.string_table.push(string.to_string()); + return len; + }, + } + + + } + + fn add_mapping(&mut self, id: u64, start: u64, end: u64, offset: u64, filename: &str, build_id: Option<&str>) { + let mapping = Mapping { + id: id, + memory_start: start, + memory_limit: end, + file_offset: offset, + filename: self.id_for_string(filename), + build_id: self.id_for_string(build_id), + has_functions: false, + has_filenames: false, + has_line_numbers: false, + has_inline_frames: false, + }; + + if !self.known_mappings.contains(&mapping.id) { + self.known_mappings.insert(mapping.id); + self.mappings.push(mapping); + } + } +/* fn add_sample(&mut self, raw_stack: &[u64], count: u64) { + let mut sample = Sample::new(); + // create location IDs + // for each location we need to create a mapping + + self.sample.push() + // + } */ } #[cfg(test)] @@ -66,7 +118,16 @@ mod tests { use super::*; #[test] - fn profile_validation() { - Profile::new() + fn test_string_table() { + let mut pprof = Pprof::new(); + assert_eq!(pprof.id_for_string("hi"), 1); + assert_eq!(pprof.id_for_string("salut"), 2); + assert_eq!(pprof.string_table, vec!["", "hi", "salut"]); + } + + #[test] + fn test_mappings() { + let mut pprof = Pprof::new(); + pprof.add_mapping(0, 0x100, 0x200, 0x0, "file.so", None); } }