jetcrab\memory/
allocator.rs

1use crate::vm::types::{AllocationCount, MemorySize};
2use std::alloc::{alloc, dealloc, Layout};
3
4pub struct MemoryAllocator {
5    total_allocated: MemorySize,
6    allocations: AllocationCount,
7    deallocations: AllocationCount,
8}
9
10impl Default for MemoryAllocator {
11    fn default() -> Self {
12        Self::new()
13    }
14}
15
16impl MemoryAllocator {
17    pub fn new() -> Self {
18        Self {
19            total_allocated: MemorySize::new(0),
20            allocations: AllocationCount::new(0),
21            deallocations: AllocationCount::new(0),
22        }
23    }
24
25    pub fn allocate(&mut self, size: MemorySize) -> *mut u8 {
26        unsafe {
27            let layout = Layout::from_size_align(size.as_usize(), 8).unwrap();
28            let ptr = alloc(layout);
29
30            if !ptr.is_null() {
31                self.total_allocated = self.total_allocated.add(size);
32                self.allocations.increment();
33            }
34
35            ptr
36        }
37    }
38
39    /// # Safety
40    ///
41    /// The caller must ensure that:
42    /// - `ptr` is a valid pointer that was previously allocated by this allocator
43    /// - `size` matches the size that was used when allocating `ptr`
44    /// - `ptr` is not null
45    pub unsafe fn deallocate(&mut self, ptr: *mut u8, size: MemorySize) {
46        if !ptr.is_null() {
47            let layout = Layout::from_size_align(size.as_usize(), 8).unwrap();
48            dealloc(ptr, layout);
49
50            self.total_allocated = self.total_allocated.sub(size);
51            self.deallocations.increment();
52        }
53    }
54
55    pub fn get_stats(&self) -> AllocatorStats {
56        AllocatorStats {
57            total_allocated: self.total_allocated,
58            allocations: self.allocations,
59            deallocations: self.deallocations,
60        }
61    }
62
63    pub fn reset_stats(&mut self) {
64        self.total_allocated = MemorySize::new(0);
65        self.allocations.reset();
66        self.deallocations.reset();
67    }
68}
69
70pub struct AllocatorStats {
71    pub total_allocated: MemorySize,
72    pub allocations: AllocationCount,
73    pub deallocations: AllocationCount,
74}