lust/jit/
profiler.rs

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}