|
3 | 3 | #![stable(feature = "alloc_module", since = "1.28.0")]
|
4 | 4 |
|
5 | 5 | use core::intrinsics::{min_align_of_val, size_of_val};
|
| 6 | +#[cfg(stage0)] |
| 7 | +use core::marker::PhantomData; |
6 | 8 | use core::ptr::{NonNull, Unique};
|
7 | 9 | use core::usize;
|
8 | 10 |
|
9 | 11 | #[stable(feature = "alloc_module", since = "1.28.0")]
|
10 | 12 | #[doc(inline)]
|
11 | 13 | pub use core::alloc::*;
|
12 | 14 |
|
| 15 | +#[cfg(stage0)] |
| 16 | +#[unstable(feature = "allocator_api", issue = "32838")] |
| 17 | +// pub to make the compiler happy wrt the trait being made public by the impls in e.g. boxed.rs. |
| 18 | +pub trait Stage0Alloc = Alloc + Default; |
| 19 | + |
| 20 | +#[cfg(not(stage0))] |
| 21 | +pub(crate) use Alloc as Stage0Alloc; |
| 22 | + |
| 23 | +#[cfg(stage0)] |
| 24 | +pub(crate) fn stage0_phantom<A>(_a: A) -> PhantomData<A> { PhantomData } |
| 25 | + |
| 26 | +#[cfg(not(stage0))] |
| 27 | +pub(crate) fn stage0_phantom<A>(a: A) -> A { a } |
| 28 | + |
| 29 | +#[cfg(stage0)] |
| 30 | +pub(crate) fn stage0_unphantom<A: Default>(_a: PhantomData<A>) -> A { A::default() } |
| 31 | + |
| 32 | +#[cfg(not(stage0))] |
| 33 | +pub(crate) fn stage0_unphantom<A>(a: A) -> A { a } |
| 34 | + |
13 | 35 | extern "Rust" {
|
14 | 36 | // These are the magic symbols to call the global allocator. rustc generates
|
15 | 37 | // them from the `#[global_allocator]` attribute if there is one, or uses the
|
@@ -37,10 +59,14 @@ extern "Rust" {
|
37 | 59 | ///
|
38 | 60 | /// Note: while this type is unstable, the functionality it provides can be
|
39 | 61 | /// accessed through the [free functions in `alloc`](index.html#functions).
|
| 62 | +#[cfg(not(test))] |
40 | 63 | #[unstable(feature = "allocator_api", issue = "32838")]
|
41 | 64 | #[derive(Copy, Clone, Default, Debug)]
|
42 | 65 | pub struct Global;
|
43 | 66 |
|
| 67 | +#[cfg(test)] |
| 68 | +pub use std::alloc::Global; |
| 69 | + |
44 | 70 | /// Allocate memory with the global allocator.
|
45 | 71 | ///
|
46 | 72 | /// This function forwards calls to the [`GlobalAlloc::alloc`] method
|
@@ -144,6 +170,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
|
144 | 170 | __rust_alloc_zeroed(layout.size(), layout.align())
|
145 | 171 | }
|
146 | 172 |
|
| 173 | +#[cfg(not(test))] |
147 | 174 | #[unstable(feature = "allocator_api", issue = "32838")]
|
148 | 175 | unsafe impl Alloc for Global {
|
149 | 176 | #[inline]
|
@@ -182,25 +209,27 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
|
182 | 209 | align as *mut u8
|
183 | 210 | } else {
|
184 | 211 | let layout = Layout::from_size_align_unchecked(size, align);
|
185 |
| - let ptr = alloc(layout); |
186 |
| - if !ptr.is_null() { |
187 |
| - ptr |
188 |
| - } else { |
189 |
| - handle_alloc_error(layout) |
| 212 | + match Global.alloc(layout) { |
| 213 | + Ok(ptr) => ptr.as_ptr(), |
| 214 | + Err(_) => handle_alloc_error(layout), |
190 | 215 | }
|
191 | 216 | }
|
192 | 217 | }
|
193 | 218 |
|
| 219 | +#[cfg(stage0)] |
| 220 | +type BoxFreeAlloc<A> = PhantomData<A>; |
| 221 | +#[cfg(not(stage0))] |
| 222 | +type BoxFreeAlloc<A> = A; |
| 223 | + |
194 | 224 | #[cfg_attr(not(test), lang = "box_free")]
|
195 | 225 | #[inline]
|
196 |
| -pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) { |
197 |
| - let ptr = ptr.as_ptr(); |
198 |
| - let size = size_of_val(&*ptr); |
199 |
| - let align = min_align_of_val(&*ptr); |
200 |
| - // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary. |
| 226 | +pub(crate) unsafe fn box_free<T: ?Sized, A: Stage0Alloc>(ptr: Unique<T>, a: BoxFreeAlloc<A>) { |
| 227 | + let size = size_of_val(&*ptr.as_ptr()); |
| 228 | + let align = min_align_of_val(&*ptr.as_ptr()); |
| 229 | + // We do not allocate for Box<T, A> when T is ZST, so deallocation is also not necessary. |
201 | 230 | if size != 0 {
|
202 | 231 | let layout = Layout::from_size_align_unchecked(size, align);
|
203 |
| - dealloc(ptr as *mut u8, layout); |
| 232 | + stage0_unphantom(a).dealloc(NonNull::from(ptr).cast(), layout); |
204 | 233 | }
|
205 | 234 | }
|
206 | 235 |
|
|
0 commit comments