Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Memoryblock with NonNull<[u8]> #75152

Merged
merged 3 commits into from
Aug 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,27 +164,27 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl AllocRef for Global {
#[inline]
fn alloc(&mut self, layout: Layout) -> Result<MemoryBlock, AllocErr> {
fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
let size = layout.size();
let ptr = if size == 0 {
layout.dangling()
} else {
// SAFETY: `layout` is non-zero in size,
unsafe { NonNull::new(alloc(layout)).ok_or(AllocErr)? }
};
Ok(MemoryBlock { ptr, size })
Ok(NonNull::slice_from_raw_parts(ptr, size))
}

#[inline]
fn alloc_zeroed(&mut self, layout: Layout) -> Result<MemoryBlock, AllocErr> {
fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
let size = layout.size();
let ptr = if size == 0 {
layout.dangling()
} else {
// SAFETY: `layout` is non-zero in size,
unsafe { NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr)? }
};
Ok(MemoryBlock { ptr, size })
Ok(NonNull::slice_from_raw_parts(ptr, size))
}

#[inline]
Expand All @@ -202,7 +202,7 @@ unsafe impl AllocRef for Global {
ptr: NonNull<u8>,
layout: Layout,
new_size: usize,
) -> Result<MemoryBlock, AllocErr> {
) -> Result<NonNull<[u8]>, AllocErr> {
debug_assert!(
new_size >= layout.size(),
"`new_size` must be greater than or equal to `layout.size()`"
Expand All @@ -212,14 +212,16 @@ unsafe impl AllocRef for Global {
// Other conditions must be upheld by the caller
unsafe {
match layout.size() {
old_size if old_size == new_size => Ok(MemoryBlock { ptr, size: new_size }),
old_size if old_size == new_size => {
Ok(NonNull::slice_from_raw_parts(ptr, new_size))
}
0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
old_size => {
// `realloc` probably checks for `new_size > size` or something similar.
intrinsics::assume(new_size > old_size);
let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
Ok(MemoryBlock { ptr, size: new_size })
Ok(NonNull::slice_from_raw_parts(ptr, new_size))
}
}
}
Expand All @@ -231,7 +233,7 @@ unsafe impl AllocRef for Global {
ptr: NonNull<u8>,
layout: Layout,
new_size: usize,
) -> Result<MemoryBlock, AllocErr> {
) -> Result<NonNull<[u8]>, AllocErr> {
debug_assert!(
new_size >= layout.size(),
"`new_size` must be greater than or equal to `layout.size()`"
Expand All @@ -241,15 +243,17 @@ unsafe impl AllocRef for Global {
// Other conditions must be upheld by the caller
unsafe {
match layout.size() {
old_size if old_size == new_size => Ok(MemoryBlock { ptr, size: new_size }),
old_size if old_size == new_size => {
Ok(NonNull::slice_from_raw_parts(ptr, new_size))
}
0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())),
old_size => {
// `realloc` probably checks for `new_size > size` or something similar.
intrinsics::assume(new_size > old_size);
let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
Ok(MemoryBlock { ptr, size: new_size })
Ok(NonNull::slice_from_raw_parts(ptr, new_size))
}
}
}
Expand All @@ -261,7 +265,7 @@ unsafe impl AllocRef for Global {
ptr: NonNull<u8>,
layout: Layout,
new_size: usize,
) -> Result<MemoryBlock, AllocErr> {
) -> Result<NonNull<[u8]>, AllocErr> {
let old_size = layout.size();
debug_assert!(
new_size <= old_size,
Expand All @@ -288,7 +292,7 @@ unsafe impl AllocRef for Global {
NonNull::new(raw_ptr).ok_or(AllocErr)?
};

Ok(MemoryBlock { ptr, size: new_size })
Ok(NonNull::slice_from_raw_parts(ptr, new_size))
}
}

Expand All @@ -300,7 +304,7 @@ unsafe impl AllocRef for Global {
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
match Global.alloc(layout) {
Ok(memory) => memory.ptr.as_ptr(),
Ok(ptr) => ptr.as_non_null_ptr().as_ptr(),
Err(_) => handle_alloc_error(layout),
}
}
Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/alloc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ use test::Bencher;
fn allocate_zeroed() {
unsafe {
let layout = Layout::from_size_align(1024, 1).unwrap();
let memory =
let ptr =
Global.alloc_zeroed(layout.clone()).unwrap_or_else(|_| handle_alloc_error(layout));

let mut i = memory.ptr.cast::<u8>().as_ptr();
let mut i = ptr.as_non_null_ptr().as_ptr();
let end = i.add(layout.size());
while i < end {
assert_eq!(*i, 0);
i = i.offset(1);
}
Global.dealloc(memory.ptr, layout);
Global.dealloc(ptr.as_non_null_ptr(), layout);
}
}

Expand Down
4 changes: 1 addition & 3 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ 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>>();
let ptr =
Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).ptr.cast();
let ptr = Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast();
unsafe { Box::from_raw(ptr.as_ptr()) }
}

Expand Down Expand Up @@ -226,7 +225,6 @@ impl<T> Box<T> {
let ptr = Global
.alloc_zeroed(layout)
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
.ptr
.cast();
unsafe { Box::from_raw(ptr.as_ptr()) }
}
Expand Down
3 changes: 3 additions & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
#![feature(negative_impls)]
#![feature(new_uninit)]
#![feature(nll)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(optin_builtin_traits)]
#![feature(or_patterns)]
#![feature(pattern)]
Expand All @@ -113,6 +114,8 @@
#![feature(rustc_attrs)]
#![feature(receiver_trait)]
#![feature(min_specialization)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(str_internals)]
Expand Down
30 changes: 15 additions & 15 deletions library/alloc/src/raw_vec.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![unstable(feature = "raw_vec_internals", reason = "implementation detail", issue = "none")]
#![doc(hidden)]

use core::alloc::{LayoutErr, MemoryBlock};
use core::alloc::LayoutErr;
use core::cmp;
use core::mem::{self, ManuallyDrop, MaybeUninit};
use core::ops::Drop;
Expand Down Expand Up @@ -186,14 +186,14 @@ impl<T, A: AllocRef> RawVec<T, A> {
AllocInit::Uninitialized => alloc.alloc(layout),
AllocInit::Zeroed => alloc.alloc_zeroed(layout),
};
let memory = match result {
Ok(memory) => memory,
let ptr = match result {
Ok(ptr) => ptr,
Err(_) => handle_alloc_error(layout),
};

Self {
ptr: unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) },
cap: Self::capacity_from_bytes(memory.size),
ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) },
cap: Self::capacity_from_bytes(ptr.len()),
alloc,
}
}
Expand Down Expand Up @@ -384,9 +384,9 @@ impl<T, A: AllocRef> RawVec<T, A> {
excess / mem::size_of::<T>()
}

