lust/jit/
profiler.rs

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