diff --git a/crossbeam-epoch/src/atomic.rs b/crossbeam-epoch/src/atomic.rs index bf149e5c8..b31926dc1 100644 --- a/crossbeam-epoch/src/atomic.rs +++ b/crossbeam-epoch/src/atomic.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; +use core::alloc::Layout; use core::borrow::{Borrow, BorrowMut}; use core::cmp; use core::fmt; @@ -7,8 +9,6 @@ use core::ops::{Deref, DerefMut}; use core::ptr; use core::slice; -use crate::alloc::alloc; -use crate::alloc::boxed::Box; use crate::guard::Guard; #[cfg(not(miri))] use crate::primitive::sync::atomic::AtomicUsize; @@ -191,9 +191,6 @@ impl Pointable for T { /// /// Elements are not present in the type, but they will be in the allocation. /// ``` -/// -// TODO(@jeehoonkang): once we bump the minimum required Rust version to 1.44 or newer, use -// [`alloc::alloc::Layout::extend`] instead. #[repr(C)] struct Array { /// The number of elements (not the number of bytes). @@ -201,21 +198,29 @@ struct Array { elements: [MaybeUninit; 0], } +impl Array { + fn layout(len: usize) -> Layout { + Layout::new::() + .extend(Layout::array::>(len).unwrap()) + .unwrap() + .0 + .pad_to_align() + } +} + impl Pointable for [MaybeUninit] { const ALIGN: usize = mem::align_of::>(); type Init = usize; unsafe fn init(len: Self::Init) -> *mut () { - let size = mem::size_of::>() + mem::size_of::>() * len; - let align = mem::align_of::>(); - let layout = alloc::Layout::from_size_align(size, align).unwrap(); + let layout = Array::::layout(len); unsafe { - let ptr = alloc::alloc(layout).cast::>(); + let ptr = alloc::alloc::alloc(layout).cast::>(); if ptr.is_null() { - alloc::handle_alloc_error(layout); + alloc::alloc::handle_alloc_error(layout); } - (*ptr).len = len; + ptr::addr_of_mut!((*ptr).len).write(len); ptr.cast::<()>() } } @@ -236,11 +241,9 @@ impl Pointable for [MaybeUninit] { unsafe fn drop(ptr: *mut ()) { unsafe { - let array = &*ptr.cast::>(); - let size = mem::size_of::>() + mem::size_of::>() * array.len; - let align = mem::align_of::>(); - let layout = alloc::Layout::from_size_align(size, align).unwrap(); - alloc::dealloc(ptr.cast::(), layout); + let len = (*ptr.cast::>()).len; + let layout = Array::::layout(len); + alloc::alloc::dealloc(ptr.cast::(), layout); } } } diff --git a/crossbeam-skiplist/src/base.rs b/crossbeam-skiplist/src/base.rs index 2155dc2fb..7b0fb87cf 100644 --- a/crossbeam-skiplist/src/base.rs +++ b/crossbeam-skiplist/src/base.rs @@ -98,18 +98,18 @@ impl Node { /// with null pointers. However, the key and the value will be left uninitialized, and that is /// why this function is unsafe. unsafe fn alloc(height: usize, ref_count: usize) -> *mut Self { + let layout = Self::get_layout(height); unsafe { - let layout = Self::get_layout(height); let ptr = alloc(layout).cast::(); if ptr.is_null() { handle_alloc_error(layout); } - ptr::write( - &mut (*ptr).refs_and_height, - AtomicUsize::new((height - 1) | ref_count << HEIGHT_BITS), - ); - ptr::write_bytes((*ptr).tower.pointers.as_mut_ptr(), 0, height); + ptr::addr_of_mut!((*ptr).refs_and_height) + .write(AtomicUsize::new((height - 1) | ref_count << HEIGHT_BITS)); + ptr::addr_of_mut!((*ptr).tower.pointers) + .cast::>() + .write_bytes(0, height); ptr } } @@ -126,14 +126,14 @@ impl Node { } /// Returns the layout of a node with the given `height`. - unsafe fn get_layout(height: usize) -> Layout { + fn get_layout(height: usize) -> Layout { assert!((1..=MAX_HEIGHT).contains(&height)); - let size_self = mem::size_of::(); - let align_self = mem::align_of::(); - let size_pointer = mem::size_of::>(); - - unsafe { Layout::from_size_align_unchecked(size_self + size_pointer * height, align_self) } + Layout::new::() + .extend(Layout::array::>(height).unwrap()) + .unwrap() + .0 + .pad_to_align() } /// Returns the height of this node's tower. @@ -912,8 +912,8 @@ where let n = Node::::alloc(height, 2); // Write the key and the value into the node. - ptr::write(&mut (*n).key, key); - ptr::write(&mut (*n).value, value); + ptr::addr_of_mut!((*n).key).write(key); + ptr::addr_of_mut!((*n).value).write(value); (Shared::>::from(n as *const _), &*n) };