Skip to content

Commit

Permalink
Associate an allocator to boxes
Browse files Browse the repository at this point in the history
This turns `Box<T>` into `Box<T, A: Alloc = Global>`. This is a
minimalist change to achieve this, not touching anything that could have
backwards incompatible consequences like requiring type annotations in
places where they currently aren't required,
per rust-lang#50822 (comment)
  • Loading branch information
glandium committed Oct 17, 2018
1 parent bef62cc commit aa19e43
Show file tree
Hide file tree
Showing 14 changed files with 193 additions and 99 deletions.
17 changes: 10 additions & 7 deletions src/liballoc/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,14 @@ extern "Rust" {
/// This type implements the [`Alloc`] trait by forwarding calls
/// to the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
#[cfg(not(test))]
#[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Copy, Clone, Default, Debug)]
pub struct Global;

#[cfg(test)]
pub use std::alloc::Global;

/// Allocate memory with the global allocator.
///
/// This function forwards calls to the [`GlobalAlloc::alloc`] method
Expand Down Expand Up @@ -147,6 +151,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
__rust_alloc_zeroed(layout.size(), layout.align())
}

#[cfg(not(test))]
#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl Alloc for Global {
#[inline]
Expand Down Expand Up @@ -185,25 +190,23 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
align as *mut u8
} else {
let layout = Layout::from_size_align_unchecked(size, align);
let ptr = alloc(layout);
if !ptr.is_null() {
ptr
} else {
handle_alloc_error(layout)
match Global.alloc(layout) {
Ok(ptr) => ptr.as_ptr(),
Err(_) => handle_alloc_error(layout),
}
}
}

#[cfg_attr(not(test), lang = "box_free")]
#[inline]
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
pub(crate) unsafe fn box_free<T: ?Sized, A: Alloc>(ptr: Unique<T>, mut a: A) {
let ptr = ptr.as_ptr();
let size = size_of_val(&*ptr);
let align = min_align_of_val(&*ptr);
// We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
if size != 0 {
let layout = Layout::from_size_align_unchecked(size, align);
dealloc(ptr as *mut u8, layout);
a.dealloc(NonNull::new_unchecked(ptr).cast(), layout);
}
}

Expand Down
Loading

0 comments on commit aa19e43

Please sign in to comment.