1
Fork 0

Implement init and init_offset on AllocInit and mark it unsafe

This commit is contained in:
Tim Diekmann 2020-03-29 01:47:05 +01:00
parent bf6a46db31
commit 3ade8ae660
3 changed files with 39 additions and 30 deletions

View file

@ -214,12 +214,12 @@ unsafe impl AllocRef for Global {
self.alloc(new_layout, init) self.alloc(new_layout, init)
} }
ReallocPlacement::MayMove => { 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); intrinsics::assume(new_size > size);
let ptr = realloc(ptr.as_ptr(), layout, new_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 }; MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
memory.init_offset(init, size); init.init_offset(memory, size);
Ok(memory) Ok(memory)
} }
} }
@ -250,7 +250,7 @@ unsafe impl AllocRef for Global {
Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
} }
ReallocPlacement::MayMove => { 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); intrinsics::assume(new_size < size);
let ptr = realloc(ptr.as_ptr(), layout, new_size); let ptr = realloc(ptr.as_ptr(), layout, new_size);
Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }) Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })

View file

@ -41,27 +41,22 @@ pub enum AllocInit {
Zeroed, Zeroed,
} }
/// Represents a block of allocated memory returned by an allocator. impl AllocInit {
#[derive(Debug, Copy, Clone)] /// Initialize the specified memory block.
#[unstable(feature = "allocator_api", issue = "32838")]
pub struct MemoryBlock {
pub ptr: NonNull<u8>,
pub size: usize,
}
impl MemoryBlock {
/// Initialize the memory block like specified by `init`.
/// ///
/// 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] #[inline]
#[unstable(feature = "allocator_api", issue = "32838")] #[unstable(feature = "allocator_api", issue = "32838")]
pub fn init(&mut self, init: AllocInit) { pub unsafe fn init(self, memory: MemoryBlock) {
// SAFETY: 0 is always smaller or equal to the size self.init_offset(memory, 0)
unsafe { self.init_offset(init, 0) }
} }
/// Initialize the memory block like specified by `init` at the specified `offset`. /// Initialize the memory block like specified by `init` at the specified `offset`.
@ -71,18 +66,32 @@ impl MemoryBlock {
/// ///
/// # Safety /// # 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] #[inline]
#[unstable(feature = "allocator_api", issue = "32838")] #[unstable(feature = "allocator_api", issue = "32838")]
pub unsafe fn init_offset(&mut self, init: AllocInit, offset: usize) { pub unsafe fn init_offset(self, memory: MemoryBlock, offset: usize) {
debug_assert!(offset <= self.size, "`offset` must be smaller than or equal to `size()`"); debug_assert!(
match init { offset <= memory.size,
"`offset` must be smaller than or equal to `memory.size`"
);
match self {
AllocInit::Uninitialized => (), 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<u8>,
pub size: usize,
} }
/// A placement constraint when growing or shrinking an existing allocation. /// A placement constraint when growing or shrinking an existing allocation.

View file

@ -188,12 +188,12 @@ unsafe impl AllocRef for System {
self.alloc(new_layout, init) self.alloc(new_layout, init)
} }
ReallocPlacement::MayMove => { 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); intrinsics::assume(new_size > size);
let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_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 }; MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
memory.init_offset(init, size); init.init_offset(memory, size);
Ok(memory) Ok(memory)
} }
} }
@ -224,7 +224,7 @@ unsafe impl AllocRef for System {
Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
} }
ReallocPlacement::MayMove => { 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); intrinsics::assume(new_size < size);
let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size); let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size);
Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }) Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })