From 361f668c4996c1f21aee39ea1a105a3067612c11 Mon Sep 17 00:00:00 2001 From: Amos Onn Date: Wed, 5 Aug 2020 02:49:21 +0200 Subject: [PATCH 1/3] Use alloc_zeroed in {Rc,Arc}::new_zeroed --- library/alloc/src/rc.rs | 39 ++++++++++++++++++++++++--------------- library/alloc/src/sync.rs | 39 ++++++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index d0a47ccea0a..9183beca55c 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -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 Rc { #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit() -> Rc> { unsafe { - Rc::from_ptr(Rc::allocate_for_layout(Layout::new::(), |mem| { - mem as *mut RcBox> - })) + Rc::from_ptr(Rc::allocate_for_layout( + Layout::new::(), + |layout| Global.alloc(layout), + |mem| mem as *mut RcBox>, + )) } } @@ -381,9 +383,11 @@ impl Rc { #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_zeroed() -> Rc> { unsafe { - let mut uninit = Self::new_uninit(); - ptr::write_bytes::(Rc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1); - uninit + Rc::from_ptr(Rc::allocate_for_layout( + Layout::new::(), + |layout| Global.alloc_zeroed(layout), + |mem| mem as *mut RcBox>, + )) } } @@ -919,6 +923,7 @@ impl Rc { /// and must return back a (potentially fat)-pointer for the `RcBox`. unsafe fn allocate_for_layout( value_layout: Layout, + allocate: impl FnOnce(Layout) -> Result, AllocErr>, mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox, ) -> *mut RcBox { // Calculate layout using the given value layout. @@ -928,7 +933,7 @@ impl Rc { let layout = Layout::new::>().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 Rc { unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { // Allocate for the `RcBox` 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 - }) + Self::allocate_for_layout( + Layout::for_value(&*ptr), + |layout| Global.alloc(layout), + |mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox, + ) } } @@ -979,9 +986,11 @@ impl 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::(len).unwrap(), |mem| { - ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]> - }) + Self::allocate_for_layout( + Layout::array::(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 AsRef for Rc { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Rc {} -/// Get the offset within an `ArcInner` for +/// Get the offset within an `RcBoRcBox` for /// a payload of type described by a pointer. /// /// # Safety diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index b3763303137..308b2e71c85 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -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 Arc { #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit() -> Arc> { unsafe { - Arc::from_ptr(Arc::allocate_for_layout(Layout::new::(), |mem| { - mem as *mut ArcInner> - })) + Arc::from_ptr(Arc::allocate_for_layout( + Layout::new::(), + |layout| Global.alloc(layout), + |mem| mem as *mut ArcInner>, + )) } } @@ -381,9 +383,11 @@ impl Arc { #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_zeroed() -> Arc> { unsafe { - let mut uninit = Self::new_uninit(); - ptr::write_bytes::(Arc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1); - uninit + Arc::from_ptr(Arc::allocate_for_layout( + Layout::new::(), + |layout| Global.alloc_zeroed(layout), + |mem| mem as *mut ArcInner>, + )) } } @@ -437,7 +441,7 @@ impl Arc { } impl 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 Arc { /// and must return back a (potentially fat)-pointer for the `ArcInner`. unsafe fn allocate_for_layout( value_layout: Layout, + allocate: impl FnOnce(Layout) -> Result, AllocErr>, mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, ) -> *mut ArcInner { // Calculate layout using the given value layout. @@ -883,7 +888,7 @@ impl Arc { // reference (see #54908). let layout = Layout::new::>().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 Arc { unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner { // Allocate for the `ArcInner` 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 - }) + Self::allocate_for_layout( + Layout::for_value(&*ptr), + |layout| Global.alloc(layout), + |mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner, + ) } } @@ -934,9 +941,11 @@ impl 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::(len).unwrap(), |mem| { - ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]> - }) + Self::allocate_for_layout( + Layout::array::(len).unwrap(), + |layout| Global.alloc(layout), + |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>, + ) } } } From ab204c5b20742d153968390bae0f3ff1095e2946 Mon Sep 17 00:00:00 2001 From: Amos Onn Date: Wed, 5 Aug 2020 02:54:59 +0200 Subject: [PATCH 2/3] Add {Box,Rc,Arc}::new_zeroed_slice --- library/alloc/src/boxed.rs | 23 +++++++++++++++++++++++ library/alloc/src/rc.rs | 34 ++++++++++++++++++++++++++++++++++ library/alloc/src/sync.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 5e304beff78..9183edef30d 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -273,6 +273,29 @@ impl Box<[T]> { pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit]> { unsafe { RawVec::with_capacity(len).into_box(len) } } + + /// Constructs a new boxed slice with uninitialized contents, with the memory + /// being filled with `0` bytes. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage + /// of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_uninit)] + /// + /// let values = Box::<[u32]>::new_zeroed_slice(3); + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [0, 0, 0]) + /// ``` + /// + /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed + #[unstable(feature = "new_uninit", issue = "63291")] + pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { + unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } + } } impl Box> { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 9183beca55c..c847cb7e1f1 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -469,6 +469,40 @@ impl Rc<[T]> { pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit]> { unsafe { Rc::from_ptr(Rc::allocate_for_slice(len)) } } + + /// Constructs a new reference-counted slice with uninitialized contents, with the memory being + /// filled with `0` bytes. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and + /// incorrect usage of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_uninit)] + /// + /// use std::rc::Rc; + /// + /// let values = Rc::<[u32]>::new_zeroed_slice(3); + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [0, 0, 0]) + /// ``` + /// + /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed + #[unstable(feature = "new_uninit", issue = "63291")] + pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit]> { + unsafe { + Rc::from_ptr(Rc::allocate_for_layout( + Layout::array::(len).unwrap(), + |layout| Global.alloc_zeroed(layout), + |mem| { + ptr::slice_from_raw_parts_mut(mem as *mut T, len) + as *mut RcBox<[mem::MaybeUninit]> + }, + )) + } + } } impl Rc> { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 308b2e71c85..9daccbc336b 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -468,6 +468,40 @@ impl Arc<[T]> { pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit]> { unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) } } + + /// Constructs a new atomically reference-counted slice with uninitialized contents, with the memory being + /// filled with `0` bytes. + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and + /// incorrect usage of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_uninit)] + /// + /// use std::sync::Arc; + /// + /// let values = Arc::<[u32]>::new_zeroed_slice(3); + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [0, 0, 0]) + /// ``` + /// + /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed + #[unstable(feature = "new_uninit", issue = "63291")] + pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit]> { + unsafe { + Arc::from_ptr(Arc::allocate_for_layout( + Layout::array::(len).unwrap(), + |layout| Global.alloc_zeroed(layout), + |mem| { + ptr::slice_from_raw_parts_mut(mem as *mut T, len) + as *mut ArcInner<[mem::MaybeUninit]> + }, + )) + } + } } impl Arc> { From 5aba816672d08a076eaa8005a109968af8ce1083 Mon Sep 17 00:00:00 2001 From: amosonn Date: Fri, 21 Aug 2020 22:25:09 +0200 Subject: [PATCH 3/3] Update rc.rs --- library/alloc/src/rc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index c847cb7e1f1..1b5ee20516b 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2133,7 +2133,7 @@ impl AsRef for Rc { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Rc {} -/// Get the offset within an `RcBoRcBox` for +/// Get the offset within an `RcBox` for /// a payload of type described by a pointer. /// /// # Safety