memscope_rs/core/tracker/
memory_analysis.rs

1//! Memory layout and container analysis functionality.
2//!
3//! This module contains methods for analyzing memory layouts, container structures,
4//! and calculating efficiency metrics for different data types.
5
6use super::memory_tracker::MemoryTracker;
7use crate::core::types::{
8    AllocatorStateInfo, CachePerformanceInfo, CapacityUtilization, CodeBloatLevel,
9    ContainerAnalysis, ContainerEfficiencyMetrics, ContainerType,
10    ContextType::{AsyncContext, LocalVariable},
11    CpuUsageInfo, DispatchOverhead, DynamicTypeInfo, EnhancedFragmentationAnalysis,
12    FieldLayoutInfo, GenericConstraint, GenericTypeInfo, LayoutEfficiency, MemoryLayoutInfo,
13    MemoryPressureInfo, MonomorphizationInfo, PaddingAnalysis, PerformanceImpact,
14    ReallocationPatterns, RuntimeStateInfo, TypeErasureInfo, TypeParameter, TypeRelationshipInfo,
15    TypeUsageInfo, VTableInfo,
16};
17
18impl MemoryTracker {
19    /// Analyze memory layout information with enhanced container analysis
20    pub fn analyze_memory_layout(&self, type_name: &str, size: usize) -> Option<MemoryLayoutInfo> {
21        // Infer memory layout based on type name and size
22        let alignment = self.estimate_alignment(type_name, size);
23        let field_layout = self.analyze_enhanced_field_layout(type_name, size, alignment);
24        let padding_info = self.analyze_padding(&field_layout, size, alignment);
25        let layout_efficiency = self.calculate_enhanced_layout_efficiency(
26            &field_layout,
27            &padding_info,
28            size,
29            type_name,
30        );
31
32        // Perform container-specific analysis
33        let container_analysis = self.analyze_container_structure(type_name, size);
34
35        Some(MemoryLayoutInfo {
36            total_size: size,
37            alignment,
38            field_layout,
39            padding_info,
40            layout_efficiency,
41            container_analysis: Some(container_analysis),
42        })
43    }
44
45    /// Analyze memory fragmentation
46    pub fn analyze_memory_fragmentation(&self) -> EnhancedFragmentationAnalysis {
47        let stats = self.stats.lock().unwrap_or_else(|e| e.into_inner());
48
49        // Calculate basic fragmentation metrics
50        let total_allocated = stats.total_allocated;
51        let active_memory = stats.active_memory;
52        let peak_memory = stats.peak_memory;
53
54        // Calculate fragmentation ratio
55        let fragmentation_ratio = if peak_memory > 0 {
56            1.0 - (active_memory as f64 / peak_memory as f64)
57        } else {
58            0.0
59        };
60
61        // Determine severity level
62        let severity = if fragmentation_ratio > 0.5 {
63            crate::core::types::FragmentationSeverity::High
64        } else if fragmentation_ratio > 0.3 {
65            crate::core::types::FragmentationSeverity::Moderate
66        } else {
67            crate::core::types::FragmentationSeverity::Low
68        };
69
70        EnhancedFragmentationAnalysis {
71            total_heap_size: total_allocated,
72            used_heap_size: active_memory,
73            free_heap_size: total_allocated.saturating_sub(active_memory),
74            free_block_count: 0,                 // Placeholder
75            free_block_distribution: Vec::new(), // Placeholder
76            fragmentation_metrics: crate::core::types::FragmentationMetrics {
77                external_fragmentation: fragmentation_ratio,
78                internal_fragmentation: 0.0,  // Placeholder
79                largest_free_block: 0,        // Placeholder
80                average_free_block_size: 0.0, // Placeholder
81                severity_level: severity,
82            },
83            fragmentation_causes: Vec::new(), // Placeholder
84        }
85    }
86
87    /// Estimate type alignment requirements
88    fn estimate_alignment(&self, type_name: &str, size: usize) -> usize {
89        if type_name.contains("u64") || type_name.contains("i64") || type_name.contains("f64") {
90            8
91        } else if type_name.contains("u32")
92            || type_name.contains("i32")
93            || type_name.contains("f32")
94        {
95            4
96        } else if type_name.contains("u16") || type_name.contains("i16") {
97            2
98        } else if type_name.contains("u8") || type_name.contains("i8") || type_name.contains("bool")
99        {
100            1
101        } else if type_name.contains("usize")
102            || type_name.contains("isize")
103            || type_name.contains("*")
104        {
105            std::mem::size_of::<usize>()
106        } else {
107            // For composite types, use heuristic approach
108            match size {
109                1 => 1,
110                2..=3 => 2,
111                4..=7 => 4,
112                _ => 8,
113            }
114        }
115    }
116
117    /// Enhanced field layout analysis with container-specific insights
118    fn analyze_enhanced_field_layout(
119        &self,
120        type_name: &str,
121        total_size: usize,
122        alignment: usize,
123    ) -> Vec<FieldLayoutInfo> {
124        let mut fields = Vec::new();
125
126        if type_name.contains("Vec<") {
127            // Vec<T> typically contains: ptr, capacity, len
128            fields.push(FieldLayoutInfo {
129                field_name: "ptr".to_string(),
130                field_type: "*mut T".to_string(),
131                offset: 0,
132                size: std::mem::size_of::<usize>(),
133                alignment: std::mem::size_of::<usize>(),
134                is_padding: false,
135            });
136            fields.push(FieldLayoutInfo {
137                field_name: "capacity".to_string(),
138                field_type: "usize".to_string(),
139                offset: std::mem::size_of::<usize>(),
140                size: std::mem::size_of::<usize>(),
141                alignment: std::mem::size_of::<usize>(),
142                is_padding: false,
143            });
144            fields.push(FieldLayoutInfo {
145                field_name: "len".to_string(),
146                field_type: "usize".to_string(),
147                offset: 2 * std::mem::size_of::<usize>(),
148                size: std::mem::size_of::<usize>(),
149                alignment: std::mem::size_of::<usize>(),
150                is_padding: false,
151            });
152
153            // Add container-specific analysis
154            self.analyze_vec_container_efficiency(type_name, total_size, &mut fields);
155        } else if type_name == "String" {
156            // String is essentially Vec<u8> with UTF-8 guarantees
157            fields.push(FieldLayoutInfo {
158                field_name: "ptr".to_string(),
159                field_type: "*mut u8".to_string(),
160                offset: 0,
161                size: std::mem::size_of::<usize>(),
162                alignment: std::mem::size_of::<usize>(),
163                is_padding: false,
164            });
165            fields.push(FieldLayoutInfo {
166                field_name: "capacity".to_string(),
167                field_type: "usize".to_string(),
168                offset: std::mem::size_of::<usize>(),
169                size: std::mem::size_of::<usize>(),
170                alignment: std::mem::size_of::<usize>(),
171                is_padding: false,
172            });
173            fields.push(FieldLayoutInfo {
174                field_name: "len".to_string(),
175                field_type: "usize".to_string(),
176                offset: 2 * std::mem::size_of::<usize>(),
177                size: std::mem::size_of::<usize>(),
178                alignment: std::mem::size_of::<usize>(),
179                is_padding: false,
180            });
181
182            // Add string-specific analysis
183            self.analyze_string_efficiency(total_size, &mut fields);
184        } else {
185            // Fallback to basic analysis for unknown types
186            self.analyze_basic_field_layout(type_name, total_size, alignment, &mut fields);
187        }
188
189        fields
190    }
191
192    /// Analyze container structure for Vec, HashMap, Box, etc.
193    fn analyze_container_structure(&self, type_name: &str, size: usize) -> ContainerAnalysis {
194        let container_type = self.classify_container_type(type_name);
195        let capacity_utilization = self.analyze_capacity_utilization(&container_type, size);
196        let reallocation_patterns = self.detect_reallocation_patterns(&container_type, size);
197        let efficiency_metrics = self.calculate_container_efficiency_metrics(
198            &container_type,
199            size,
200            &capacity_utilization,
201            &reallocation_patterns,
202        );
203
204        ContainerAnalysis {
205            container_type,
206            capacity_utilization,
207            reallocation_patterns,
208            efficiency_metrics,
209        }
210    }
211
212    /// Calculate enhanced layout efficiency with container-specific insights
213    fn calculate_enhanced_layout_efficiency(
214        &self,
215        _fields: &[FieldLayoutInfo],
216        _padding_info: &PaddingAnalysis,
217        size: usize,
218        type_name: &str,
219    ) -> LayoutEfficiency {
220        // Calculate basic efficiency metrics
221        let padding_overhead = self.calculate_padding_overhead(_fields, size);
222        let memory_utilization = self.calculate_memory_utilization(size, padding_overhead);
223
224        // Container-specific efficiency adjustments
225        let container_efficiency = self.calculate_container_specific_efficiency(type_name, size);
226
227        // Calculate overall efficiency score
228        let overall_score = (memory_utilization + container_efficiency) / 2.0;
229
230        LayoutEfficiency {
231            memory_utilization,
232            cache_friendliness: container_efficiency * 100.0, // Convert to 0-100 scale
233            alignment_waste: padding_overhead as usize,
234            optimization_potential: if overall_score < 0.5 {
235                crate::core::types::OptimizationPotential::Major {
236                    potential_savings: (padding_overhead * 0.8) as usize,
237                    suggestions: self.generate_efficiency_recommendations(overall_score, type_name),
238                }
239            } else if overall_score < 0.8 {
240                crate::core::types::OptimizationPotential::Moderate {
241                    potential_savings: (padding_overhead * 0.5) as usize,
242                    suggestions: self.generate_efficiency_recommendations(overall_score, type_name),
243                }
244            } else {
245                crate::core::types::OptimizationPotential::None
246            },
247        }
248    }
249
250    /// Analyze padding information
251    #[allow(unused)]
252    fn analyze_padding(
253        &self,
254        fields: &[FieldLayoutInfo],
255        total_size: usize,
256        _alignment: usize,
257    ) -> PaddingAnalysis {
258        let mut total_padding = 0;
259        let mut padding_locations = Vec::new();
260
261        // Calculate padding between fields
262        for i in 0..fields.len().saturating_sub(1) {
263            let current_end = fields[i].offset + fields[i].size;
264            let next_start = fields[i + 1].offset;
265            if next_start > current_end {
266                let padding_size = next_start - current_end;
267                total_padding += padding_size;
268                padding_locations.push((current_end, padding_size));
269            }
270        }
271
272        // Calculate trailing padding
273        if let Some(last_field) = fields.last() {
274            let last_end = last_field.offset + last_field.size;
275            if total_size > last_end {
276                let trailing_padding = total_size - last_end;
277                total_padding += trailing_padding;
278                padding_locations.push((last_end, trailing_padding));
279            }
280        }
281
282        PaddingAnalysis {
283            total_padding_bytes: total_padding,
284            padding_locations: padding_locations
285                .into_iter()
286                .map(|(offset, size)| crate::core::types::PaddingLocation {
287                    start_offset: offset,
288                    size,
289                    reason: crate::core::types::PaddingReason::FieldAlignment,
290                })
291                .collect(),
292            padding_ratio: if total_size > 0 {
293                total_padding as f64 / total_size as f64
294            } else {
295                0.0
296            },
297            optimization_suggestions: vec![
298                "Consider reordering fields by size (largest first)".to_string(),
299                "Use #[repr(packed)] for space-critical structs".to_string(),
300            ],
301        }
302    }
303
304    // Private helper methods
305
306    /// Classify container type based on type name
307    fn classify_container_type(&self, type_name: &str) -> ContainerType {
308        if type_name.contains("Vec<") {
309            ContainerType::Vec {
310                element_type: "T".to_string(), // Placeholder
311                element_size: 8,               // Placeholder
312            }
313        } else if type_name.contains("HashMap<") {
314            ContainerType::HashMap {
315                key_type: "K".to_string(),   // Placeholder
316                value_type: "V".to_string(), // Placeholder
317                key_size: 8,                 // Placeholder
318                value_size: 8,               // Placeholder
319            }
320        } else if type_name.contains("BTreeMap<") {
321            ContainerType::BTreeMap {
322                key_type: "K".to_string(),   // Placeholder
323                value_type: "V".to_string(), // Placeholder
324                key_size: 8,                 // Placeholder
325                value_size: 8,               // Placeholder
326            }
327        } else if type_name.contains("Box<") {
328            ContainerType::Box {
329                boxed_type: "T".to_string(), // Placeholder
330                boxed_size: 8,               // Placeholder
331            }
332        } else if type_name == "String" {
333            ContainerType::String
334        } else {
335            ContainerType::Other {
336                type_name: type_name.to_string(),
337            }
338        }
339    }
340
341    /// Analyze capacity utilization for containers
342    fn analyze_capacity_utilization(
343        &self,
344        container_type: &ContainerType,
345        size: usize,
346    ) -> CapacityUtilization {
347        // This is a simplified implementation
348        // In a real implementation, you would track actual capacity vs length
349        let estimated_utilization = match container_type {
350            ContainerType::Vec { .. } | ContainerType::String => {
351                // Assume 75% utilization for dynamic arrays
352                0.75
353            }
354            ContainerType::HashMap { .. } => {
355                // HashMap typically maintains ~75% load factor
356                0.75
357            }
358            ContainerType::Box { .. } => {
359                // Box is always 100% utilized
360                1.0
361            }
362            _ => 0.5, // Default assumption
363        };
364
365        CapacityUtilization {
366            current_capacity: (size as f64 / estimated_utilization) as usize,
367            current_length: size,
368            utilization_ratio: estimated_utilization,
369            wasted_space: ((1.0 - estimated_utilization) * size as f64) as usize,
370            efficiency_assessment: if estimated_utilization > 0.9 {
371                crate::core::types::UtilizationEfficiency::Excellent
372            } else if estimated_utilization > 0.7 {
373                crate::core::types::UtilizationEfficiency::Good
374            } else if estimated_utilization > 0.5 {
375                crate::core::types::UtilizationEfficiency::Fair
376            } else {
377                crate::core::types::UtilizationEfficiency::Poor {
378                    suggestion: "Consider using a more appropriate container size".to_string(),
379                }
380            },
381        }
382    }
383
384    /// Detect reallocation patterns
385    fn detect_reallocation_patterns(
386        &self,
387        container_type: &ContainerType,
388        _size: usize,
389    ) -> ReallocationPatterns {
390        // This is a placeholder implementation
391        // In a real implementation, you would track allocation history
392        ReallocationPatterns {
393            frequency_assessment: match container_type {
394                ContainerType::Vec { .. } | ContainerType::String => {
395                    crate::core::types::ReallocationFrequency::Moderate
396                }
397                ContainerType::HashMap { .. } => crate::core::types::ReallocationFrequency::Low,
398                ContainerType::Box { .. } => crate::core::types::ReallocationFrequency::None,
399                _ => crate::core::types::ReallocationFrequency::Low,
400            },
401            growth_pattern: crate::core::types::GrowthPattern::Exponential,
402            estimated_reallocations: 2, // Placeholder
403            optimization_suggestions: vec![
404                "Consider pre-allocating capacity if size is known".to_string()
405            ],
406        }
407    }
408
409    /// Calculate container-specific efficiency metrics
410    fn calculate_container_efficiency_metrics(
411        &self,
412        container_type: &ContainerType,
413        _size: usize,
414        capacity_utilization: &CapacityUtilization,
415        _reallocation_patterns: &ReallocationPatterns,
416    ) -> ContainerEfficiencyMetrics {
417        let access_efficiency = match container_type {
418            ContainerType::Vec { .. } | ContainerType::String => 0.95, // O(1) access
419            ContainerType::HashMap { .. } => 0.85,                     // Average O(1) access
420            ContainerType::BTreeMap { .. } => 0.75,                    // O(log n) access
421            ContainerType::Box { .. } => 1.0,                          // Direct access
422            _ => 0.5,
423        };
424
425        let memory_overhead = match container_type {
426            ContainerType::Vec { .. } | ContainerType::String => 0.1, // 10% overhead
427            ContainerType::HashMap { .. } => 0.25,                    // 25% overhead for hash table
428            ContainerType::BTreeMap { .. } => 0.15, // 15% overhead for tree structure
429            ContainerType::Box { .. } => 0.05,      // Minimal overhead
430            _ => 0.2,
431        };
432
433        ContainerEfficiencyMetrics {
434            memory_overhead,
435            cache_efficiency: access_efficiency * 100.0,
436            access_efficiency: crate::core::types::AccessEfficiency::Sequential, // Placeholder
437            health_score: (access_efficiency
438                + capacity_utilization.utilization_ratio
439                + (1.0 - memory_overhead))
440                / 3.0
441                * 100.0,
442        }
443    }
444
445    // Additional helper methods (placeholder implementations)
446
447    fn analyze_vec_container_efficiency(
448        &self,
449        type_name: &str,
450        total_size: usize,
451        fields: &mut Vec<FieldLayoutInfo>,
452    ) {
453        // Extract element type from Vec<T>
454        let element_type = if let Some(start) = type_name.find('<') {
455            if let Some(end) = type_name.rfind('>') {
456                &type_name[start + 1..end]
457            } else {
458                "T"
459            }
460        } else {
461            "T"
462        };
463
464        // Estimate element size
465        let element_size = self.estimate_type_size(element_type);
466
467        // Add efficiency analysis as a virtual field
468        fields.push(FieldLayoutInfo {
469            field_name: "efficiency_analysis".to_string(),
470            field_type: format!("VecEfficiency<{element_type}>"),
471            offset: 0, // Virtual field
472            size: 0,   // Virtual field
473            alignment: 1,
474            is_padding: false,
475        });
476
477        // Add capacity utilization insight
478        let estimated_capacity = if total_size > 24 {
479            // Vec header is ~24 bytes
480            (total_size - 24) / element_size.max(1)
481        } else {
482            0
483        };
484
485        if estimated_capacity > 0 {
486            fields.push(FieldLayoutInfo {
487                field_name: "capacity_analysis".to_string(),
488                field_type: format!("EstimatedCapacity: {estimated_capacity}"),
489                offset: 0, // Virtual field
490                size: 0,   // Virtual field
491                alignment: 1,
492                is_padding: false,
493            });
494        }
495    }
496
497    fn analyze_string_efficiency(&self, total_size: usize, fields: &mut Vec<FieldLayoutInfo>) {
498        // String is essentially Vec<u8>, so similar analysis
499        let estimated_capacity = total_size.saturating_sub(24);
500
501        fields.push(FieldLayoutInfo {
502            field_name: "string_analysis".to_string(),
503            field_type: format!("StringCapacity: {estimated_capacity} bytes"),
504            offset: 0, // Virtual field
505            size: 0,   // Virtual field
506            alignment: 1,
507            is_padding: false,
508        });
509
510        // Add UTF-8 efficiency note
511        fields.push(FieldLayoutInfo {
512            field_name: "encoding_info".to_string(),
513            field_type: "UTF-8 encoded".to_string(),
514            offset: 0, // Virtual field
515            size: 0,   // Virtual field
516            alignment: 1,
517            is_padding: false,
518        });
519    }
520
521    fn analyze_basic_field_layout(
522        &self,
523        type_name: &str,
524        total_size: usize,
525        alignment: usize,
526        fields: &mut Vec<FieldLayoutInfo>,
527    ) {
528        // For unknown types, create a basic single-field layout
529        fields.push(FieldLayoutInfo {
530            field_name: "data".to_string(),
531            field_type: type_name.to_string(),
532            offset: 0,
533            size: total_size,
534            alignment,
535            is_padding: false,
536        });
537
538        // Add alignment padding if necessary
539        let aligned_size = (total_size + alignment - 1) & !(alignment - 1);
540        if aligned_size > total_size {
541            fields.push(FieldLayoutInfo {
542                field_name: "tail_padding".to_string(),
543                field_type: "padding".to_string(),
544                offset: total_size,
545                size: aligned_size - total_size,
546                alignment: 1,
547                is_padding: true,
548            });
549        }
550    }
551
552    fn calculate_padding_overhead(&self, fields: &[FieldLayoutInfo], size: usize) -> f64 {
553        let total_padding: usize = fields
554            .iter()
555            .filter(|field| field.is_padding)
556            .map(|field| field.size)
557            .sum();
558
559        if size > 0 {
560            total_padding as f64 / size as f64
561        } else {
562            0.0
563        }
564    }
565
566    fn calculate_memory_utilization(&self, size: usize, padding_overhead: f64) -> f64 {
567        if size > 0 {
568            1.0 - padding_overhead
569        } else {
570            0.0
571        }
572    }
573
574    fn calculate_container_specific_efficiency(&self, type_name: &str, size: usize) -> f64 {
575        match type_name {
576            name if name.contains("Vec<") => {
577                // Vec efficiency depends on capacity utilization
578                if size > 24 {
579                    0.85 // Good efficiency for dynamic arrays
580                } else {
581                    0.6 // Lower efficiency for small vectors
582                }
583            }
584            name if name.contains("HashMap<") => {
585                // HashMap efficiency depends on load factor
586                if size > 48 {
587                    0.75 // Reasonable efficiency for hash tables
588                } else {
589                    0.5 // Lower efficiency for small hash maps
590                }
591            }
592            name if name.contains("Box<") => 1.0, // Box is always efficient
593            "String" => {
594                if size > 24 {
595                    0.9 // Good efficiency for strings
596                } else {
597                    0.7 // Lower efficiency for small strings
598                }
599            }
600            _ => 0.8, // Default efficiency
601        }
602    }
603
604    fn generate_efficiency_recommendations(&self, score: f64, type_name: &str) -> Vec<String> {
605        let mut recommendations = Vec::new();
606
607        if score < 0.5 {
608            recommendations.push(
609                "Consider significant restructuring for better memory efficiency".to_string(),
610            );
611        }
612
613        if type_name.contains("Vec<") {
614            if score < 0.8 {
615                recommendations.push(
616                    "Consider pre-allocating Vec capacity with Vec::with_capacity()".to_string(),
617                );
618                recommendations
619                    .push("Use Vec::shrink_to_fit() to reduce unused capacity".to_string());
620            }
621        } else if type_name.contains("HashMap<") {
622            if score < 0.7 {
623                recommendations
624                    .push("Consider pre-sizing HashMap with HashMap::with_capacity()".to_string());
625                recommendations.push(
626                    "Evaluate if BTreeMap might be more efficient for your use case".to_string(),
627                );
628            }
629        } else if type_name == "String" && score < 0.8 {
630            recommendations
631                .push("Consider using String::with_capacity() for known string sizes".to_string());
632            recommendations.push("Use &str instead of String when possible".to_string());
633        }
634
635        if score < 0.6 {
636            recommendations
637                .push("Consider using #[repr(packed)] for space-critical structs".to_string());
638            recommendations.push(
639                "Reorder struct fields by size (largest first) to minimize padding".to_string(),
640            );
641        }
642
643        if recommendations.is_empty() {
644            recommendations.push("Memory layout is already well optimized".to_string());
645        }
646
647        recommendations
648    }
649
650    /// Estimate type size based on type name
651    pub(crate) fn estimate_type_size(&self, type_name: &str) -> usize {
652        match type_name {
653            "u8" | "i8" | "bool" => 1,
654            "u16" | "i16" => 2,
655            "u32" | "i32" | "f32" => 4,
656            "u64" | "i64" | "f64" => 8,
657            "usize" | "isize" => std::mem::size_of::<usize>(),
658            "String" => 24, // Vec-like structure
659            name if name.starts_with("Vec<") => 24,
660            name if name.starts_with("HashMap<") => 48,
661            name if name.starts_with("Box<") => std::mem::size_of::<usize>(),
662            _ => 8, // Default estimate
663        }
664    }
665
666    /// Analyze generic type information
667    pub fn analyze_generic_type(&self, type_name: &str, size: usize) -> Option<GenericTypeInfo> {
668        if !type_name.contains('<') || !type_name.contains('>') {
669            return None; // Not a generic type
670        }
671
672        let base_type = self.extract_base_type(type_name);
673        let type_parameters = self.extract_type_parameters(type_name, size);
674        let monomorphization_info = self.analyze_monomorphization(&base_type, &type_parameters);
675        let constraints = self.infer_generic_constraints(&base_type, &type_parameters);
676
677        Some(GenericTypeInfo {
678            base_type,
679            type_parameters,
680            monomorphization_info,
681            constraints,
682        })
683    }
684
685    /// Analyze dynamic type information (trait objects)
686    pub fn analyze_dynamic_type(&self, type_name: &str, size: usize) -> Option<DynamicTypeInfo> {
687        if !type_name.contains("dyn ") && !type_name.contains("Box<dyn") {
688            return None; // Not a trait object
689        }
690
691        let trait_name = self.extract_trait_name(type_name);
692        let vtable_info = self.analyze_vtable(&trait_name, size);
693        let concrete_type = self.try_infer_concrete_type(type_name);
694        let dispatch_overhead = self.calculate_dispatch_overhead(&trait_name);
695        let type_erasure_info = self.analyze_type_erasure(size);
696
697        Some(DynamicTypeInfo {
698            trait_name,
699            vtable_info,
700            concrete_type,
701            dispatch_overhead,
702            type_erasure_info,
703        })
704    }
705
706    /// Collect runtime state information
707    pub fn collect_runtime_state(&self) -> RuntimeStateInfo {
708        RuntimeStateInfo {
709            cpu_usage: self.collect_cpu_usage(),
710            memory_pressure: self.assess_memory_pressure(),
711            cache_performance: self.estimate_cache_performance(),
712            allocator_state: self.analyze_allocator_state(),
713            gc_info: None, // Rust doesn't have GC
714        }
715    }
716
717    fn extract_base_type(&self, type_name: &str) -> String {
718        if let Some(pos) = type_name.find('<') {
719            type_name[..pos].to_string()
720        } else {
721            type_name.to_string()
722        }
723    }
724
725    fn extract_trait_name(&self, type_name: &str) -> String {
726        if type_name.contains("dyn ") {
727            if let Some(start) = type_name.find("dyn ") {
728                let after_dyn = &type_name[start + 4..];
729                if let Some(end) = after_dyn.find('>') {
730                    after_dyn[..end].trim().to_string()
731                } else {
732                    after_dyn.trim().to_string()
733                }
734            } else {
735                "Unknown".to_string()
736            }
737        } else {
738            "Unknown".to_string()
739        }
740    }
741
742    /// Collect CPU usage information
743    fn collect_cpu_usage(&self) -> CpuUsageInfo {
744        // In actual implementation, this would call system APIs to get real CPU usage
745        CpuUsageInfo {
746            current_usage_percent: 15.0, // Simulated value
747            average_usage_percent: 12.0,
748            peak_usage_percent: 25.0,
749            intensive_operations_count: 100,
750        }
751    }
752
753    /// Assess memory pressure
754    fn assess_memory_pressure(&self) -> MemoryPressureInfo {
755        let stats = self.stats.lock().unwrap_or_else(|e| e.into_inner());
756        let pressure_level = if stats.active_memory > 1024 * 1024 * 100 {
757            // > 100MB
758            crate::core::types::MemoryPressureLevel::High
759        } else if stats.active_memory > 1024 * 1024 * 50 {
760            // > 50MB
761            crate::core::types::MemoryPressureLevel::Moderate
762        } else {
763            crate::core::types::MemoryPressureLevel::Low
764        };
765
766        MemoryPressureInfo {
767            pressure_level,
768            available_memory_percent: 75.0, // Simulated value
769            allocation_failures: 0,
770            fragmentation_level: stats.fragmentation_analysis.fragmentation_ratio,
771        }
772    }
773
774    /// Estimate cache performance
775    fn estimate_cache_performance(&self) -> CachePerformanceInfo {
776        CachePerformanceInfo {
777            l1_hit_rate: 0.95,
778            l2_hit_rate: 0.85,
779            l3_hit_rate: 0.70,
780            cache_miss_penalty_ns: 100.0,
781            access_pattern: crate::core::types::MemoryAccessPattern::Mixed,
782        }
783    }
784
785    /// Analyze type relationships
786    pub fn analyze_type_relationships(&self, type_name: &str) -> Option<TypeRelationshipInfo> {
787        Some(TypeRelationshipInfo {
788            type_name: type_name.to_string(),
789            parent_types: vec![],
790            child_types: vec![],
791            composed_types: vec![],
792            complexity_score: self.calculate_type_complexity(type_name),
793            inheritance_depth: 0,
794            composition_breadth: 0,
795        })
796    }
797
798    /// Calculate type complexity score
799    fn calculate_type_complexity(&self, type_name: &str) -> u32 {
800        let mut score = 1;
801        if type_name.contains('<') {
802            score += 2;
803        }
804        if type_name.contains("dyn") {
805            score += 3;
806        }
807        if type_name.contains("impl") {
808            score += 2;
809        }
810        score += type_name.matches(',').count() as u32;
811        score
812    }
813
814    /// Track type usage with enhanced statistics collection
815    pub fn track_type_usage(&self, type_name: &str) -> Option<TypeUsageInfo> {
816        // Get active allocations to analyze type usage patterns
817        let active_allocations = match self.get_active_allocations() {
818            Ok(allocations) => allocations,
819            Err(_) => return None, // Skip if lock is contended
820        };
821
822        // Calculate type usage statistics from current allocations
823        let mut type_count = 0u64;
824        let mut total_size = 0usize;
825        let mut allocation_timestamps = Vec::new();
826        let mut allocation_sizes = Vec::new();
827
828        // Analyze current allocations for this type
829        for allocation in &active_allocations {
830            if let Some(ref alloc_type) = allocation.type_name {
831                if alloc_type == type_name {
832                    type_count += 1;
833                    total_size += allocation.size;
834                    allocation_timestamps.push(allocation.timestamp_alloc);
835                    allocation_sizes.push(allocation.size);
836                }
837            }
838        }
839
840        // If no allocations found for this type, return basic info
841        if type_count == 0 {
842            return Some(TypeUsageInfo {
843                type_name: type_name.to_string(),
844                total_usage_count: 1,
845                usage_contexts: vec![],
846                usage_timeline: vec![],
847                hot_paths: vec![],
848                performance_impact: self.calculate_basic_performance_impact(type_name),
849            });
850        }
851
852        // Create usage timeline from allocation timestamps
853        let usage_timeline = self.create_usage_timeline(&allocation_timestamps, &allocation_sizes);
854
855        // Analyze usage contexts based on type characteristics
856        let usage_contexts = self.analyze_usage_contexts(type_name, type_count, total_size);
857
858        // Calculate performance impact based on usage patterns
859        let performance_impact = self.calculate_type_performance_impact(
860            type_name,
861            type_count,
862            total_size,
863            &allocation_sizes,
864        );
865
866        Some(TypeUsageInfo {
867            type_name: type_name.to_string(),
868            total_usage_count: type_count,
869            usage_contexts,
870            usage_timeline,
871            hot_paths: vec![], // Hot path analysis would require more complex profiling
872            performance_impact,
873        })
874    }
875
876    /// Generate optimization recommendations based on type characteristics
877    fn generate_optimization_recommendations(
878        &self,
879        type_name: &str,
880    ) -> Vec<crate::core::types::OptimizationRecommendation> {
881        let mut recommendations = Vec::new();
882
883        match type_name {
884            "String" => {
885                recommendations.push(crate::core::types::OptimizationRecommendation {
886                    recommendation_type:
887                        crate::core::types::RecommendationType::DataStructureChange,
888                    priority: crate::core::types::Priority::Medium,
889                    description: "Consider using &str when possible to avoid allocations"
890                        .to_string(),
891                    expected_improvement: 15.0,
892                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
893                });
894                recommendations.push(crate::core::types::OptimizationRecommendation {
895                    recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
896                    priority: crate::core::types::Priority::Medium,
897                    description: "Use String::with_capacity() when final size is known".to_string(),
898                    expected_improvement: 20.0,
899                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
900                });
901            }
902            name if name.starts_with("Vec<") => {
903                recommendations.push(crate::core::types::OptimizationRecommendation {
904                    recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
905                    priority: crate::core::types::Priority::High,
906                    description: "Use Vec::with_capacity() when size is predictable".to_string(),
907                    expected_improvement: 25.0,
908                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
909                });
910                recommendations.push(crate::core::types::OptimizationRecommendation {
911                    recommendation_type:
912                        crate::core::types::RecommendationType::DataStructureChange,
913                    priority: crate::core::types::Priority::Low,
914                    description: "Consider using SmallVec for small collections".to_string(),
915                    expected_improvement: 10.0,
916                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Medium,
917                });
918            }
919            name if name.starts_with("HashMap<") => {
920                recommendations.push(crate::core::types::OptimizationRecommendation {
921                    recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
922                    priority: crate::core::types::Priority::High,
923                    description: "Use HashMap::with_capacity() for better performance".to_string(),
924                    expected_improvement: 30.0,
925                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
926                });
927                recommendations.push(crate::core::types::OptimizationRecommendation {
928                    recommendation_type:
929                        crate::core::types::RecommendationType::DataStructureChange,
930                    priority: crate::core::types::Priority::Medium,
931                    description:
932                        "Consider using FxHashMap for better performance with integer keys"
933                            .to_string(),
934                    expected_improvement: 15.0,
935                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Medium,
936                });
937            }
938            name if name.starts_with("Box<") => {
939                recommendations.push(crate::core::types::OptimizationRecommendation {
940                    recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
941                    priority: crate::core::types::Priority::Low,
942                    description: "Box is efficient for heap allocation of single values"
943                        .to_string(),
944                    expected_improvement: 5.0,
945                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
946                });
947            }
948            name if name.starts_with("Rc<") => {
949                recommendations.push(crate::core::types::OptimizationRecommendation {
950                    recommendation_type:
951                        crate::core::types::RecommendationType::DataStructureChange,
952                    priority: crate::core::types::Priority::Medium,
953                    description: "Consider Arc<> for thread-safe reference counting".to_string(),
954                    expected_improvement: 0.0, // No performance improvement, just thread safety
955                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
956                });
957                recommendations.push(crate::core::types::OptimizationRecommendation {
958                    recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
959                    priority: crate::core::types::Priority::High,
960                    description: "Be aware of potential reference cycles".to_string(),
961                    expected_improvement: 0.0, // Prevents memory leaks
962                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Medium,
963                });
964            }
965            name if name.starts_with("Arc<") => {
966                recommendations.push(crate::core::types::OptimizationRecommendation {
967                    recommendation_type:
968                        crate::core::types::RecommendationType::DataStructureChange,
969                    priority: crate::core::types::Priority::Low,
970                    description: "Arc has atomic overhead - use Rc if single-threaded".to_string(),
971                    expected_improvement: 10.0,
972                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
973                });
974                recommendations.push(crate::core::types::OptimizationRecommendation {
975                    recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
976                    priority: crate::core::types::Priority::Medium,
977                    description: "Consider weak references to break cycles".to_string(),
978                    expected_improvement: 0.0, // Prevents memory leaks
979                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Medium,
980                });
981            }
982            _ => {
983                recommendations.push(crate::core::types::OptimizationRecommendation {
984                    recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
985                    priority: crate::core::types::Priority::Low,
986                    description: "Consider the memory layout and access patterns".to_string(),
987                    expected_improvement: 5.0,
988                    implementation_difficulty: crate::core::types::ImplementationDifficulty::Medium,
989                });
990            }
991        }
992
993        recommendations
994    }
995
996    /// help functions
997    /// Calculate performance impact based on actual usage patterns
998    fn calculate_type_performance_impact(
999        &self,
1000        type_name: &str,
1001        usage_count: u64,
1002        total_size: usize,
1003        allocation_sizes: &[usize],
1004    ) -> crate::core::types::TypePerformanceImpact {
1005        let avg_size = if usage_count > 0 {
1006            total_size as f64 / usage_count as f64
1007        } else {
1008            0.0
1009        };
1010
1011        // Calculate size variance to detect allocation patterns
1012        let size_variance = if allocation_sizes.len() > 1 {
1013            let mean = avg_size;
1014            let variance = allocation_sizes
1015                .iter()
1016                .map(|&size| (size as f64 - mean).powi(2))
1017                .sum::<f64>()
1018                / allocation_sizes.len() as f64;
1019            variance.sqrt()
1020        } else {
1021            0.0
1022        };
1023
1024        // Base scores on type characteristics
1025        let mut base_scores = self.calculate_basic_performance_impact(type_name);
1026
1027        // Adjust scores based on usage patterns
1028
1029        // High usage count might indicate performance bottlenecks
1030        if usage_count > 1000 {
1031            base_scores.performance_score *= 0.9; // Reduce performance score
1032            base_scores.cpu_efficiency_score *= 0.95;
1033        }
1034
1035        // Large average size might indicate memory inefficiency
1036        if avg_size > 1024.0 * 1024.0 {
1037            // > 1MB
1038            base_scores.memory_efficiency_score *= 0.8;
1039            base_scores.cache_efficiency_score *= 0.7;
1040        }
1041
1042        // High size variance might indicate inefficient allocation patterns
1043        if size_variance > avg_size * 0.5 {
1044            base_scores.memory_efficiency_score *= 0.9;
1045        }
1046
1047        // Add specific recommendations based on analysis
1048        let mut recommendations = base_scores.optimization_recommendations;
1049
1050        if usage_count > 100 && avg_size < 64.0 {
1051            recommendations.push(crate::core::types::OptimizationRecommendation {
1052                recommendation_type: crate::core::types::RecommendationType::MemoryPooling,
1053                priority: crate::core::types::Priority::High,
1054                description:
1055                    "Consider using object pooling for small, frequently allocated objects"
1056                        .to_string(),
1057                expected_improvement: 25.0,
1058                implementation_difficulty: crate::core::types::ImplementationDifficulty::Medium,
1059            });
1060        }
1061
1062        if size_variance > avg_size {
1063            recommendations.push(crate::core::types::OptimizationRecommendation {
1064                recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
1065                priority: crate::core::types::Priority::High,
1066                description:
1067                    "Consider pre-allocating with estimated capacity to reduce reallocations"
1068                        .to_string(),
1069                expected_improvement: 30.0,
1070                implementation_difficulty: crate::core::types::ImplementationDifficulty::Easy,
1071            });
1072        }
1073
1074        if total_size > 10 * 1024 * 1024 {
1075            // > 10MB total
1076            recommendations.push(crate::core::types::OptimizationRecommendation {
1077                recommendation_type: crate::core::types::RecommendationType::MemoryLayout,
1078                priority: crate::core::types::Priority::Critical,
1079                description:
1080                    "Consider memory usage optimization - this type uses significant memory"
1081                        .to_string(),
1082                expected_improvement: 40.0,
1083                implementation_difficulty: crate::core::types::ImplementationDifficulty::Hard,
1084            });
1085        }
1086
1087        crate::core::types::TypePerformanceImpact {
1088            performance_score: base_scores.performance_score,
1089            memory_efficiency_score: base_scores.memory_efficiency_score,
1090            cpu_efficiency_score: base_scores.cpu_efficiency_score,
1091            cache_efficiency_score: base_scores.cache_efficiency_score,
1092            optimization_recommendations: recommendations,
1093        }
1094    }
1095
1096    /// Calculate basic performance impact for types with no allocation data
1097    fn calculate_basic_performance_impact(
1098        &self,
1099        type_name: &str,
1100    ) -> crate::core::types::TypePerformanceImpact {
1101        // Provide reasonable defaults based on type characteristics
1102        let (perf_score, mem_score, cpu_score, cache_score) = match type_name {
1103            "String" => (80.0, 85.0, 90.0, 75.0),
1104            name if name.starts_with("Vec<") => (85.0, 90.0, 85.0, 80.0),
1105            name if name.starts_with("HashMap<") => (75.0, 80.0, 70.0, 65.0),
1106            name if name.starts_with("Box<") => (90.0, 95.0, 95.0, 90.0),
1107            name if name.starts_with("Rc<") || name.starts_with("Arc<") => (85.0, 85.0, 80.0, 85.0),
1108            _ => (85.0, 90.0, 80.0, 75.0), // Default scores
1109        };
1110
1111        crate::core::types::TypePerformanceImpact {
1112            performance_score: perf_score,
1113            memory_efficiency_score: mem_score,
1114            cpu_efficiency_score: cpu_score,
1115            cache_efficiency_score: cache_score,
1116            optimization_recommendations: self.generate_optimization_recommendations(type_name),
1117        }
1118    }
1119
1120    /// Create usage timeline from allocation timestamps and sizes
1121    fn create_usage_timeline(
1122        &self,
1123        timestamps: &[u64],
1124        sizes: &[usize],
1125    ) -> Vec<crate::core::types::UsageTimePoint> {
1126        if timestamps.is_empty() {
1127            return vec![];
1128        }
1129
1130        // Group allocations by time windows (e.g., 1 second intervals)
1131        let mut timeline = Vec::new();
1132        let window_size_ns = 1_000_000_000; // 1 second in nanoseconds
1133
1134        if let (Some(&first_ts), Some(&last_ts)) = (timestamps.first(), timestamps.last()) {
1135            let mut current_window = first_ts;
1136
1137            while current_window <= last_ts {
1138                let window_end = current_window + window_size_ns;
1139
1140                // Count allocations and total memory in this window
1141                let mut usage_count = 0u32;
1142                let mut memory_usage = 0usize;
1143
1144                for (i, &ts) in timestamps.iter().enumerate() {
1145                    if ts >= current_window && ts < window_end {
1146                        usage_count += 1;
1147                        memory_usage += sizes[i];
1148                    }
1149                }
1150
1151                if usage_count > 0 {
1152                    timeline.push(crate::core::types::UsageTimePoint {
1153                        timestamp: current_window,
1154                        usage_count,
1155                        memory_usage,
1156                        performance_snapshot: crate::core::types::PerformanceSnapshot {
1157                            cpu_usage: 0.0, // Would need system profiling
1158                            memory_usage: memory_usage as f64,
1159                            cache_hit_rate: 0.95, // Estimated
1160                            throughput: usage_count as f64,
1161                        },
1162                    });
1163                }
1164
1165                current_window = window_end;
1166            }
1167        }
1168
1169        timeline
1170    }
1171
1172    /// Analyze usage contexts based on type characteristics
1173    fn analyze_usage_contexts(
1174        &self,
1175        type_name: &str,
1176        usage_count: u64,
1177        total_size: usize,
1178    ) -> Vec<crate::core::types::UsageContext> {
1179        let mut contexts = Vec::new();
1180
1181        // Infer context based on type name patterns
1182        let context_type = if type_name.starts_with("Vec<")
1183            || type_name.starts_with("HashMap<")
1184            || type_name.starts_with("BTreeMap<")
1185            || type_name.starts_with("Box<")
1186            || type_name.starts_with("Rc<")
1187            || type_name.starts_with("Arc<")
1188            || type_name == "String"
1189            || type_name.starts_with("&str")
1190        {
1191            LocalVariable
1192        } else if type_name.contains("Future") || type_name.contains("async") {
1193            AsyncContext
1194        } else {
1195            LocalVariable
1196        };
1197
1198        // Calculate performance metrics for this context
1199        let avg_size = if usage_count > 0 {
1200            total_size as f64 / usage_count as f64
1201        } else {
1202            0.0
1203        };
1204        let allocation_frequency = usage_count as f64; // Simplified
1205
1206        contexts.push(crate::core::types::UsageContext {
1207            context_type,
1208            location: "unknown".to_string(), // Would need stack trace analysis
1209            frequency: usage_count as u32,
1210            performance_metrics: crate::core::types::ContextPerformanceMetrics {
1211                avg_execution_time_ns: avg_size * 10.0, // Rough estimate
1212                allocation_frequency,
1213                cache_miss_rate: self.estimate_cache_miss_rate(type_name, avg_size),
1214                branch_misprediction_rate: 0.05, // Default estimate
1215            },
1216        });
1217
1218        contexts
1219    }
1220
1221    /// Estimate cache miss rate based on type and size characteristics
1222    fn estimate_cache_miss_rate(&self, type_name: &str, avg_size: f64) -> f64 {
1223        // Cache line size is typically 64 bytes
1224        let cache_line_size = 64.0;
1225
1226        if avg_size <= cache_line_size {
1227            0.05 // Low miss rate for small objects
1228        } else if avg_size <= cache_line_size * 4.0 {
1229            0.15 // Medium miss rate
1230        } else if type_name.starts_with("Vec<") || type_name.starts_with("HashMap<") {
1231            0.25 // Higher miss rate for large containers
1232        } else {
1233            0.35 // High miss rate for large objects
1234        }
1235    }
1236
1237    /// Analyze stack allocation information
1238    pub fn analyze_stack_allocation(
1239        &self,
1240        type_name: &str,
1241        ptr: usize,
1242    ) -> Option<crate::core::types::StackAllocationInfo> {
1243        // Heuristic: if pointer is in typical stack range, consider it stack allocation
1244        let stack_start = 0x7fff_0000_0000; // Typical stack start on x64
1245        let stack_end = 0x7fff_ffff_ffff; // Typical stack end on x64
1246
1247        if ptr >= stack_start && ptr <= stack_end {
1248            Some(crate::core::types::StackAllocationInfo {
1249                frame_id: (ptr >> 12) & 0xffff, // Use high bits as frame ID
1250                var_name: "stack_var".to_string(),
1251                stack_offset: (ptr as isize) - (stack_start as isize),
1252                size: self.estimate_type_size(type_name),
1253                function_name: "unknown_function".to_string(),
1254                stack_depth: self.estimate_stack_depth(ptr),
1255                scope_info: crate::core::types::StackScopeInfo {
1256                    scope_type: crate::core::types::ScopeType::Function,
1257                    start_line: None,
1258                    end_line: None,
1259                    parent_scope: None,
1260                    nesting_level: 1,
1261                },
1262            })
1263        } else {
1264            None
1265        }
1266    }
1267
1268    /// Estimate stack depth based on pointer address
1269    fn estimate_stack_depth(&self, ptr: usize) -> usize {
1270        let stack_start = 0x7fff_0000_0000;
1271        if ptr >= stack_start {
1272            ((ptr - stack_start) / 4096).min(100) // Estimate based on 4KB frames
1273        } else {
1274            0
1275        }
1276    }
1277
1278    /// Extract generic type parameters
1279    fn extract_type_parameters(&self, type_name: &str, total_size: usize) -> Vec<TypeParameter> {
1280        let mut parameters = Vec::new();
1281
1282        if let Some(start) = type_name.find('<') {
1283            if let Some(end) = type_name.rfind('>') {
1284                let params_str = &type_name[start + 1..end];
1285                let param_names: Vec<&str> = params_str.split(',').map(|s| s.trim()).collect();
1286
1287                for (i, param_name) in param_names.iter().enumerate() {
1288                    let estimated_size = self.estimate_type_parameter_size(
1289                        param_name,
1290                        total_size,
1291                        param_names.len(),
1292                    );
1293                    parameters.push(TypeParameter {
1294                        name: format!("T{i}"),
1295                        concrete_type: param_name.to_string(),
1296                        size: estimated_size,
1297                        alignment: self.estimate_alignment(param_name, estimated_size),
1298                        is_lifetime: param_name.starts_with('\''),
1299                    });
1300                }
1301            }
1302        }
1303
1304        parameters
1305    }
1306
1307    /// Analyze virtual function table
1308    fn analyze_vtable(&self, trait_name: &str, _size: usize) -> VTableInfo {
1309        let method_count = match trait_name {
1310            "Display" | "Debug" => 1,
1311            "Iterator" => 2,
1312            "Clone" => 1,
1313            "Drop" => 1,
1314            _ => 3, // Default estimate
1315        };
1316
1317        let vtable_size =
1318            method_count * std::mem::size_of::<usize>() + std::mem::size_of::<usize>(); // Method pointers + type info
1319        let methods = (0..method_count)
1320            .map(|i| crate::core::types::VTableMethod {
1321                name: format!("method_{i}"),
1322                signature: "fn(&self) -> ()".to_string(),
1323                vtable_offset: i * std::mem::size_of::<usize>(),
1324            })
1325            .collect();
1326
1327        VTableInfo {
1328            vtable_size,
1329            method_count,
1330            vtable_ptr_offset: 0,
1331            methods,
1332        }
1333    }
1334
1335    /// Try to infer concrete type
1336    fn try_infer_concrete_type(&self, type_name: &str) -> Option<String> {
1337        // In actual implementation, this might need more complex type inference logic
1338        if type_name.contains("String") {
1339            Some("String".to_string())
1340        } else if type_name.contains("Vec") {
1341            Some("Vec<T>".to_string())
1342        } else {
1343            None
1344        }
1345    }
1346
1347    /// Calculate dynamic dispatch overhead
1348    fn calculate_dispatch_overhead(&self, trait_name: &str) -> DispatchOverhead {
1349        let indirect_call_overhead_ns = match trait_name {
1350            "Display" | "Debug" => 2.0, // Simple trait
1351            "Iterator" => 3.0,
1352            _ => 5.0, // Complex trait
1353        };
1354
1355        DispatchOverhead {
1356            indirect_call_overhead_ns,
1357            cache_miss_probability: 0.1,     // 10% cache miss
1358            branch_misprediction_rate: 0.05, // 5% branch misprediction
1359            performance_impact: if indirect_call_overhead_ns > 4.0 {
1360                PerformanceImpact::Moderate
1361            } else {
1362                PerformanceImpact::Minor
1363            },
1364        }
1365    }
1366
1367    /// Analyze type erasure information
1368    fn analyze_type_erasure(&self, size: usize) -> TypeErasureInfo {
1369        TypeErasureInfo {
1370            type_info_recoverable: false, // trait objects typically cannot recover original type
1371            size_info: Some(size),
1372            alignment_info: Some(std::mem::size_of::<usize>()), // Usually aligned to pointer size
1373            destructor_info: Some("dynamic".to_string()),
1374        }
1375    }
1376
1377    /// Analyze monomorphization information
1378    fn analyze_monomorphization(
1379        &self,
1380        _base_type: &str,
1381        parameters: &[TypeParameter],
1382    ) -> MonomorphizationInfo {
1383        // Estimate monomorphization instance count (based on parameter complexity)
1384        let instance_count = parameters
1385            .iter()
1386            .map(|p| if p.concrete_type.contains('<') { 2 } else { 1 })
1387            .product::<usize>()
1388            .max(1);
1389
1390        let per_instance_memory = parameters.iter().map(|p| p.size).sum::<usize>();
1391        let total_memory_usage = instance_count * per_instance_memory;
1392
1393        let code_bloat_assessment = match instance_count {
1394            1..=2 => CodeBloatLevel::Low,
1395            3..=5 => CodeBloatLevel::Moderate,
1396            6..=10 => CodeBloatLevel::High,
1397            _ => CodeBloatLevel::Excessive,
1398        };
1399
1400        MonomorphizationInfo {
1401            instance_count,
1402            per_instance_memory,
1403            total_memory_usage,
1404            code_bloat_assessment,
1405        }
1406    }
1407
1408    /// Infer generic constraints
1409    fn infer_generic_constraints(
1410        &self,
1411        _base_type: &str,
1412        _parameters: &[TypeParameter],
1413    ) -> Vec<GenericConstraint> {
1414        let mut constraints = Vec::new();
1415
1416        match _base_type {
1417            "Vec" | "HashMap" | "BTreeMap" => {
1418                constraints.push(GenericConstraint {
1419                    constraint_type: crate::core::types::ConstraintType::Trait("Clone".to_string()),
1420                    description: "Element types typically need to implement Clone".to_string(),
1421                    memory_impact: crate::core::types::MemoryImpact::None,
1422                });
1423            }
1424            "Rc" | "Arc" => {
1425                constraints.push(GenericConstraint {
1426                    constraint_type: crate::core::types::ConstraintType::Trait(
1427                        "Send + Sync".to_string(),
1428                    ),
1429                    description: "Shared pointer contents need to be thread-safe".to_string(),
1430                    memory_impact: crate::core::types::MemoryImpact::SizeIncrease(
1431                        std::mem::size_of::<usize>(),
1432                    ),
1433                });
1434            }
1435            _ => {}
1436        }
1437
1438        constraints
1439    }
1440
1441    /// Analyze allocator state
1442    fn analyze_allocator_state(&self) -> AllocatorStateInfo {
1443        let stats = self.stats.lock().unwrap_or_else(|e| e.into_inner());
1444
1445        AllocatorStateInfo {
1446            allocator_type: "System".to_string(),
1447            heap_size: 1024 * 1024 * 1024, // 1GB simulated value
1448            heap_used: stats.active_memory,
1449            free_blocks_count: 1000,         // Simulated value
1450            largest_free_block: 1024 * 1024, // 1MB
1451            efficiency_score: 0.85,
1452        }
1453    }
1454
1455    /// Estimate generic parameter size
1456    fn estimate_type_parameter_size(
1457        &self,
1458        param_type: &str,
1459        total_size: usize,
1460        param_count: usize,
1461    ) -> usize {
1462        if param_type.starts_with('\'') {
1463            return 0; // Lifetime parameters don't take up space
1464        }
1465
1466        match param_type {
1467            "u8" | "i8" | "bool" => 1,
1468            "u16" | "i16" => 2,
1469            "u32" | "i32" | "f32" => 4,
1470            "u64" | "i64" | "f64" => 8,
1471            "usize" | "isize" => std::mem::size_of::<usize>(),
1472            _ => {
1473                // For complex types, evenly distribute total size
1474                if param_count > 0 {
1475                    total_size / param_count
1476                } else {
1477                    std::mem::size_of::<usize>()
1478                }
1479            }
1480        }
1481    }
1482}
1483
1484#[cfg(test)]
1485mod tests {
1486    use crate::core::tracker::memory_tracker::MemoryTracker;
1487    use crate::core::types::*;
1488
1489    fn create_test_tracker() -> MemoryTracker {
1490        MemoryTracker::new()
1491    }
1492
1493    #[test]
1494    fn test_estimate_alignment() {
1495        let tracker = create_test_tracker();
1496
1497        // Test primitive type alignments
1498        assert_eq!(tracker.estimate_alignment("u64", 8), 8);
1499        assert_eq!(tracker.estimate_alignment("i64", 8), 8);
1500        assert_eq!(tracker.estimate_alignment("f64", 8), 8);
1501        assert_eq!(tracker.estimate_alignment("u32", 4), 4);
1502        assert_eq!(tracker.estimate_alignment("i32", 4), 4);
1503        assert_eq!(tracker.estimate_alignment("f32", 4), 4);
1504        assert_eq!(tracker.estimate_alignment("u16", 2), 2);
1505        assert_eq!(tracker.estimate_alignment("i16", 2), 2);
1506        assert_eq!(tracker.estimate_alignment("u8", 1), 1);
1507        assert_eq!(tracker.estimate_alignment("i8", 1), 1);
1508        assert_eq!(tracker.estimate_alignment("bool", 1), 1);
1509
1510        // Test pointer types
1511        assert_eq!(
1512            tracker.estimate_alignment("usize", 8),
1513            std::mem::size_of::<usize>()
1514        );
1515        assert_eq!(
1516            tracker.estimate_alignment("isize", 8),
1517            std::mem::size_of::<usize>()
1518        );
1519        assert_eq!(
1520            tracker.estimate_alignment("*const T", 8),
1521            std::mem::size_of::<usize>()
1522        );
1523
1524        // Test composite types with size heuristics
1525        assert_eq!(tracker.estimate_alignment("SomeStruct", 1), 1);
1526        assert_eq!(tracker.estimate_alignment("SomeStruct", 3), 2);
1527        assert_eq!(tracker.estimate_alignment("SomeStruct", 7), 4);
1528        assert_eq!(tracker.estimate_alignment("SomeStruct", 16), 8);
1529    }
1530
1531    #[test]
1532    fn test_estimate_type_size() {
1533        let tracker = create_test_tracker();
1534
1535        // Test primitive types
1536        assert_eq!(tracker.estimate_type_size("u8"), 1);
1537        assert_eq!(tracker.estimate_type_size("i8"), 1);
1538        assert_eq!(tracker.estimate_type_size("bool"), 1);
1539        assert_eq!(tracker.estimate_type_size("u16"), 2);
1540        assert_eq!(tracker.estimate_type_size("i16"), 2);
1541        assert_eq!(tracker.estimate_type_size("u32"), 4);
1542        assert_eq!(tracker.estimate_type_size("i32"), 4);
1543        assert_eq!(tracker.estimate_type_size("f32"), 4);
1544        assert_eq!(tracker.estimate_type_size("u64"), 8);
1545        assert_eq!(tracker.estimate_type_size("i64"), 8);
1546        assert_eq!(tracker.estimate_type_size("f64"), 8);
1547        assert_eq!(
1548            tracker.estimate_type_size("usize"),
1549            std::mem::size_of::<usize>()
1550        );
1551        assert_eq!(
1552            tracker.estimate_type_size("isize"),
1553            std::mem::size_of::<usize>()
1554        );
1555
1556        // Test container types
1557        assert_eq!(tracker.estimate_type_size("String"), 24);
1558        assert_eq!(tracker.estimate_type_size("Vec<i32>"), 24);
1559        assert_eq!(tracker.estimate_type_size("HashMap<String, i32>"), 48);
1560        assert_eq!(
1561            tracker.estimate_type_size("Box<i32>"),
1562            std::mem::size_of::<usize>()
1563        );
1564
1565        // Test unknown types
1566        assert_eq!(tracker.estimate_type_size("UnknownType"), 8);
1567    }
1568
1569    #[test]
1570    fn test_analyze_memory_layout() {
1571        let tracker = create_test_tracker();
1572
1573        // Test Vec layout analysis
1574        let vec_layout = tracker.analyze_memory_layout("Vec<i32>", 24);
1575        assert!(vec_layout.is_some());
1576        let layout = vec_layout.unwrap();
1577        assert_eq!(layout.total_size, 24);
1578        assert_eq!(layout.alignment, 4); // Vec<i32> alignment should be 4 for i32
1579        assert_eq!(layout.field_layout.len(), 4); // ptr, capacity, len, efficiency_analysis
1580        assert!(layout.container_analysis.is_some());
1581
1582        // Test String layout analysis
1583        let string_layout = tracker.analyze_memory_layout("String", 24);
1584        assert!(string_layout.is_some());
1585        let layout = string_layout.unwrap();
1586        assert_eq!(layout.total_size, 24);
1587        assert_eq!(layout.field_layout.len(), 5); // ptr, capacity, len + 2 string fields
1588
1589        // Test unknown type layout
1590        let unknown_layout = tracker.analyze_memory_layout("UnknownType", 16);
1591        assert!(unknown_layout.is_some());
1592        let layout = unknown_layout.unwrap();
1593        assert_eq!(layout.total_size, 16);
1594        assert!(!layout.field_layout.is_empty());
1595    }
1596
1597    #[test]
1598    fn test_analyze_memory_fragmentation() {
1599        let tracker = create_test_tracker();
1600
1601        let fragmentation = tracker.analyze_memory_fragmentation();
1602
1603        // Test basic structure
1604        // Heap sizes are always >= 0 for usize types
1605        assert_eq!(fragmentation.free_block_count, 0); // Placeholder value
1606        assert!(fragmentation.free_block_distribution.is_empty()); // Placeholder
1607
1608        // Test fragmentation metrics
1609        assert!(fragmentation.fragmentation_metrics.external_fragmentation >= 0.0);
1610        assert!(fragmentation.fragmentation_metrics.external_fragmentation <= 1.0);
1611        assert_eq!(
1612            fragmentation.fragmentation_metrics.internal_fragmentation,
1613            0.0
1614        ); // Placeholder
1615
1616        // Test severity assessment
1617        match fragmentation.fragmentation_metrics.severity_level {
1618            FragmentationSeverity::Low
1619            | FragmentationSeverity::Moderate
1620            | FragmentationSeverity::High
1621            | FragmentationSeverity::Critical => {
1622                // All valid severity levels
1623            }
1624        }
1625    }
1626
1627    #[test]
1628    fn test_classify_container_type() {
1629        let tracker = create_test_tracker();
1630
1631        // Test Vec classification
1632        let vec_type = tracker.classify_container_type("Vec<i32>");
1633        match vec_type {
1634            ContainerType::Vec {
1635                element_type,
1636                element_size,
1637            } => {
1638                assert_eq!(element_type, "T");
1639                assert_eq!(element_size, 8);
1640            }
1641            _ => panic!("Expected Vec container type"),
1642        }
1643
1644        // Test HashMap classification
1645        let hashmap_type = tracker.classify_container_type("HashMap<String, i32>");
1646        match hashmap_type {
1647            ContainerType::HashMap {
1648                key_type,
1649                value_type,
1650                key_size,
1651                value_size,
1652            } => {
1653                assert_eq!(key_type, "K");
1654                assert_eq!(value_type, "V");
1655                assert_eq!(key_size, 8);
1656                assert_eq!(value_size, 8);
1657            }
1658            _ => panic!("Expected HashMap container type"),
1659        }
1660
1661        // Test Box classification
1662        let box_type = tracker.classify_container_type("Box<String>");
1663        match box_type {
1664            ContainerType::Box {
1665                boxed_type,
1666                boxed_size,
1667            } => {
1668                assert_eq!(boxed_type, "T");
1669                assert_eq!(boxed_size, 8);
1670            }
1671            _ => panic!("Expected Box container type"),
1672        }
1673
1674        // Test String classification
1675        let string_type = tracker.classify_container_type("String");
1676        match string_type {
1677            ContainerType::String => {
1678                // Correct classification
1679            }
1680            _ => panic!("Expected String container type"),
1681        }
1682
1683        // Test unknown type classification
1684        let other_type = tracker.classify_container_type("CustomStruct");
1685        match other_type {
1686            ContainerType::Other { type_name } => {
1687                assert_eq!(type_name, "CustomStruct");
1688            }
1689            _ => panic!("Expected Other container type"),
1690        }
1691    }
1692
1693    #[test]
1694    fn test_analyze_capacity_utilization() {
1695        let tracker = create_test_tracker();
1696
1697        // Test Vec capacity utilization
1698        let vec_type = ContainerType::Vec {
1699            element_type: "i32".to_string(),
1700            element_size: 4,
1701        };
1702        let utilization = tracker.analyze_capacity_utilization(&vec_type, 100);
1703
1704        assert!(utilization.current_capacity > 0);
1705        assert_eq!(utilization.current_length, 100);
1706        assert!(utilization.utilization_ratio > 0.0);
1707        assert!(utilization.utilization_ratio <= 1.0);
1708        // Wasted space is always >= 0 for usize
1709
1710        match utilization.efficiency_assessment {
1711            UtilizationEfficiency::Excellent
1712            | UtilizationEfficiency::Good
1713            | UtilizationEfficiency::Fair
1714            | UtilizationEfficiency::Poor { .. } => {
1715                // All valid efficiency levels
1716            }
1717        }
1718
1719        // Test Box capacity utilization (should be 100%)
1720        let box_type = ContainerType::Box {
1721            boxed_type: "i32".to_string(),
1722            boxed_size: 4,
1723        };
1724        let box_utilization = tracker.analyze_capacity_utilization(&box_type, 4);
1725        assert_eq!(box_utilization.utilization_ratio, 1.0);
1726    }
1727
1728    #[test]
1729    fn test_detect_reallocation_patterns() {
1730        let tracker = create_test_tracker();
1731
1732        // Test Vec reallocation patterns
1733        let vec_type = ContainerType::Vec {
1734            element_type: "i32".to_string(),
1735            element_size: 4,
1736        };
1737        let patterns = tracker.detect_reallocation_patterns(&vec_type, 100);
1738
1739        match patterns.frequency_assessment {
1740            ReallocationFrequency::None
1741            | ReallocationFrequency::Low
1742            | ReallocationFrequency::Moderate
1743            | ReallocationFrequency::High { .. } => {
1744                // All valid frequency levels
1745            }
1746        }
1747
1748        match patterns.growth_pattern {
1749            GrowthPattern::Exponential => {
1750                // Expected for Vec
1751            }
1752            _ => panic!("Expected exponential growth pattern for Vec"),
1753        }
1754
1755        // Estimated reallocations is always >= 0 for usize
1756        assert!(!patterns.optimization_suggestions.is_empty());
1757
1758        // Test Box reallocation patterns (should be None)
1759        let box_type = ContainerType::Box {
1760            boxed_type: "i32".to_string(),
1761            boxed_size: 4,
1762        };
1763        let box_patterns = tracker.detect_reallocation_patterns(&box_type, 4);
1764        match box_patterns.frequency_assessment {
1765            ReallocationFrequency::None => {
1766                // Expected for Box
1767            }
1768            _ => panic!("Expected no reallocations for Box"),
1769        }
1770    }
1771
1772    #[test]
1773    fn test_calculate_container_efficiency_metrics() {
1774        let tracker = create_test_tracker();
1775
1776        let vec_type = ContainerType::Vec {
1777            element_type: "i32".to_string(),
1778            element_size: 4,
1779        };
1780        let capacity_util = CapacityUtilization {
1781            current_capacity: 100,
1782            current_length: 75,
1783            utilization_ratio: 0.75,
1784            wasted_space: 25,
1785            efficiency_assessment: UtilizationEfficiency::Good,
1786        };
1787        let realloc_patterns = ReallocationPatterns {
1788            frequency_assessment: ReallocationFrequency::Moderate,
1789            growth_pattern: GrowthPattern::Exponential,
1790            estimated_reallocations: 2,
1791            optimization_suggestions: vec!["test".to_string()],
1792        };
1793
1794        let metrics = tracker.calculate_container_efficiency_metrics(
1795            &vec_type,
1796            100,
1797            &capacity_util,
1798            &realloc_patterns,
1799        );
1800
1801        assert!(metrics.memory_overhead >= 0.0);
1802        assert!(metrics.memory_overhead <= 1.0);
1803        assert!(metrics.cache_efficiency >= 0.0);
1804        assert!(metrics.cache_efficiency <= 100.0);
1805        assert!(metrics.health_score >= 0.0);
1806        assert!(metrics.health_score <= 100.0);
1807
1808        match metrics.access_efficiency {
1809            AccessEfficiency::Sequential => {
1810                // Expected placeholder value
1811            }
1812            _ => {
1813                // Other values are also valid
1814            }
1815        }
1816    }
1817
1818    #[test]
1819    fn test_analyze_generic_type() {
1820        let tracker = create_test_tracker();
1821
1822        // Test generic type analysis
1823        let generic_info = tracker.analyze_generic_type("Vec<String>", 24);
1824        assert!(generic_info.is_some());
1825        let info = generic_info.unwrap();
1826        assert_eq!(info.base_type, "Vec");
1827        assert!(!info.type_parameters.is_empty());
1828        assert!(!info.constraints.is_empty());
1829
1830        // Test non-generic type
1831        let non_generic = tracker.analyze_generic_type("String", 24);
1832        assert!(non_generic.is_none());
1833
1834        // Test complex generic type
1835        let complex_generic = tracker.analyze_generic_type("HashMap<String, Vec<i32>>", 48);
1836        assert!(complex_generic.is_some());
1837        let complex_info = complex_generic.unwrap();
1838        assert_eq!(complex_info.base_type, "HashMap");
1839        assert_eq!(complex_info.type_parameters.len(), 2);
1840    }
1841
1842    #[test]
1843    fn test_analyze_dynamic_type() {
1844        let tracker = create_test_tracker();
1845
1846        // Test trait object analysis
1847        let dyn_info = tracker.analyze_dynamic_type("Box<dyn Display>", 16);
1848        assert!(dyn_info.is_some());
1849        let info = dyn_info.unwrap();
1850        assert!(!info.trait_name.is_empty());
1851        assert!(info.vtable_info.method_count > 0);
1852        assert!(info.dispatch_overhead.indirect_call_overhead_ns > 0.0);
1853
1854        // Test non-dynamic type
1855        let non_dyn = tracker.analyze_dynamic_type("String", 24);
1856        assert!(non_dyn.is_none());
1857    }
1858
1859    #[test]
1860    fn test_collect_runtime_state() {
1861        let tracker = create_test_tracker();
1862
1863        let runtime_state = tracker.collect_runtime_state();
1864
1865        // Test CPU usage info
1866        assert!(runtime_state.cpu_usage.current_usage_percent >= 0.0);
1867        assert!(runtime_state.cpu_usage.current_usage_percent <= 100.0);
1868        assert!(runtime_state.cpu_usage.average_usage_percent >= 0.0);
1869        assert!(runtime_state.cpu_usage.peak_usage_percent >= 0.0);
1870        // Intensive operations count is always >= 0 for u64
1871
1872        // Test memory pressure info
1873        match runtime_state.memory_pressure.pressure_level {
1874            MemoryPressureLevel::Low
1875            | MemoryPressureLevel::Moderate
1876            | MemoryPressureLevel::High
1877            | MemoryPressureLevel::Critical => {
1878                // All valid pressure levels
1879            }
1880        }
1881        assert!(runtime_state.memory_pressure.available_memory_percent >= 0.0);
1882        assert!(runtime_state.memory_pressure.available_memory_percent <= 100.0);
1883        // Allocation failures is always >= 0 for u64
1884
1885        // Test cache performance info
1886        assert!(runtime_state.cache_performance.l1_hit_rate >= 0.0);
1887        assert!(runtime_state.cache_performance.l1_hit_rate <= 1.0);
1888        assert!(runtime_state.cache_performance.l2_hit_rate >= 0.0);
1889        assert!(runtime_state.cache_performance.l2_hit_rate <= 1.0);
1890        assert!(runtime_state.cache_performance.l3_hit_rate >= 0.0);
1891        assert!(runtime_state.cache_performance.l3_hit_rate <= 1.0);
1892        assert!(runtime_state.cache_performance.cache_miss_penalty_ns >= 0.0);
1893
1894        // Test allocator state
1895        assert!(!runtime_state.allocator_state.allocator_type.is_empty());
1896        assert!(runtime_state.allocator_state.heap_size > 0);
1897        // Allocator state values are always >= 0 for usize types
1898        assert!(runtime_state.allocator_state.efficiency_score >= 0.0);
1899        assert!(runtime_state.allocator_state.efficiency_score <= 1.0);
1900
1901        // Test GC info (should be None for Rust)
1902        assert!(runtime_state.gc_info.is_none());
1903    }
1904
1905    #[test]
1906    fn test_analyze_type_relationships() {
1907        let tracker = create_test_tracker();
1908
1909        let relationships = tracker.analyze_type_relationships("Vec<String>");
1910        assert!(relationships.is_some());
1911        let rel = relationships.unwrap();
1912        assert_eq!(rel.type_name, "Vec<String>");
1913        assert!(rel.complexity_score > 0);
1914        assert_eq!(rel.inheritance_depth, 0); // Rust doesn't have inheritance
1915        assert_eq!(rel.composition_breadth, 0);
1916    }
1917
1918    #[test]
1919    fn test_calculate_type_complexity() {
1920        let tracker = create_test_tracker();
1921
1922        // Test simple type
1923        let simple_complexity = tracker.calculate_type_complexity("String");
1924        assert_eq!(simple_complexity, 1);
1925
1926        // Test generic type
1927        let generic_complexity = tracker.calculate_type_complexity("Vec<String>");
1928        assert!(generic_complexity > 1);
1929
1930        // Test trait object
1931        let trait_complexity = tracker.calculate_type_complexity("Box<dyn Display>");
1932        assert!(trait_complexity > 2);
1933
1934        // Test impl trait
1935        let impl_complexity = tracker.calculate_type_complexity("impl Iterator<Item = String>");
1936        assert!(impl_complexity > 2);
1937
1938        // Test complex generic with multiple parameters
1939        let complex_complexity =
1940            tracker.calculate_type_complexity("HashMap<String, Vec<i32>, RandomState>");
1941        assert!(complex_complexity > 3);
1942    }
1943
1944    #[test]
1945    fn test_track_type_usage() {
1946        let tracker = create_test_tracker();
1947
1948        // Test type usage tracking
1949        let usage_info = tracker.track_type_usage("String");
1950        assert!(usage_info.is_some());
1951        let info = usage_info.unwrap();
1952        assert_eq!(info.type_name, "String");
1953        assert!(info.total_usage_count >= 1);
1954
1955        // Performance impact should have reasonable values
1956        assert!(info.performance_impact.performance_score >= 0.0);
1957        assert!(info.performance_impact.performance_score <= 100.0);
1958        assert!(info.performance_impact.memory_efficiency_score >= 0.0);
1959        assert!(info.performance_impact.memory_efficiency_score <= 100.0);
1960        assert!(info.performance_impact.cpu_efficiency_score >= 0.0);
1961        assert!(info.performance_impact.cpu_efficiency_score <= 100.0);
1962        assert!(info.performance_impact.cache_efficiency_score >= 0.0);
1963        assert!(info.performance_impact.cache_efficiency_score <= 100.0);
1964        assert!(!info
1965            .performance_impact
1966            .optimization_recommendations
1967            .is_empty());
1968    }
1969
1970    #[test]
1971    fn test_analyze_stack_allocation() {
1972        let tracker = create_test_tracker();
1973
1974        // Test with stack-like pointer
1975        let stack_ptr = 0x7fff_8000_0000;
1976        let stack_info = tracker.analyze_stack_allocation("i32", stack_ptr);
1977        assert!(stack_info.is_some());
1978        let info = stack_info.unwrap();
1979        // Frame ID is always >= 0 for usize
1980        assert_eq!(info.var_name, "stack_var");
1981        assert!(info.stack_offset >= 0);
1982        assert_eq!(info.size, 4); // i32 size
1983        assert_eq!(info.function_name, "unknown_function");
1984        // Stack depth is always >= 0 for usize
1985
1986        match info.scope_info.scope_type {
1987            ScopeType::Function => {
1988                // Expected scope type
1989            }
1990            _ => panic!("Expected function scope type"),
1991        }
1992
1993        // Test with non-stack pointer
1994        let heap_ptr = 0x1000_0000;
1995        let non_stack_info = tracker.analyze_stack_allocation("i32", heap_ptr);
1996        assert!(non_stack_info.is_none());
1997    }
1998
1999    #[test]
2000    fn test_estimate_stack_depth() {
2001        let tracker = create_test_tracker();
2002
2003        let stack_start = 0x7fff_0000_0000;
2004
2005        // Test various stack depths
2006        let depth1 = tracker.estimate_stack_depth(stack_start);
2007        assert_eq!(depth1, 0);
2008
2009        let depth2 = tracker.estimate_stack_depth(stack_start + 4096);
2010        assert_eq!(depth2, 1);
2011
2012        let depth3 = tracker.estimate_stack_depth(stack_start + 8192);
2013        assert_eq!(depth3, 2);
2014
2015        // Test non-stack pointer
2016        let non_stack_depth = tracker.estimate_stack_depth(0x1000_0000);
2017        assert_eq!(non_stack_depth, 0);
2018    }
2019
2020    #[test]
2021    fn test_extract_base_type() {
2022        let tracker = create_test_tracker();
2023
2024        assert_eq!(tracker.extract_base_type("Vec<String>"), "Vec");
2025        assert_eq!(tracker.extract_base_type("HashMap<K, V>"), "HashMap");
2026        assert_eq!(tracker.extract_base_type("String"), "String");
2027        assert_eq!(tracker.extract_base_type("Box<dyn Display>"), "Box");
2028    }
2029
2030    #[test]
2031    fn test_extract_trait_name() {
2032        let tracker = create_test_tracker();
2033
2034        assert_eq!(tracker.extract_trait_name("Box<dyn Display>"), "Display");
2035        assert_eq!(tracker.extract_trait_name("dyn Iterator"), "Iterator");
2036        assert_eq!(tracker.extract_trait_name("String"), "Unknown");
2037    }
2038
2039    #[test]
2040    fn test_estimate_cache_miss_rate() {
2041        let tracker = create_test_tracker();
2042
2043        // Test small objects (should have low miss rate)
2044        let small_miss_rate = tracker.estimate_cache_miss_rate("i32", 32.0);
2045        assert!(small_miss_rate <= 0.1);
2046
2047        // Test medium objects
2048        let medium_miss_rate = tracker.estimate_cache_miss_rate("SomeStruct", 128.0);
2049        assert!(medium_miss_rate > 0.1);
2050        assert!(medium_miss_rate <= 0.2);
2051
2052        // Test large containers
2053        let large_container_miss_rate = tracker.estimate_cache_miss_rate("Vec<i32>", 1024.0);
2054        assert!(large_container_miss_rate > 0.2);
2055        assert!(large_container_miss_rate <= 0.3);
2056
2057        // Test very large objects
2058        let very_large_miss_rate = tracker.estimate_cache_miss_rate("LargeStruct", 4096.0);
2059        assert!(very_large_miss_rate > 0.3);
2060    }
2061}