static_alloc/
allocator_api2.rs1use crate::{
2 bump::{Bump, BumpSlice, BumpView},
3 unsync,
4};
5
6use allocator_api2::alloc::{AllocError, Allocator, Layout};
7use core::ptr::NonNull;
8
9unsafe impl<T> Allocator for Bump<T> {
10 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
11 Allocator::allocate(&self.as_view(), layout)
12 }
13
14 unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout) {}
15
16 unsafe fn shrink(
17 &self,
18 ptr: NonNull<u8>,
19 old_layout: Layout,
20 new_layout: Layout,
21 ) -> Result<NonNull<[u8]>, AllocError> {
22 unsafe { Allocator::shrink(&self.as_view(), ptr, old_layout, new_layout) }
25 }
26}
27
28unsafe impl Allocator for BumpSlice {
29 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
30 Allocator::allocate(&self.as_view(), layout)
31 }
32
33 unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout) {}
34
35 unsafe fn shrink(
36 &self,
37 ptr: NonNull<u8>,
38 old_layout: Layout,
39 new_layout: Layout,
40 ) -> Result<NonNull<[u8]>, AllocError> {
41 unsafe { Allocator::shrink(&self.as_view(), ptr, old_layout, new_layout) }
44 }
45}
46
47unsafe impl Allocator for BumpView<'_> {
48 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
49 let len = layout.size();
50 match self.get_layout(layout) {
51 None => Err(AllocError),
52 Some(allocation) => Ok(NonNull::slice_from_raw_parts(allocation.ptr, len)),
53 }
54 }
55
56 unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout) {}
57
58 unsafe fn shrink(
59 &self,
60 ptr: NonNull<u8>,
61 old_layout: Layout,
62 new_layout: Layout,
63 ) -> Result<NonNull<[u8]>, AllocError> {
64 unsafe { shrink_in_place(ptr, old_layout, new_layout) }
67 }
68}
69
70unsafe impl<T> Allocator for unsync::Bump<T> {
71 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
72 <unsync::BumpSlice as Allocator>::allocate(self, layout)
73 }
74
75 unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout) {}
76
77 unsafe fn shrink(
78 &self,
79 ptr: NonNull<u8>,
80 old_layout: Layout,
81 new_layout: Layout,
82 ) -> Result<NonNull<[u8]>, AllocError> {
83 unsafe { <unsync::BumpSlice as Allocator>::shrink(self, ptr, old_layout, new_layout) }
86 }
87}
88
89unsafe impl Allocator for unsync::BumpSlice {
90 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
91 let len = layout.size();
92 match self.alloc(layout) {
93 None => Err(AllocError),
94 Some(allocation) => Ok(NonNull::slice_from_raw_parts(allocation, len)),
95 }
96 }
97
98 unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout) {}
99
100 unsafe fn shrink(
101 &self,
102 ptr: NonNull<u8>,
103 old_layout: Layout,
104 new_layout: Layout,
105 ) -> Result<NonNull<[u8]>, AllocError> {
106 unsafe { shrink_in_place(ptr, old_layout, new_layout) }
109 }
110}
111
112unsafe fn shrink_in_place(
115 ptr: NonNull<u8>,
116 old_layout: Layout,
117 new_layout: Layout,
118) -> Result<NonNull<[u8]>, AllocError> {
119 debug_assert!(new_layout.size() <= old_layout.size());
120 let len = new_layout.size();
121
122 let offset = ptr.align_offset(new_layout.align());
123
124 if offset > 0 {
125 if old_layout
126 .size()
127 .checked_sub(offset)
128 .is_none_or(|n| n < len)
129 {
130 return Err(AllocError);
132 }
133
134 let dst = unsafe { ptr.byte_add(offset) };
138 unsafe { ptr.copy_to(dst, len) };
141 dst
142 } else {
143 ptr
144 };
145
146 Ok(NonNull::slice_from_raw_parts(ptr, len))
147}