Skip to content

Commit

Permalink
Preparation for allocator aware Box
Browse files Browse the repository at this point in the history
  • Loading branch information
TimDiekmann committed Feb 11, 2020
1 parent b6690a8 commit 76aa29f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
18 changes: 12 additions & 6 deletions src/liballoc/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,21 +200,27 @@ 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]
// 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>) {
let ptr = ptr.as_ptr();
let size = size_of_val(&*ptr);
let align = min_align_of_val(&*ptr);
let size = size_of_val(ptr.as_ref());
let align = min_align_of_val(ptr.as_ref());
// 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);
Global.dealloc(ptr.cast().into(), layout);
}
}

Expand Down
31 changes: 16 additions & 15 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,14 @@ impl<T> Box<T> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
if layout.size() == 0 {
return Box(NonNull::dangling().into());
unsafe {
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
Expand Down Expand Up @@ -264,15 +266,14 @@ impl<T> Box<[T]> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
let ptr = if layout.size() == 0 {
NonNull::dangling()
} else {
unsafe {
unsafe {
let ptr = if layout.size() == 0 {
NonNull::dangling()
} else {
Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast()
}
};
let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) };
Box(Unique::from(slice))
};
Box::from_raw(slice::from_raw_parts_mut(ptr.as_ptr(), len))
}
}
}

Expand Down Expand Up @@ -308,7 +309,7 @@ impl<T> Box<mem::MaybeUninit<T>> {
#[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
pub unsafe fn assume_init(self) -> Box<T> {
Box(Box::into_unique(self).cast())
Box::from_raw(Box::into_raw(self) as *mut T)
}
}

Expand Down Expand Up @@ -346,7 +347,7 @@ impl<T> Box<[mem::MaybeUninit<T>]> {
#[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
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])
}
}

Expand Down

0 comments on commit 76aa29f

Please sign in to comment.