mmtk/util/analysis/
mod.rs1use crate::scheduler::*;
2use crate::util::statistics::stats::Stats;
3use crate::vm::VMBinding;
4use crate::MMTK;
5use std::sync::{Arc, Mutex};
6
7pub mod gc_count;
8pub mod obj_num;
9pub mod obj_size;
10
11use self::gc_count::GcCounter;
12use self::obj_num::ObjectCounter;
13use self::obj_size::PerSizeClassObjectCounter;
14
15pub trait RtAnalysis<VM: VMBinding> {
26 fn alloc_hook(&mut self, _size: usize, _align: usize, _offset: usize) {}
27 fn gc_hook(&mut self, _mmtk: &'static MMTK<VM>) {}
28 fn set_running(&mut self, running: bool);
29}
30
31#[derive(Default)]
32pub struct GcHookWork;
33
34impl<VM: VMBinding> GCWork<VM> for GcHookWork {
35 fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
36 mmtk.analysis_manager.gc_hook(mmtk);
37 }
38}
39
40#[derive(Default)]
43pub struct AnalysisManager<VM: VMBinding> {
44 routines: Mutex<Vec<Arc<Mutex<dyn RtAnalysis<VM> + Send>>>>,
45}
46
47impl<VM: VMBinding> AnalysisManager<VM> {
48 pub fn new(stats: Arc<Stats>) -> Self {
49 let mut manager = AnalysisManager {
50 routines: Mutex::new(vec![]),
51 };
52 manager.initialize_routines(stats);
53 manager
54 }
55
56 fn initialize_routines(&mut self, stats: Arc<Stats>) {
59 let ctr = stats.new_event_counter("obj.num", true, true);
60 let gc_ctr = stats.new_event_counter("gc.num", true, true);
61 let obj_num = Arc::new(Mutex::new(ObjectCounter::new(true, ctr)));
62 let gc_count = Arc::new(Mutex::new(GcCounter::new(true, gc_ctr)));
63 let obj_size = Arc::new(Mutex::new(PerSizeClassObjectCounter::new(true, stats)));
64 self.add_analysis_routine(obj_num);
65 self.add_analysis_routine(gc_count);
66 self.add_analysis_routine(obj_size);
67 }
68
69 pub fn add_analysis_routine(&mut self, routine: Arc<Mutex<dyn RtAnalysis<VM> + Send>>) {
70 let mut routines = self.routines.lock().unwrap();
71 routines.push(routine.clone());
72 }
73
74 pub fn alloc_hook(&self, size: usize, align: usize, offset: usize) {
75 let routines = self.routines.lock().unwrap();
76 for r in &*routines {
77 r.lock().unwrap().alloc_hook(size, align, offset);
78 }
79 }
80
81 pub fn gc_hook(&self, mmtk: &'static MMTK<VM>) {
82 let routines = self.routines.lock().unwrap();
83 for r in &*routines {
84 r.lock().unwrap().gc_hook(mmtk);
85 }
86 }
87}