1use std::collections::HashMap;
2pub struct Profiler {
3 backedges: HashMap<(usize, usize), u32>,
4 hot_spots: Vec<HotSpot>,
5}
6
7#[derive(Debug, Clone)]
8pub struct HotSpot {
9 pub function_idx: usize,
10 pub start_ip: usize,
11 pub iterations: u32,
12}
13
14impl Profiler {
15 pub fn new() -> Self {
16 Self {
17 backedges: HashMap::new(),
18 hot_spots: Vec::new(),
19 }
20 }
21
22 pub fn record_backedge(&mut self, func_idx: usize, ip: usize) -> u32 {
23 let count = self
24 .backedges
25 .entry((func_idx, ip))
26 .and_modify(|c| *c += 1)
27 .or_insert(1);
28 *count
29 }
30
31 pub fn is_hot(&self, func_idx: usize, ip: usize, threshold: u32) -> bool {
32 self.backedges
33 .get(&(func_idx, ip))
34 .map(|&count| count >= threshold)
35 .unwrap_or(false)
36 }
37
38 pub fn get_count(&self, func_idx: usize, ip: usize) -> u32 {
39 self.backedges.get(&(func_idx, ip)).copied().unwrap_or(0)
40 }
41
42 pub fn mark_hot(&mut self, func_idx: usize, ip: usize) {
43 let iterations = self.get_count(func_idx, ip);
44 self.hot_spots.push(HotSpot {
45 function_idx: func_idx,
46 start_ip: ip,
47 iterations,
48 });
49 }
50
51 pub fn hot_spots(&self) -> &[HotSpot] {
52 &self.hot_spots
53 }
54
55 pub fn reset(&mut self) {
56 self.backedges.clear();
57 self.hot_spots.clear();
58 }
59}
60
61impl Default for Profiler {
62 fn default() -> Self {
63 Self::new()
64 }
65}