Skip to content

Commit 3cbdf18

Browse files
committed
Associate an allocator to boxes
This turns `Box<T>` into `Box<T, A = Global>`, with a `A: Alloc` bound for impls. Ideally, inherent methods like `Box::new` would be applied to `Box<T, A: Alloc + Default>`, but as of now, that would be backwards incompatible because it would require type annotations in places where they currently aren't required. `impl FromIterator` is not covered because it relies on `Vec`, which would need allocator awareness. `DispatchFromDyn` is left out or being generic over `A` because there is no bound that would make it work currently. `FnBox` is left out because it's related to `DispatchFromDyn`.
1 parent 98ebb0c commit 3cbdf18

File tree

10 files changed

+210
-119
lines changed

10 files changed

+210
-119
lines changed

src/liballoc/alloc.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ extern "Rust" {
4040
/// accessed through the [free functions in `alloc`](index.html#functions).
4141
///
4242
/// [`Alloc`]: trait.Alloc.html
43+
#[cfg(not(test))]
4344
#[unstable(feature = "allocator_api", issue = "32838")]
4445
#[derive(Copy, Clone, Default, Debug)]
4546
pub struct Global;
4647

48+
#[cfg(test)]
49+
pub use std::alloc::Global;
50+
4751
/// Allocate memory with the global allocator.
4852
///
4953
/// This function forwards calls to the [`GlobalAlloc::alloc`] method
@@ -163,6 +167,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
163167
__rust_alloc_zeroed(layout.size(), layout.align())
164168
}
165169

170+
#[cfg(not(test))]
166171
#[unstable(feature = "allocator_api", issue = "32838")]
167172
unsafe impl Alloc for Global {
168173
#[inline]
@@ -201,25 +206,22 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
201206
align as *mut u8
202207
} else {
203208
let layout = Layout::from_size_align_unchecked(size, align);
204-
let ptr = alloc(layout);
205-
if !ptr.is_null() {
206-
ptr
207-
} else {
208-
handle_alloc_error(layout)
209+
match Global.alloc(layout) {
210+
Ok(ptr) => ptr.as_ptr(),
211+
Err(_) => handle_alloc_error(layout),
209212
}
210213
}
211214
}
212215

213216
#[cfg_attr(not(test), lang = "box_free")]
214217
#[inline]
215-
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
216-
let ptr = ptr.as_ptr();
217-
let size = size_of_val(&*ptr);
218-
let align = min_align_of_val(&*ptr);
219-
// We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
218+
pub(crate) unsafe fn box_free<T: ?Sized, A: Alloc>(ptr: Unique<T>, mut a: A) {
219+
let size = size_of_val(&*ptr.as_ptr());
220+
let align = min_align_of_val(&*ptr.as_ptr());
221+
// We do not allocate for Box<T, A> when T is ZST, so deallocation is also not necessary.
220222
if size != 0 {
221223
let layout = Layout::from_size_align_unchecked(size, align);
222-
dealloc(ptr as *mut u8, layout);
224+
a.dealloc(NonNull::from(ptr).cast(), layout);
223225
}
224226
}
225227

0 commit comments

Comments
 (0)