jetcrab\vm\heap/
management.rs

1use super::entries::HeapEntry;
2use super::types::{HeapMetrics, HeapStats};
3use crate::vm::bytecode::Bytecode;
4use crate::vm::handle::HeapHandleId;
5use crate::vm::types::{ArgIndex, ArraySize, LocalIndex};
6use crate::vm::value::Value;
7use std::collections::HashMap;
8
9pub trait HeapAllocator {
10    fn allocate(&mut self, entry: HeapEntry) -> HeapHandleId;
11    fn deallocate(&mut self, handle: HeapHandleId) -> bool;
12    fn get(&self, handle: HeapHandleId) -> Option<&HeapEntry>;
13    fn get_mut(&mut self, handle: HeapHandleId) -> Option<&mut HeapEntry>;
14    fn get_entries(&self) -> &HashMap<HeapHandleId, HeapEntry>;
15    fn get_entries_mut(&mut self) -> &mut HashMap<HeapHandleId, HeapEntry>;
16    fn size(&self) -> usize;
17    fn is_empty(&self) -> bool;
18    fn clear(&mut self);
19    fn get_metrics(&self) -> &HeapMetrics;
20}
21
22pub trait GarbageCollector {
23    fn collect_garbage(
24        &mut self,
25        entries: &mut HashMap<HeapHandleId, HeapEntry>,
26        roots: &[HeapHandleId],
27    ) -> usize;
28    fn get_collection_stats(&self) -> (usize, u32, u32);
29}
30
31pub trait HeapManager {
32    fn get(&self, handle: HeapHandleId) -> Option<&HeapEntry>;
33    fn get_mut(&mut self, handle: HeapHandleId) -> Option<&mut HeapEntry>;
34    fn set_object_property(&mut self, handle: HeapHandleId, key: String, value: Value);
35    fn get_object_property(&self, handle: HeapHandleId, key: &str) -> Option<&Value>;
36    fn push_array_element(&mut self, handle: HeapHandleId, value: Value);
37    fn get_array_element(&self, handle: HeapHandleId, idx: ArraySize) -> Option<&Value>;
38    fn set_array_element(&mut self, handle: HeapHandleId, idx: ArraySize, value: Value);
39    fn remove_object_property(&mut self, handle: HeapHandleId, key: &str);
40    fn has_object_property(&self, handle: HeapHandleId, key: &str) -> bool;
41    fn size(&self) -> usize;
42    fn is_empty(&self) -> bool;
43    fn clear(&mut self);
44    fn get_stats(&self) -> HeapStats;
45    fn get_metrics(&self) -> &HeapMetrics;
46    fn collect_garbage(&mut self, roots: &[HeapHandleId]) -> usize;
47}
48
49pub trait HeapOperations {
50    fn alloc_object(&mut self) -> HeapHandleId;
51    fn alloc_array(&mut self) -> HeapHandleId;
52    fn alloc_function(
53        &mut self,
54        bytecode: Bytecode,
55        arg_count: ArgIndex,
56        local_count: LocalIndex,
57    ) -> HeapHandleId;
58    fn alloc_string(&mut self, value: String) -> HeapHandleId;
59}
60
61pub struct Heap {
62    allocator: Box<dyn HeapAllocator>,
63    gc: Box<dyn GarbageCollector>,
64    stats: HeapStats,
65    metrics: HeapMetrics,
66}
67
68impl Clone for Heap {
69    fn clone(&self) -> Self {
70        Self {
71            allocator: Box::new(super::allocation::HeapAllocatorImpl::new()),
72            gc: Box::new(super::garbage_collection::GarbageCollectorImpl::new()),
73            stats: self.stats.clone(),
74            metrics: self.metrics.clone(),
75        }
76    }
77}
78
79impl Heap {
80    pub fn new() -> Self {
81        Self {
82            allocator: Box::new(super::allocation::HeapAllocatorImpl::new()),
83            gc: Box::new(super::garbage_collection::GarbageCollectorImpl::new()),
84            stats: HeapStats::new(),
85            metrics: HeapMetrics::new(),
86        }
87    }
88
89    pub fn with_capacity(capacity: usize) -> Self {
90        Self {
91            allocator: Box::new(super::allocation::HeapAllocatorImpl::with_capacity(
92                capacity,
93            )),
94            gc: Box::new(super::garbage_collection::GarbageCollectorImpl::new()),
95            stats: HeapStats::new(),
96            metrics: HeapMetrics::new(),
97        }
98    }
99
100    // Métodos auxiliares para compatibilidade
101    pub fn alloc_object(&mut self) -> HeapHandleId {
102        let handle = self.allocator.allocate(HeapEntry::Object(HashMap::new()));
103        self.metrics.record_allocation();
104        self.update_stats();
105        handle
106    }
107
108    pub fn alloc_array(&mut self) -> HeapHandleId {
109        let handle = self.allocator.allocate(HeapEntry::Array(Vec::new()));
110        self.metrics.record_allocation();
111        self.update_stats();
112        handle
113    }
114
115    pub fn alloc_function(
116        &mut self,
117        bytecode: Bytecode,
118        arg_count: ArgIndex,
119        local_count: LocalIndex,
120    ) -> HeapHandleId {
121        let handle = self.allocator.allocate(HeapEntry::Function {
122            bytecode,
123            arg_count,
124            local_count,
125            closure_vars: HashMap::new(),
126        });
127        self.metrics.record_allocation();
128        self.update_stats();
129        handle
130    }
131
132    pub fn alloc_string(&mut self, value: String) -> HeapHandleId {
133        let handle = self.allocator.allocate(HeapEntry::String(value));
134        self.metrics.record_allocation();
135        self.update_stats();
136        handle
137    }
138
139    // Métodos de compatibilidade para código existente
140    pub fn get(&self, handle: HeapHandleId) -> Option<&HeapEntry> {
141        self.allocator.get(handle)
142    }
143
144    pub fn get_mut(&mut self, handle: HeapHandleId) -> Option<&mut HeapEntry> {
145        self.allocator.get_mut(handle)
146    }
147
148    pub fn get_object_property(&self, handle: HeapHandleId, key: &str) -> Option<&Value> {
149        if let Some(HeapEntry::Object(obj)) = self.allocator.get(handle) {
150            obj.get(key)
151        } else {
152            None
153        }
154    }
155
156    pub fn set_object_property(&mut self, handle: HeapHandleId, key: String, value: Value) {
157        if let Some(HeapEntry::Object(obj)) = self.allocator.get_mut(handle) {
158            obj.insert(key, value);
159        }
160    }
161
162    pub fn set_array_element(&mut self, handle: HeapHandleId, idx: ArraySize, value: Value) {
163        if let Some(HeapEntry::Array(arr)) = self.allocator.get_mut(handle) {
164            let index = idx.as_usize();
165            if index < arr.len() {
166                arr[index] = value;
167            } else {
168                arr.resize(index + 1, Value::Undefined);
169                arr[index] = value;
170            }
171        }
172    }
173
174    fn update_stats(&mut self) {
175        let entries = self.allocator.get_entries();
176        let mut object_count = 0;
177        let mut array_count = 0;
178        let mut function_count = 0;
179        let mut string_count = 0;
180        let mut memory_usage = 0;
181
182        for entry in entries.values() {
183            match entry {
184                HeapEntry::Object(_) => object_count += 1,
185                HeapEntry::Array(_) => array_count += 1,
186                HeapEntry::Function { .. } => function_count += 1,
187                HeapEntry::String(_) => string_count += 1,
188            }
189            memory_usage += entry.memory_usage();
190        }
191
192        self.stats
193            .update_counts(object_count, array_count, function_count, string_count);
194        self.stats.set_memory_usage(memory_usage);
195    }
196}
197
198impl HeapManager for Heap {
199    fn get(&self, handle: HeapHandleId) -> Option<&HeapEntry> {
200        self.allocator.get(handle)
201    }
202
203    fn get_mut(&mut self, handle: HeapHandleId) -> Option<&mut HeapEntry> {
204        self.allocator.get_mut(handle)
205    }
206
207    fn set_object_property(&mut self, handle: HeapHandleId, key: String, value: Value) {
208        if let Some(HeapEntry::Object(obj)) = self.allocator.get_mut(handle) {
209            obj.insert(key, value);
210        }
211    }
212
213    fn get_object_property(&self, handle: HeapHandleId, key: &str) -> Option<&Value> {
214        if let Some(HeapEntry::Object(obj)) = self.allocator.get(handle) {
215            obj.get(key)
216        } else {
217            None
218        }
219    }
220
221    fn push_array_element(&mut self, handle: HeapHandleId, value: Value) {
222        if let Some(HeapEntry::Array(arr)) = self.allocator.get_mut(handle) {
223            arr.push(value);
224        }
225    }
226
227    fn get_array_element(&self, handle: HeapHandleId, idx: ArraySize) -> Option<&Value> {
228        if let Some(HeapEntry::Array(arr)) = self.allocator.get(handle) {
229            arr.get(idx.as_usize())
230        } else {
231            None
232        }
233    }
234
235    fn set_array_element(&mut self, handle: HeapHandleId, idx: ArraySize, value: Value) {
236        if let Some(HeapEntry::Array(arr)) = self.allocator.get_mut(handle) {
237            let index = idx.as_usize();
238            if index < arr.len() {
239                arr[index] = value;
240            } else {
241                arr.resize(index + 1, Value::Undefined);
242                arr[index] = value;
243            }
244        }
245    }
246
247    fn remove_object_property(&mut self, handle: HeapHandleId, key: &str) {
248        if let Some(HeapEntry::Object(obj)) = self.allocator.get_mut(handle) {
249            obj.remove(key);
250        }
251    }
252
253    fn has_object_property(&self, handle: HeapHandleId, key: &str) -> bool {
254        if let Some(HeapEntry::Object(obj)) = self.allocator.get(handle) {
255            obj.contains_key(key)
256        } else {
257            false
258        }
259    }
260
261    fn size(&self) -> usize {
262        self.allocator.size()
263    }
264
265    fn is_empty(&self) -> bool {
266        self.allocator.is_empty()
267    }
268
269    fn clear(&mut self) {
270        self.allocator.clear();
271    }
272
273    fn get_stats(&self) -> HeapStats {
274        self.stats.clone()
275    }
276
277    fn get_metrics(&self) -> &HeapMetrics {
278        &self.metrics
279    }
280
281    fn collect_garbage(&mut self, roots: &[HeapHandleId]) -> usize {
282        let entries = self.allocator.get_entries_mut();
283        let collected = self.gc.collect_garbage(entries, roots);
284        self.metrics.record_gc_cycle(std::time::Duration::ZERO);
285        collected
286    }
287}
288
289impl HeapOperations for Heap {
290    fn alloc_object(&mut self) -> HeapHandleId {
291        self.alloc_object()
292    }
293
294    fn alloc_array(&mut self) -> HeapHandleId {
295        self.alloc_array()
296    }
297
298    fn alloc_function(
299        &mut self,
300        bytecode: Bytecode,
301        arg_count: ArgIndex,
302        local_count: LocalIndex,
303    ) -> HeapHandleId {
304        self.alloc_function(bytecode, arg_count, local_count)
305    }
306
307    fn alloc_string(&mut self, value: String) -> HeapHandleId {
308        self.alloc_string(value)
309    }
310}
311
312impl Default for Heap {
313    fn default() -> Self {
314        Self::new()
315    }
316}