Skip to main content

memscope_rs/analysis/closure/
types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ClosureInfo {
6    pub ptr: usize,
7    pub captures: Vec<CaptureInfo>,
8    pub creation_timestamp: u64,
9    pub thread_id: String,
10    pub call_site: String,
11    pub memory_footprint: ClosureFootprint,
12    pub optimization_potential: OptimizationPotential,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct CaptureInfo {
17    pub var_name: String,
18    pub var_ptr: usize,
19    pub mode: CaptureMode,
20    pub var_type: String,
21    pub size: usize,
22    pub lifetime_bound: Option<String>,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
26pub enum CaptureMode {
27    ByValue,
28    ByReference,
29    ByMutableReference,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct ClosureFootprint {
34    pub total_size: usize,
35    pub capture_count: usize,
36    pub by_value_count: usize,
37    pub by_ref_count: usize,
38    pub by_mut_ref_count: usize,
39    pub estimated_heap_usage: usize,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct OptimizationPotential {
44    pub level: OptimizationLevel,
45    pub potential_savings: usize,
46    pub suggestions: Vec<String>,
47}
48
49#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
50pub enum OptimizationLevel {
51    None,
52    Low,
53    Medium,
54    High,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct CaptureEvent {
59    pub closure_ptr: usize,
60    pub captured_var: CaptureInfo,
61    pub event_type: CaptureEventType,
62    pub timestamp: u64,
63}
64
65#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
66pub enum CaptureEventType {
67    Captured,
68    Released,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct DetectedClosure {
73    pub ptr: usize,
74    pub type_name: String,
75    pub size: usize,
76    pub estimated_captures: usize,
77    pub closure_type: ClosureType,
78    pub creation_context: CreationContext,
79    pub memory_impact: MemoryImpact,
80}
81
82#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
83pub enum ClosureType {
84    Fn,
85    FnMut,
86    FnOnce,
87    Unknown,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct CreationContext {
92    pub scope_name: Option<String>,
93    pub thread_id: String,
94    pub timestamp: u64,
95}
96
97#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
98pub enum MemoryImpact {
99    Minimal,
100    Low,
101    Medium,
102    High,
103    VeryHigh,
104}
105
106#[derive(Debug, Clone, Default, Serialize, Deserialize)]
107pub struct CaptureStatistics {
108    pub total_closures: usize,
109    pub total_captures: usize,
110    pub avg_captures_per_closure: f64,
111    pub total_memory_usage: usize,
112    pub captures_by_mode: HashMap<CaptureMode, usize>,
113    pub captures_by_type: HashMap<String, usize>,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct OptimizationSuggestion {
118    pub category: OptimizationCategory,
119    pub priority: SuggestionPriority,
120    pub description: String,
121    pub recommendation: String,
122    pub estimated_impact: String,
123}
124
125#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
126pub enum OptimizationCategory {
127    Memory,
128    Performance,
129    Lifetime,
130}
131
132#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
133pub enum SuggestionPriority {
134    Low,
135    Medium,
136    High,
137    Critical,
138}
139
140#[derive(Debug)]
141pub struct LifetimeGraph {
142    relationships: HashMap<usize, Vec<LifetimeRelationship>>,
143}
144
145impl Default for LifetimeGraph {
146    fn default() -> Self {
147        Self::new()
148    }
149}
150
151impl LifetimeGraph {
152    pub fn new() -> Self {
153        Self {
154            relationships: HashMap::new(),
155        }
156    }
157
158    pub fn add_closure_relationships(&mut self, closure_ptr: usize, captures: &[CaptureInfo]) {
159        let relationships: Vec<LifetimeRelationship> = captures
160            .iter()
161            .map(|capture| LifetimeRelationship {
162                captured_var_ptr: capture.var_ptr,
163                capture_mode: capture.mode.clone(),
164                relationship_type: self.classify_relationship(&capture.mode),
165            })
166            .collect();
167
168        self.relationships.insert(closure_ptr, relationships);
169    }
170
171    pub fn remove_closure(&mut self, closure_ptr: usize) {
172        self.relationships.remove(&closure_ptr);
173    }
174
175    fn classify_relationship(&self, mode: &CaptureMode) -> RelationshipType {
176        match mode {
177            CaptureMode::ByValue => RelationshipType::Ownership,
178            CaptureMode::ByReference => RelationshipType::SharedBorrow,
179            CaptureMode::ByMutableReference => RelationshipType::ExclusiveBorrow,
180        }
181    }
182
183    pub fn analyze_lifetimes(&self) -> LifetimeAnalysis {
184        let mut potential_issues = Vec::new();
185        let mut lifetime_patterns = Vec::new();
186
187        for (closure_ptr, relationships) in &self.relationships {
188            let has_value_captures = relationships
189                .iter()
190                .any(|r| r.capture_mode == CaptureMode::ByValue);
191            let has_ref_captures = relationships.iter().any(|r| {
192                matches!(
193                    r.capture_mode,
194                    CaptureMode::ByReference | CaptureMode::ByMutableReference
195                )
196            });
197
198            if has_value_captures && has_ref_captures {
199                potential_issues.push(LifetimeIssue {
200                    closure_ptr: *closure_ptr,
201                    issue_type: LifetimeIssueType::MixedCaptureMode,
202                    description: "Closure mixes value and reference captures".to_string(),
203                    severity: IssueSeverity::Medium,
204                    suggestion: "Consider consistent capture strategy".to_string(),
205                });
206            }
207
208            if relationships.len() > 5 {
209                lifetime_patterns.push(LifetimePattern {
210                    pattern_type: LifetimePatternType::ManyCaptures,
211                    description: format!("Closure captures {} variables", relationships.len()),
212                    impact: if relationships.len() > 10 {
213                        PatternImpact::High
214                    } else {
215                        PatternImpact::Medium
216                    },
217                });
218            }
219        }
220
221        LifetimeAnalysis {
222            total_relationships: self.relationships.len(),
223            potential_issues,
224            lifetime_patterns,
225        }
226    }
227}
228
229#[derive(Debug, Clone)]
230pub struct LifetimeRelationship {
231    pub captured_var_ptr: usize,
232    pub capture_mode: CaptureMode,
233    pub relationship_type: RelationshipType,
234}
235
236#[derive(Debug, Clone, PartialEq)]
237pub enum RelationshipType {
238    Ownership,
239    SharedBorrow,
240    ExclusiveBorrow,
241}
242
243#[derive(Debug, Clone, Default, Serialize, Deserialize)]
244pub struct LifetimeAnalysis {
245    pub total_relationships: usize,
246    pub potential_issues: Vec<LifetimeIssue>,
247    pub lifetime_patterns: Vec<LifetimePattern>,
248}
249
250#[derive(Debug, Clone, Serialize, Deserialize)]
251pub struct LifetimeIssue {
252    pub closure_ptr: usize,
253    pub issue_type: LifetimeIssueType,
254    pub description: String,
255    pub severity: IssueSeverity,
256    pub suggestion: String,
257}
258
259#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
260pub enum LifetimeIssueType {
261    MixedCaptureMode,
262    PotentialDanglingReference,
263    UnnecessaryCapture,
264}
265
266#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
267pub enum IssueSeverity {
268    Low,
269    Medium,
270    High,
271    Critical,
272}
273
274#[derive(Debug, Clone, Serialize, Deserialize)]
275pub struct LifetimePattern {
276    pub pattern_type: LifetimePatternType,
277    pub description: String,
278    pub impact: PatternImpact,
279}
280
281#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
282pub enum LifetimePatternType {
283    ManyCaptures,
284    LongLivedClosure,
285    FrequentCreation,
286}
287
288#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
289pub enum PatternImpact {
290    Low,
291    Medium,
292    High,
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize)]
296pub struct ClosureAnalysisReport {
297    pub detected_closures: Vec<DetectedClosure>,
298    pub capture_statistics: CaptureStatistics,
299    pub optimization_suggestions: Vec<OptimizationSuggestion>,
300    pub lifetime_analysis: LifetimeAnalysis,
301    pub analysis_timestamp: u64,
302}