jetcrab\vm\heap/
garbage_collection.rs

1use crate::vm::handle::HeapHandleId;
2use super::entries::HeapEntry;
3use super::types::HeapMetrics;
4use std::collections::{HashSet, HashMap};
5use std::time::Instant;
6
7pub struct GarbageCollectorImpl {
8    metrics: HeapMetrics,
9    collection_count: usize,
10    total_collection_time: std::time::Duration,
11    last_collection_size: usize,
12}
13
14impl Clone for GarbageCollectorImpl {
15    fn clone(&self) -> Self {
16        Self {
17            metrics: self.metrics.clone(),
18            collection_count: self.collection_count,
19            total_collection_time: self.total_collection_time,
20            last_collection_size: self.last_collection_size,
21        }
22    }
23}
24
25impl GarbageCollectorImpl {
26    pub fn new() -> Self {
27        Self {
28            metrics: HeapMetrics::new(),
29            collection_count: 0,
30            total_collection_time: std::time::Duration::ZERO,
31            last_collection_size: 0,
32        }
33    }
34
35    pub fn get_metrics(&self) -> &HeapMetrics {
36        &self.metrics
37    }
38
39    pub fn get_metrics_mut(&mut self) -> &mut HeapMetrics {
40        &mut self.metrics
41    }
42
43    // Métodos auxiliares para compatibilidade
44    pub fn mark_and_sweep(&mut self, roots: &[HeapHandleId]) -> usize {
45        let marked = self.mark_phase(roots);
46        self.sweep_phase(&marked)
47    }
48
49    pub fn mark_phase(&mut self, roots: &[HeapHandleId]) -> HashSet<usize> {
50        let mut marked = HashSet::new();
51        let mut to_visit = Vec::new();
52        
53        // Add root objects to visit list
54        for root in roots {
55            to_visit.push(root.as_usize());
56        }
57        
58        // Mark reachable objects
59        while let Some(index) = to_visit.pop() {
60            if marked.insert(index) {
61                // Add referenced objects to visit list
62                // This is a simplified version - in practice, you'd traverse object references
63                if let Some(entry) = self.get_entry(index) {
64                    match entry {
65                        HeapEntry::Object(obj) => {
66                            // Add object property references
67                            for value in obj.values() {
68                                if let Some(handle) = self.extract_handle(value) {
69                                    to_visit.push(handle.as_usize());
70                                }
71                            }
72                        }
73                        HeapEntry::Array(arr) => {
74                            // Add array element references
75                            for value in arr {
76                                if let Some(handle) = self.extract_handle(value) {
77                                    to_visit.push(handle.as_usize());
78                                }
79                            }
80                        }
81                        HeapEntry::Function { closure_vars, .. } => {
82                            // Add closure variable references
83                            for value in closure_vars.values() {
84                                if let Some(handle) = self.extract_handle(value) {
85                                    to_visit.push(handle.as_usize());
86                                }
87                            }
88                        }
89                        _ => {}
90                    }
91                }
92            }
93        }
94        
95        marked
96    }
97
98    pub fn sweep_phase(&mut self, marked: &HashSet<usize>) -> usize {
99        let mut collected = 0;
100        
101        // This is a simplified sweep - in practice, you'd iterate through entries
102        // and remove unmarked ones
103        for index in 0..self.get_entry_count() {
104            if !marked.contains(&index) {
105                // Mark as deallocated
106                self.mark_as_deallocated(index);
107                collected += 1;
108            }
109        }
110        
111        collected
112    }
113}
114
115impl super::management::GarbageCollector for GarbageCollectorImpl {
116    fn collect_garbage(&mut self, _entries: &mut HashMap<HeapHandleId, HeapEntry>, roots: &[HeapHandleId]) -> usize {
117        let start_time = Instant::now();
118        let collected = self.mark_and_sweep(roots);
119        let duration = start_time.elapsed();
120        
121        self.collection_count += 1;
122        self.total_collection_time += duration;
123        self.last_collection_size = collected;
124        self.metrics.record_gc_cycle(duration);
125        
126        collected
127    }
128
129    fn get_collection_stats(&self) -> (usize, u32, u32) {
130        (
131            self.collection_count,
132            self.total_collection_time.as_millis() as u32,
133            self.last_collection_size as u32
134        )
135    }
136}
137
138impl Default for GarbageCollectorImpl {
139    fn default() -> Self {
140        Self::new()
141    }
142}
143
144// Helper methods that would be implemented in practice
145impl GarbageCollectorImpl {
146    fn get_entry(&self, _index: usize) -> Option<&HeapEntry> {
147        // This would access the actual heap entries
148        None
149    }
150    
151    fn get_entry_count(&self) -> usize {
152        // This would return the actual entry count
153        0
154    }
155    
156    fn mark_as_deallocated(&mut self, _index: usize) {
157        // This would mark an entry as deallocated
158    }
159    
160    fn extract_handle(&self, _value: &crate::vm::value::Value) -> Option<HeapHandleId> {
161        // This would extract heap handles from values
162        None
163    }
164}
165
166#[derive(Debug, Clone, Copy)]
167pub struct GarbageCollectionStats {
168    pub collection_count: usize,
169    pub total_collection_time: std::time::Duration,
170    pub last_collection_size: usize,
171    pub average_collection_time: std::time::Duration,
172}
173
174impl GarbageCollectionStats {
175    pub fn new() -> Self {
176        Self {
177            collection_count: 0,
178            total_collection_time: std::time::Duration::ZERO,
179            last_collection_size: 0,
180            average_collection_time: std::time::Duration::ZERO,
181        }
182    }
183}
184
185impl Default for GarbageCollectionStats {
186    fn default() -> Self {
187        Self::new()
188    }
189}