Use alloc_zeroed in {Rc,Arc}::new_zeroed

This commit is contained in:
Amos Onn 2020-08-05 02:49:21 +02:00
parent 119d2a1a98
commit 361f668c49
2 changed files with 48 additions and 30 deletions

View File

@ -250,7 +250,7 @@ use core::pin::Pin;
use core::ptr::{self, NonNull};
use core::slice::from_raw_parts_mut;
use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout};
use crate::alloc::{box_free, handle_alloc_error, AllocErr, AllocRef, Global, Layout};
use crate::borrow::{Cow, ToOwned};
use crate::string::String;
use crate::vec::Vec;
@ -352,9 +352,11 @@ impl<T> Rc<T> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
unsafe {
Rc::from_ptr(Rc::allocate_for_layout(Layout::new::<T>(), |mem| {
mem as *mut RcBox<mem::MaybeUninit<T>>
}))
Rc::from_ptr(Rc::allocate_for_layout(
Layout::new::<T>(),
|layout| Global.alloc(layout),
|mem| mem as *mut RcBox<mem::MaybeUninit<T>>,
))
}
}
@ -381,9 +383,11 @@ impl<T> Rc<T> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
unsafe {
let mut uninit = Self::new_uninit();
ptr::write_bytes::<T>(Rc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1);
uninit
Rc::from_ptr(Rc::allocate_for_layout(
Layout::new::<T>(),
|layout| Global.alloc_zeroed(layout),
|mem| mem as *mut RcBox<mem::MaybeUninit<T>>,
))
}
}
@ -919,6 +923,7 @@ impl<T: ?Sized> Rc<T> {
/// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
unsafe fn allocate_for_layout(
value_layout: Layout,
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocErr>,
mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox<T>,
) -> *mut RcBox<T> {
// Calculate layout using the given value layout.
@ -928,7 +933,7 @@ impl<T: ?Sized> Rc<T> {
let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align();
// Allocate for the layout.
let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout));
// Initialize the RcBox
let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr());
@ -946,9 +951,11 @@ impl<T: ?Sized> Rc<T> {
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
// Allocate for the `RcBox<T>` using the given value.
unsafe {
Self::allocate_for_layout(Layout::for_value(&*ptr), |mem| {
set_data_ptr(ptr as *mut T, mem) as *mut RcBox<T>
})
Self::allocate_for_layout(
Layout::for_value(&*ptr),
|layout| Global.alloc(layout),
|mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox<T>,
)
}
}
@ -979,9 +986,11 @@ impl<T> Rc<[T]> {
/// Allocates an `RcBox<[T]>` with the given length.
unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> {
unsafe {
Self::allocate_for_layout(Layout::array::<T>(len).unwrap(), |mem| {
ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>
})
Self::allocate_for_layout(
Layout::array::<T>(len).unwrap(),
|layout| Global.alloc(layout),
|mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>,
)
}
}
}
@ -2090,7 +2099,7 @@ impl<T: ?Sized> AsRef<T> for Rc<T> {
#[stable(feature = "pin", since = "1.33.0")]
impl<T: ?Sized> Unpin for Rc<T> {}
/// Get the offset within an `ArcInner` for
/// Get the offset within an `RcBoRcBox` for
/// a payload of type described by a pointer.
///
/// # Safety

View File

@ -23,7 +23,7 @@ use core::slice::from_raw_parts_mut;
use core::sync::atomic;
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout};
use crate::alloc::{box_free, handle_alloc_error, AllocErr, AllocRef, Global, Layout};
use crate::borrow::{Cow, ToOwned};
use crate::boxed::Box;
use crate::rc::is_dangling;
@ -352,9 +352,11 @@ impl<T> Arc<T> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
unsafe {
Arc::from_ptr(Arc::allocate_for_layout(Layout::new::<T>(), |mem| {
mem as *mut ArcInner<mem::MaybeUninit<T>>
}))
Arc::from_ptr(Arc::allocate_for_layout(
Layout::new::<T>(),
|layout| Global.alloc(layout),
|mem| mem as *mut ArcInner<mem::MaybeUninit<T>>,
))
}
}
@ -381,9 +383,11 @@ impl<T> Arc<T> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
unsafe {
let mut uninit = Self::new_uninit();
ptr::write_bytes::<T>(Arc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1);
uninit
Arc::from_ptr(Arc::allocate_for_layout(
Layout::new::<T>(),
|layout| Global.alloc_zeroed(layout),
|mem| mem as *mut ArcInner<mem::MaybeUninit<T>>,
))
}
}
@ -437,7 +441,7 @@ impl<T> Arc<T> {
}
impl<T> Arc<[T]> {
/// Constructs a new reference-counted slice with uninitialized contents.
/// Constructs a new atomically reference-counted slice with uninitialized contents.
///
/// # Examples
///
@ -875,6 +879,7 @@ impl<T: ?Sized> Arc<T> {
/// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
unsafe fn allocate_for_layout(
value_layout: Layout,
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocErr>,
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
) -> *mut ArcInner<T> {
// Calculate layout using the given value layout.
@ -883,7 +888,7 @@ impl<T: ?Sized> Arc<T> {
// reference (see #54908).
let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();
let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout));
// Initialize the ArcInner
let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr());
@ -901,9 +906,11 @@ impl<T: ?Sized> Arc<T> {
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
// Allocate for the `ArcInner<T>` using the given value.
unsafe {
Self::allocate_for_layout(Layout::for_value(&*ptr), |mem| {
set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>
})
Self::allocate_for_layout(
Layout::for_value(&*ptr),
|layout| Global.alloc(layout),
|mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>,
)
}
}
@ -934,9 +941,11 @@ impl<T> Arc<[T]> {
/// Allocates an `ArcInner<[T]>` with the given length.
unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> {
unsafe {
Self::allocate_for_layout(Layout::array::<T>(len).unwrap(), |mem| {
ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>
})
Self::allocate_for_layout(
Layout::array::<T>(len).unwrap(),
|layout| Global.alloc(layout),
|mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>,
)
}
}
}