osom_tools_runtime/allocator/
std_allocator.rs

1use alloc::alloc as std_alloc;
2
3use core::alloc::Layout;
4
5use super::{AllocatedMemory, AllocationError, Allocator};
6
7/// A thin wrapper around `*mut u8`.
8#[derive(PartialEq, Eq, Clone, Hash, Debug)]
9#[repr(transparent)]
10#[must_use]
11pub struct StdAllocatedMemory {
12    ptr: *mut u8,
13}
14
15impl StdAllocatedMemory {
16    #[inline(always)]
17    const fn new(ptr: *mut u8) -> Self {
18        Self { ptr }
19    }
20}
21
22unsafe impl AllocatedMemory for StdAllocatedMemory {
23    #[inline(always)]
24    unsafe fn as_ptr(&self) -> *mut u8 {
25        self.ptr
26    }
27
28    fn resize(self, old_layout: Layout, new_layout: Layout) -> Result<Self, AllocationError> {
29        let new_ptr = if old_layout.align() == new_layout.align() {
30            let new_ptr = unsafe { std_alloc::realloc(self.ptr, old_layout, new_layout.size()) };
31            if new_ptr.is_null() {
32                return Err(AllocationError);
33            }
34            new_ptr
35        } else {
36            let new_ptr = unsafe { std_alloc::alloc(new_layout) };
37            if new_ptr.is_null() {
38                return Err(AllocationError);
39            }
40
41            let copy_size = core::cmp::min(old_layout.size(), new_layout.size());
42
43            unsafe {
44                self.ptr.copy_to_nonoverlapping(new_ptr, copy_size);
45                std_alloc::dealloc(self.ptr, old_layout);
46            }
47
48            new_ptr
49        };
50
51        Ok(StdAllocatedMemory::new(new_ptr))
52    }
53
54    fn deallocate(self, layout: Layout) {
55        unsafe { std_alloc::dealloc(self.ptr, layout) };
56    }
57}
58
59/// Represents the default allocator taken from the standard Rust library.
60#[derive(Clone, Default, Debug)]
61#[repr(C)]
62#[must_use]
63pub struct StdAllocator;
64
65unsafe impl Allocator for StdAllocator {
66    type TAllocatedMemory = StdAllocatedMemory;
67
68    fn allocate(&self, layout: Layout) -> Result<Self::TAllocatedMemory, AllocationError> {
69        let new_ptr = unsafe { std_alloc::alloc(layout) };
70        if new_ptr.is_null() {
71            return Err(AllocationError);
72        }
73        Ok(StdAllocatedMemory::new(new_ptr))
74    }
75
76    #[inline(always)]
77    unsafe fn convert_raw_ptr(&self, ptr: *mut u8) -> Self::TAllocatedMemory {
78        StdAllocatedMemory::new(ptr)
79    }
80    
81    #[inline(always)]
82    unsafe fn dangling<T>(&self) -> Self::TAllocatedMemory {
83        StdAllocatedMemory::new(core::ptr::dangling_mut::<T>().cast())
84    }
85}