1 //! Memory allocation APIs
3 #![stable(feature = "alloc_module", since = "1.28.0")]
5 use core
::intrinsics
::{min_align_of_val, size_of_val}
;
6 use core
::ptr
::{NonNull, Unique}
;
9 #[stable(feature = "alloc_module", since = "1.28.0")]
11 pub use core
::alloc
::*;
17 // These are the magic symbols to call the global allocator. rustc generates
18 // them from the `#[global_allocator]` attribute if there is one, or uses the
19 // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`)
22 #[rustc_allocator_nounwind]
23 fn __rust_alloc(size
: usize, align
: usize) -> *mut u8;
24 #[rustc_allocator_nounwind]
25 fn __rust_dealloc(ptr
: *mut u8, size
: usize, align
: usize);
26 #[rustc_allocator_nounwind]
27 fn __rust_realloc(ptr
: *mut u8,
30 new_size
: usize) -> *mut u8;
31 #[rustc_allocator_nounwind]
32 fn __rust_alloc_zeroed(size
: usize, align
: usize) -> *mut u8;
35 /// The global memory allocator.
37 /// This type implements the [`Alloc`] trait by forwarding calls
38 /// to the allocator registered with the `#[global_allocator]` attribute
39 /// if there is one, or the `std` crate’s default.
41 /// Note: while this type is unstable, the functionality it provides can be
42 /// accessed through the [free functions in `alloc`](index.html#functions).
44 /// [`Alloc`]: trait.Alloc.html
45 #[unstable(feature = "allocator_api", issue = "32838")]
46 #[derive(Copy, Clone, Default, Debug)]
49 /// Allocate memory with the global allocator.
51 /// This function forwards calls to the [`GlobalAlloc::alloc`] method
52 /// of the allocator registered with the `#[global_allocator]` attribute
53 /// if there is one, or the `std` crate’s default.
55 /// This function is expected to be deprecated in favor of the `alloc` method
56 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
60 /// See [`GlobalAlloc::alloc`].
62 /// [`Global`]: struct.Global.html
63 /// [`Alloc`]: trait.Alloc.html
64 /// [`GlobalAlloc::alloc`]: trait.GlobalAlloc.html#tymethod.alloc
69 /// use std::alloc::{alloc, dealloc, Layout};
72 /// let layout = Layout::new::<u16>();
73 /// let ptr = alloc(layout);
75 /// *(ptr as *mut u16) = 42;
76 /// assert_eq!(*(ptr as *mut u16), 42);
78 /// dealloc(ptr, layout);
81 #[stable(feature = "global_alloc", since = "1.28.0")]
83 pub unsafe fn alloc(layout
: Layout
) -> *mut u8 {
84 __rust_alloc(layout
.size(), layout
.align())
87 /// Deallocate memory with the global allocator.
89 /// This function forwards calls to the [`GlobalAlloc::dealloc`] method
90 /// of the allocator registered with the `#[global_allocator]` attribute
91 /// if there is one, or the `std` crate’s default.
93 /// This function is expected to be deprecated in favor of the `dealloc` method
94 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
98 /// See [`GlobalAlloc::dealloc`].
100 /// [`Global`]: struct.Global.html
101 /// [`Alloc`]: trait.Alloc.html
102 /// [`GlobalAlloc::dealloc`]: trait.GlobalAlloc.html#tymethod.dealloc
103 #[stable(feature = "global_alloc", since = "1.28.0")]
105 pub unsafe fn dealloc(ptr
: *mut u8, layout
: Layout
) {
106 __rust_dealloc(ptr
, layout
.size(), layout
.align())
109 /// Reallocate memory with the global allocator.
111 /// This function forwards calls to the [`GlobalAlloc::realloc`] method
112 /// of the allocator registered with the `#[global_allocator]` attribute
113 /// if there is one, or the `std` crate’s default.
115 /// This function is expected to be deprecated in favor of the `realloc` method
116 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
120 /// See [`GlobalAlloc::realloc`].
122 /// [`Global`]: struct.Global.html
123 /// [`Alloc`]: trait.Alloc.html
124 /// [`GlobalAlloc::realloc`]: trait.GlobalAlloc.html#method.realloc
125 #[stable(feature = "global_alloc", since = "1.28.0")]
127 pub unsafe fn realloc(ptr
: *mut u8, layout
: Layout
, new_size
: usize) -> *mut u8 {
128 __rust_realloc(ptr
, layout
.size(), layout
.align(), new_size
)
131 /// Allocate zero-initialized memory with the global allocator.
133 /// This function forwards calls to the [`GlobalAlloc::alloc_zeroed`] method
134 /// of the allocator registered with the `#[global_allocator]` attribute
135 /// if there is one, or the `std` crate’s default.
137 /// This function is expected to be deprecated in favor of the `alloc_zeroed` method
138 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
142 /// See [`GlobalAlloc::alloc_zeroed`].
144 /// [`Global`]: struct.Global.html
145 /// [`Alloc`]: trait.Alloc.html
146 /// [`GlobalAlloc::alloc_zeroed`]: trait.GlobalAlloc.html#method.alloc_zeroed
151 /// use std::alloc::{alloc_zeroed, dealloc, Layout};
154 /// let layout = Layout::new::<u16>();
155 /// let ptr = alloc_zeroed(layout);
157 /// assert_eq!(*(ptr as *mut u16), 0);
159 /// dealloc(ptr, layout);
162 #[stable(feature = "global_alloc", since = "1.28.0")]
164 pub unsafe fn alloc_zeroed(layout
: Layout
) -> *mut u8 {
165 __rust_alloc_zeroed(layout
.size(), layout
.align())
168 #[unstable(feature = "allocator_api", issue = "32838")]
169 unsafe impl Alloc
for Global
{
171 unsafe fn alloc(&mut self, layout
: Layout
) -> Result
<NonNull
<u8>, AllocErr
> {
172 NonNull
::new(alloc(layout
)).ok_or(AllocErr
)
176 unsafe fn dealloc(&mut self, ptr
: NonNull
<u8>, layout
: Layout
) {
177 dealloc(ptr
.as_ptr(), layout
)
181 unsafe fn realloc(&mut self,
185 -> Result
<NonNull
<u8>, AllocErr
>
187 NonNull
::new(realloc(ptr
.as_ptr(), layout
, new_size
)).ok_or(AllocErr
)
191 unsafe fn alloc_zeroed(&mut self, layout
: Layout
) -> Result
<NonNull
<u8>, AllocErr
> {
192 NonNull
::new(alloc_zeroed(layout
)).ok_or(AllocErr
)
196 /// The allocator for unique pointers.
197 // This function must not unwind. If it does, MIR codegen will fail.
199 #[lang = "exchange_malloc"]
201 unsafe fn exchange_malloc(size
: usize, align
: usize) -> *mut u8 {
205 let layout
= Layout
::from_size_align_unchecked(size
, align
);
206 let ptr
= alloc(layout
);
210 handle_alloc_error(layout
)
215 #[cfg_attr(not(test), lang = "box_free")]
217 pub(crate) unsafe fn box_free
<T
: ?Sized
>(ptr
: Unique
<T
>) {
218 let ptr
= ptr
.as_ptr();
219 let size
= size_of_val(&*ptr
);
220 let align
= min_align_of_val(&*ptr
);
221 // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
223 let layout
= Layout
::from_size_align_unchecked(size
, align
);
224 dealloc(ptr
as *mut u8, layout
);
228 /// Abort on memory allocation error or failure.
230 /// Callers of memory allocation APIs wishing to abort computation
231 /// in response to an allocation error are encouraged to call this function,
232 /// rather than directly invoking `panic!` or similar.
234 /// The default behavior of this function is to print a message to standard error
235 /// and abort the process.
236 /// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
238 /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
239 /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
240 #[stable(feature = "global_alloc", since = "1.28.0")]
241 #[rustc_allocator_nounwind]
242 pub fn handle_alloc_error(layout
: Layout
) -> ! {
245 fn oom_impl(layout
: Layout
) -> !;
247 unsafe { oom_impl(layout) }