1 // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Memory allocation APIs
13 #![stable(feature = "alloc_module", since = "1.28.0")]
15 use core
::intrinsics
::{min_align_of_val, size_of_val}
;
16 use core
::ptr
::{NonNull, Unique}
;
19 #[stable(feature = "alloc_module", since = "1.28.0")]
21 pub use core
::alloc
::*;
25 #[rustc_allocator_nounwind]
26 fn __rust_alloc(size
: usize, align
: usize) -> *mut u8;
27 #[rustc_allocator_nounwind]
28 fn __rust_dealloc(ptr
: *mut u8, size
: usize, align
: usize);
29 #[rustc_allocator_nounwind]
30 fn __rust_realloc(ptr
: *mut u8,
33 new_size
: usize) -> *mut u8;
34 #[rustc_allocator_nounwind]
35 fn __rust_alloc_zeroed(size
: usize, align
: usize) -> *mut u8;
38 /// The global memory allocator.
40 /// This type implements the [`Alloc`] trait by forwarding calls
41 /// to the allocator registered with the `#[global_allocator]` attribute
42 /// if there is one, or the `std` crate’s default.
43 #[unstable(feature = "allocator_api", issue = "32838")]
44 #[derive(Copy, Clone, Default, Debug)]
47 /// Allocate memory with the global allocator.
49 /// This function forwards calls to the [`GlobalAlloc::alloc`] method
50 /// of the allocator registered with the `#[global_allocator]` attribute
51 /// if there is one, or the `std` crate’s default.
53 /// This function is expected to be deprecated in favor of the `alloc` method
54 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
58 /// See [`GlobalAlloc::alloc`].
59 #[stable(feature = "global_alloc", since = "1.28.0")]
61 pub unsafe fn alloc(layout
: Layout
) -> *mut u8 {
62 __rust_alloc(layout
.size(), layout
.align())
65 /// Deallocate memory with the global allocator.
67 /// This function forwards calls to the [`GlobalAlloc::dealloc`] method
68 /// of the allocator registered with the `#[global_allocator]` attribute
69 /// if there is one, or the `std` crate’s default.
71 /// This function is expected to be deprecated in favor of the `dealloc` method
72 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
76 /// See [`GlobalAlloc::dealloc`].
77 #[stable(feature = "global_alloc", since = "1.28.0")]
79 pub unsafe fn dealloc(ptr
: *mut u8, layout
: Layout
) {
80 __rust_dealloc(ptr
, layout
.size(), layout
.align())
83 /// Reallocate memory with the global allocator.
85 /// This function forwards calls to the [`GlobalAlloc::realloc`] method
86 /// of the allocator registered with the `#[global_allocator]` attribute
87 /// if there is one, or the `std` crate’s default.
89 /// This function is expected to be deprecated in favor of the `realloc` method
90 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
94 /// See [`GlobalAlloc::realloc`].
95 #[stable(feature = "global_alloc", since = "1.28.0")]
97 pub unsafe fn realloc(ptr
: *mut u8, layout
: Layout
, new_size
: usize) -> *mut u8 {
98 __rust_realloc(ptr
, layout
.size(), layout
.align(), new_size
)
101 /// Allocate zero-initialized memory with the global allocator.
103 /// This function forwards calls to the [`GlobalAlloc::alloc_zeroed`] method
104 /// of the allocator registered with the `#[global_allocator]` attribute
105 /// if there is one, or the `std` crate’s default.
107 /// This function is expected to be deprecated in favor of the `alloc_zeroed` method
108 /// of the [`Global`] type when it and the [`Alloc`] trait become stable.
112 /// See [`GlobalAlloc::alloc_zeroed`].
113 #[stable(feature = "global_alloc", since = "1.28.0")]
115 pub unsafe fn alloc_zeroed(layout
: Layout
) -> *mut u8 {
116 __rust_alloc_zeroed(layout
.size(), layout
.align())
119 #[unstable(feature = "allocator_api", issue = "32838")]
120 unsafe impl Alloc
for Global
{
122 unsafe fn alloc(&mut self, layout
: Layout
) -> Result
<NonNull
<u8>, AllocErr
> {
123 NonNull
::new(alloc(layout
)).ok_or(AllocErr
)
127 unsafe fn dealloc(&mut self, ptr
: NonNull
<u8>, layout
: Layout
) {
128 dealloc(ptr
.as_ptr(), layout
)
132 unsafe fn realloc(&mut self,
136 -> Result
<NonNull
<u8>, AllocErr
>
138 NonNull
::new(realloc(ptr
.as_ptr(), layout
, new_size
)).ok_or(AllocErr
)
142 unsafe fn alloc_zeroed(&mut self, layout
: Layout
) -> Result
<NonNull
<u8>, AllocErr
> {
143 NonNull
::new(alloc_zeroed(layout
)).ok_or(AllocErr
)
147 /// The allocator for unique pointers.
148 // This function must not unwind. If it does, MIR codegen will fail.
150 #[lang = "exchange_malloc"]
152 unsafe fn exchange_malloc(size
: usize, align
: usize) -> *mut u8 {
156 let layout
= Layout
::from_size_align_unchecked(size
, align
);
157 let ptr
= alloc(layout
);
161 handle_alloc_error(layout
)
166 #[cfg_attr(not(test), lang = "box_free")]
168 pub(crate) unsafe fn box_free
<T
: ?Sized
>(ptr
: Unique
<T
>) {
169 let ptr
= ptr
.as_ptr();
170 let size
= size_of_val(&*ptr
);
171 let align
= min_align_of_val(&*ptr
);
172 // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
174 let layout
= Layout
::from_size_align_unchecked(size
, align
);
175 dealloc(ptr
as *mut u8, layout
);
179 /// Abort on memory allocation error or failure.
181 /// Callers of memory allocation APIs wishing to abort computation
182 /// in response to an allocation error are encouraged to call this function,
183 /// rather than directly invoking `panic!` or similar.
185 /// The default behavior of this function is to print a message to standard error
186 /// and abort the process.
187 /// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
189 /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
190 /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
191 #[stable(feature = "global_alloc", since = "1.28.0")]
192 #[rustc_allocator_nounwind]
193 pub fn handle_alloc_error(layout
: Layout
) -> ! {
194 #[allow(improper_ctypes)]
197 fn oom_impl(layout
: Layout
) -> !;
199 unsafe { oom_impl(layout) }
205 use self::test
::Bencher
;
207 use alloc
::{Global, Alloc, Layout, handle_alloc_error}
;
210 fn allocate_zeroed() {
212 let layout
= Layout
::from_size_align(1024, 1).unwrap();
213 let ptr
= Global
.alloc_zeroed(layout
.clone())
214 .unwrap_or_else(|_
| handle_alloc_error(layout
));
216 let mut i
= ptr
.cast
::<u8>().as_ptr();
217 let end
= i
.offset(layout
.size() as isize);
222 Global
.dealloc(ptr
, layout
);
227 fn alloc_owned_small(b
: &mut Bencher
) {
229 let _
: Box
<_
> = box 10;