fn set_memory(&mut self, memory: MemoryBlock) {
self.ptr = unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) };
self.cap = Self::capacity_from_bytes(memory.size);
fn set_ptr(&mut self, ptr: NonNull<[u8]>) {
self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) };
self.cap = Self::capacity_from_bytes(ptr.len());
}

// This method is usually instantiated many times. So we want it to be as
Expand Down Expand Up @@ -432,8 +432,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
let new_layout = Layout::array::<T>(cap);

// `finish_grow` is non-generic over `T`.
let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
self.set_memory(memory);
let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
self.set_ptr(ptr);
Ok(())
}

Expand All @@ -451,8 +451,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
let new_layout = Layout::array::<T>(cap);

// `finish_grow` is non-generic over `T`.
let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
self.set_memory(memory);
let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
self.set_ptr(ptr);
Ok(())
}

Expand All @@ -462,13 +462,13 @@ impl<T, A: AllocRef> RawVec<T, A> {
let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
let new_size = amount * mem::size_of::<T>();

let memory = unsafe {
let ptr = unsafe {
self.alloc.shrink(ptr, layout, new_size).map_err(|_| TryReserveError::AllocError {
layout: Layout::from_size_align_unchecked(new_size, layout.align()),
non_exhaustive: (),
})?
};
self.set_memory(memory);
self.set_ptr(ptr);
Ok(())
}
}
Expand All @@ -481,7 +481,7 @@ fn finish_grow<A>(
new_layout: Result<Layout, LayoutErr>,
current_memory: Option<(NonNull<u8>, Layout)>,
alloc: &mut A,
) -> Result<MemoryBlock, TryReserveError>
) -> Result<NonNull<[u8]>, TryReserveError>
where
A: AllocRef,
{
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/raw_vec/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn allocator_param() {
fuel: usize,
}
unsafe impl AllocRef for BoundedAlloc {
fn alloc(&mut self, layout: Layout) -> Result<MemoryBlock, AllocErr> {
fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
let size = layout.size();
if size > self.fuel {
return Err(AllocErr);
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,10 +928,10 @@ impl<T: ?Sized> Rc<T> {
let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align();

// Allocate for the layout.
let mem = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));

// Initialize the RcBox
let inner = mem_to_rcbox(mem.ptr.as_ptr());
let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr());
unsafe {
debug_assert_eq!(Layout::for_value(&*inner), layout);

Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,10 +883,10 @@ impl<T: ?Sized> Arc<T> {
// reference (see #54908).
let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();

let mem = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));

// Initialize the ArcInner
let inner = mem_to_arcinner(mem.ptr.as_ptr());
let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr());
debug_assert_eq!(unsafe { Layout::for_value(&*inner) }, layout);

unsafe {
Expand Down Expand Up @@ -986,7 +986,7 @@ impl<T> Arc<[T]> {
let slice = from_raw_parts_mut(self.elems, self.n_elems);
ptr::drop_in_place(slice);

Global.dealloc(self.mem.cast(), self.layout);
Global.dealloc(self.mem, self.layout);
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions library/alloc/tests/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,23 @@ fn check_overalign_requests<T: AllocRef>(mut allocator: T) {
unsafe {
let pointers: Vec<_> = (0..iterations)
.map(|_| {
allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap().ptr
allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
})
.collect();
for &ptr in &pointers {
assert_eq!(
(ptr.as_ptr() as usize) % align,
(ptr.as_non_null_ptr().as_ptr() as usize) % align,
0,
"Got a pointer less aligned than requested"
)
}

// Clean up
for &ptr in &pointers {
allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
allocator.dealloc(
ptr.as_non_null_ptr(),
Layout::from_size_align(size, align).unwrap(),
)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions library/alloc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#![feature(associated_type_bounds)]
#![feature(binary_heap_into_iter_sorted)]
#![feature(binary_heap_drain_sorted)]
#![feature(slice_ptr_get)]
#![feature(split_inclusive)]
#![feature(binary_heap_retain)]

Expand Down
Loading