1
Fork 0

Preparation for allocator aware Box

This commit is contained in:
Tim Diekmann 2020-02-11 13:02:51 +01:00
parent b6690a8c35
commit 76aa29ff5e
No known key found for this signature in database
GPG key ID: C6F230B5E341BEFB
2 changed files with 28 additions and 21 deletions

View file

@ -200,21 +200,27 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
align as *mut u8 align as *mut u8
} else { } else {
let layout = Layout::from_size_align_unchecked(size, align); let layout = Layout::from_size_align_unchecked(size, align);
let ptr = alloc(layout); match Global.alloc(layout) {
if !ptr.is_null() { ptr } else { handle_alloc_error(layout) } Ok(ptr) => ptr.as_ptr(),
Err(_) => handle_alloc_error(layout),
}
} }
} }
#[cfg_attr(not(test), lang = "box_free")] #[cfg_attr(not(test), lang = "box_free")]
#[inline] #[inline]
// This signature has to be the same as `Box`, otherwise an ICE will happen.
// When an additional parameter to `Box` is added (like `A: AllocRef`), this has to be added here as
// well.
// For example if `Box` is changed to `struct Box<T: ?Sized, A: AllocRef>(Unique<T>, A)`,
// this function has to be changed to `fn box_free<T: ?Sized, A: AllocRef>(Unique<T>, A)` as well.
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) { pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
let ptr = ptr.as_ptr(); let size = size_of_val(ptr.as_ref());
let size = size_of_val(&*ptr); let align = min_align_of_val(ptr.as_ref());
let align = min_align_of_val(&*ptr);
// We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary. // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
if size != 0 { if size != 0 {
let layout = Layout::from_size_align_unchecked(size, align); let layout = Layout::from_size_align_unchecked(size, align);
dealloc(ptr as *mut u8, layout); Global.dealloc(ptr.cast().into(), layout);
} }
} }

View file

@ -196,12 +196,14 @@ impl<T> Box<T> {
#[unstable(feature = "new_uninit", issue = "63291")] #[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> { pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
let layout = alloc::Layout::new::<mem::MaybeUninit<T>>(); let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
if layout.size() == 0 { unsafe {
return Box(NonNull::dangling().into()); let ptr = if layout.size() == 0 {
NonNull::dangling()
} else {
Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast()
};
Box::from_raw(ptr.as_ptr())
} }
let ptr =
unsafe { Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)) };
Box(ptr.cast().into())
} }
/// Constructs a new `Box` with uninitialized contents, with the memory /// Constructs a new `Box` with uninitialized contents, with the memory
@ -264,15 +266,14 @@ impl<T> Box<[T]> {
#[unstable(feature = "new_uninit", issue = "63291")] #[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> { pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap(); let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
let ptr = if layout.size() == 0 { unsafe {
NonNull::dangling() let ptr = if layout.size() == 0 {
} else { NonNull::dangling()
unsafe { } else {
Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast() Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast()
} };
}; Box::from_raw(slice::from_raw_parts_mut(ptr.as_ptr(), len))
let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) }; }
Box(Unique::from(slice))
} }
} }
@ -308,7 +309,7 @@ impl<T> Box<mem::MaybeUninit<T>> {
#[unstable(feature = "new_uninit", issue = "63291")] #[unstable(feature = "new_uninit", issue = "63291")]
#[inline] #[inline]
pub unsafe fn assume_init(self) -> Box<T> { pub unsafe fn assume_init(self) -> Box<T> {
Box(Box::into_unique(self).cast()) Box::from_raw(Box::into_raw(self) as *mut T)
} }
} }
@ -346,7 +347,7 @@ impl<T> Box<[mem::MaybeUninit<T>]> {
#[unstable(feature = "new_uninit", issue = "63291")] #[unstable(feature = "new_uninit", issue = "63291")]
#[inline] #[inline]
pub unsafe fn assume_init(self) -> Box<[T]> { pub unsafe fn assume_init(self) -> Box<[T]> {
Box(Unique::new_unchecked(Box::into_raw(self) as _)) Box::from_raw(Box::into_raw(self) as *mut [T])
} }
} }