use crate::util::analysis::RtAnalysis;
use crate::util::statistics::counter::EventCounter;
use crate::util::statistics::stats::Stats;
use crate::vm::VMBinding;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
pub struct PerSizeClassObjectCounter {
running: bool,
size_classes: Mutex<HashMap<String, Arc<Mutex<EventCounter>>>>,
stats: Arc<Stats>,
}
macro_rules! new_ctr {
( $stats:expr, $map:expr, $size_class:expr ) => {{
let ctr = $stats.new_event_counter(&$size_class, true, true);
$map.insert($size_class.to_string(), ctr.clone());
ctr
}};
}
impl PerSizeClassObjectCounter {
pub fn new(running: bool, stats: Arc<Stats>) -> Self {
Self {
running,
size_classes: Mutex::new(HashMap::new()),
stats,
}
}
fn size_class(&self, size: usize) -> usize {
2_usize.pow(63_u32 - (size - 1).leading_zeros() + 1)
}
}
impl<VM: VMBinding> RtAnalysis<VM> for PerSizeClassObjectCounter {
fn alloc_hook(&mut self, size: usize, _align: usize, _offset: usize) {
if !self.running {
return;
}
let size_class = format!("size{}", self.size_class(size));
let mut size_classes = self.size_classes.lock().unwrap();
let c = size_classes.get_mut(&size_class);
match c {
None => {
let ctr = new_ctr!(self.stats, size_classes, size_class);
ctr.lock().unwrap().inc();
}
Some(ctr) => {
ctr.lock().unwrap().inc();
}
}
}
fn set_running(&mut self, running: bool) {
self.running = running;
}
}