From 3ade8ae6608a9d371580e5e8d68c26a4e3e897fb Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Sun, 29 Mar 2020 01:47:05 +0100 Subject: [PATCH] Implement `init` and `init_offset` on `AllocInit` and mark it unsafe --- src/liballoc/alloc.rs | 8 +++--- src/libcore/alloc/mod.rs | 53 +++++++++++++++++++++++----------------- src/libstd/alloc.rs | 8 +++--- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 67927629ed3..66575e3ef55 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -214,12 +214,12 @@ unsafe impl AllocRef for Global { self.alloc(new_layout, init) } ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size > old_size` or something similar. + // `realloc` probably checks for `new_size > size` or something similar. intrinsics::assume(new_size > size); let ptr = realloc(ptr.as_ptr(), layout, new_size); - let mut memory = + let memory = MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }; - memory.init_offset(init, size); + init.init_offset(memory, size); Ok(memory) } } @@ -250,7 +250,7 @@ unsafe impl AllocRef for Global { Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) } ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size < old_size` or something similar. + // `realloc` probably checks for `new_size < size` or something similar. intrinsics::assume(new_size < size); let ptr = realloc(ptr.as_ptr(), layout, new_size); Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }) diff --git a/src/libcore/alloc/mod.rs b/src/libcore/alloc/mod.rs index f2f12a98fa6..cc8c730b63a 100644 --- a/src/libcore/alloc/mod.rs +++ b/src/libcore/alloc/mod.rs @@ -41,27 +41,22 @@ pub enum AllocInit { Zeroed, } -/// Represents a block of allocated memory returned by an allocator. -#[derive(Debug, Copy, Clone)] -#[unstable(feature = "allocator_api", issue = "32838")] -pub struct MemoryBlock { - pub ptr: NonNull, - pub size: usize, -} - -impl MemoryBlock { - /// Initialize the memory block like specified by `init`. +impl AllocInit { + /// Initialize the specified memory block. /// - /// This behaves like calling [`MemoryBlock::initialize_offset(ptr, layout, 0)`][off]. + /// This behaves like calling [`AllocInit::initialize_offset(ptr, layout, 0)`][off]. /// - /// [off]: MemoryBlock::init_offset + /// [off]: AllocInit::init_offset /// - /// [*fit*]: trait.AllocRef.html#memory-fitting + /// # Safety + /// + /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes. + /// + /// [valid]: ../ptr/index.html#safety #[inline] #[unstable(feature = "allocator_api", issue = "32838")] - pub fn init(&mut self, init: AllocInit) { - // SAFETY: 0 is always smaller or equal to the size - unsafe { self.init_offset(init, 0) } + pub unsafe fn init(self, memory: MemoryBlock) { + self.init_offset(memory, 0) } /// Initialize the memory block like specified by `init` at the specified `offset`. @@ -71,20 +66,34 @@ impl MemoryBlock { /// /// # Safety /// - /// * `offset` must be smaller than or equal to `size()` + /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes. + /// * `offset` must be smaller than or equal to `memory.size` /// - /// [*fit*]: trait.AllocRef.html#memory-fitting + /// [valid]: ../ptr/index.html#safety #[inline] #[unstable(feature = "allocator_api", issue = "32838")] - pub unsafe fn init_offset(&mut self, init: AllocInit, offset: usize) { - debug_assert!(offset <= self.size, "`offset` must be smaller than or equal to `size()`"); - match init { + pub unsafe fn init_offset(self, memory: MemoryBlock, offset: usize) { + debug_assert!( + offset <= memory.size, + "`offset` must be smaller than or equal to `memory.size`" + ); + match self { AllocInit::Uninitialized => (), - AllocInit::Zeroed => self.ptr.as_ptr().add(offset).write_bytes(0, self.size - offset), + AllocInit::Zeroed => { + memory.ptr.as_ptr().add(offset).write_bytes(0, memory.size - offset) + } } } } +/// Represents a block of allocated memory returned by an allocator. +#[derive(Debug, Copy, Clone)] +#[unstable(feature = "allocator_api", issue = "32838")] +pub struct MemoryBlock { + pub ptr: NonNull, + pub size: usize, +} + /// A placement constraint when growing or shrinking an existing allocation. #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[unstable(feature = "allocator_api", issue = "32838")] diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 843c46775af..8df4666c536 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -188,12 +188,12 @@ unsafe impl AllocRef for System { self.alloc(new_layout, init) } ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size > old_size` or something similar. + // `realloc` probably checks for `new_size > size` or something similar. intrinsics::assume(new_size > size); let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size); - let mut memory = + let memory = MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }; - memory.init_offset(init, size); + init.init_offset(memory, size); Ok(memory) } } @@ -224,7 +224,7 @@ unsafe impl AllocRef for System { Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) } ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size < old_size` or something similar. + // `realloc` probably checks for `new_size < size` or something similar. intrinsics::assume(new_size < size); let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size); Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })