jetcrab\vm\heap/
allocation.rs1use super::entries::HeapEntry;
2use super::types::HeapMetrics;
3use crate::vm::bytecode::Bytecode;
4use crate::vm::handle::HeapHandleId;
5use crate::vm::types::{ArgIndex, LocalIndex};
6use std::collections::HashMap;
7
8pub struct HeapAllocatorImpl {
9 entries: HashMap<HeapHandleId, HeapEntry>,
10 next_id: usize,
11 metrics: HeapMetrics,
12}
13
14impl Clone for HeapAllocatorImpl {
15 fn clone(&self) -> Self {
16 Self {
17 entries: self.entries.clone(),
18 next_id: self.next_id,
19 metrics: self.metrics.clone(),
20 }
21 }
22}
23
24impl HeapAllocatorImpl {
25 pub fn new() -> Self {
26 Self {
27 entries: HashMap::new(),
28 next_id: 0,
29 metrics: HeapMetrics::new(),
30 }
31 }
32
33 pub fn with_capacity(_capacity: usize) -> Self {
34 Self {
35 entries: HashMap::new(),
36 next_id: 0,
37 metrics: HeapMetrics::new(),
38 }
39 }
40
41 pub fn get_next_id(&self) -> usize {
42 self.next_id
43 }
44
45 pub fn set_next_id(&mut self, id: usize) {
46 self.next_id = id;
47 }
48
49 pub fn alloc_object(&mut self) -> HeapHandleId {
51 let id = HeapHandleId::new(self.next_id);
52 self.entries.insert(id, HeapEntry::Object(HashMap::new()));
53 self.next_id += 1;
54 self.metrics.record_allocation();
55 id
56 }
57
58 pub fn alloc_array(&mut self) -> HeapHandleId {
59 let id = HeapHandleId::new(self.next_id);
60 self.entries.insert(id, HeapEntry::Array(Vec::new()));
61 self.next_id += 1;
62 self.metrics.record_allocation();
63 id
64 }
65
66 pub fn alloc_function(
67 &mut self,
68 bytecode: Bytecode,
69 arg_count: ArgIndex,
70 local_count: LocalIndex,
71 ) -> HeapHandleId {
72 let id = HeapHandleId::new(self.next_id);
73 self.entries.insert(
74 id,
75 HeapEntry::Function {
76 bytecode,
77 arg_count,
78 local_count,
79 closure_vars: HashMap::new(),
80 },
81 );
82 self.next_id += 1;
83 self.metrics.record_allocation();
84 id
85 }
86
87 pub fn alloc_string(&mut self, value: String) -> HeapHandleId {
88 let id = HeapHandleId::new(self.next_id);
89 self.entries.insert(id, HeapEntry::String(value));
90 self.next_id += 1;
91 self.metrics.record_allocation();
92 id
93 }
94}
95
96impl super::management::HeapAllocator for HeapAllocatorImpl {
97 fn allocate(&mut self, entry: HeapEntry) -> HeapHandleId {
98 let id = HeapHandleId::new(self.next_id);
99 self.entries.insert(id, entry);
100 self.next_id += 1;
101 self.metrics.record_allocation();
102 id
103 }
104
105 fn deallocate(&mut self, handle: HeapHandleId) -> bool {
106 if self.entries.remove(&handle).is_some() {
107 self.metrics.record_deallocation();
108 true
109 } else {
110 false
111 }
112 }
113
114 fn get(&self, handle: HeapHandleId) -> Option<&HeapEntry> {
115 self.entries.get(&handle)
116 }
117
118 fn get_mut(&mut self, handle: HeapHandleId) -> Option<&mut HeapEntry> {
119 self.entries.get_mut(&handle)
120 }
121
122 fn get_entries(&self) -> &HashMap<HeapHandleId, HeapEntry> {
123 &self.entries
124 }
125
126 fn get_entries_mut(&mut self) -> &mut HashMap<HeapHandleId, HeapEntry> {
127 &mut self.entries
128 }
129
130 fn size(&self) -> usize {
131 self.entries.len()
132 }
133
134 fn is_empty(&self) -> bool {
135 self.entries.is_empty()
136 }
137
138 fn clear(&mut self) {
139 self.entries.clear();
140 }
141
142 fn get_metrics(&self) -> &HeapMetrics {
143 &self.metrics
144 }
145}
146
147impl Default for HeapAllocatorImpl {
148 fn default() -> Self {
149 Self::new()
150 }
151}