Implement init
and init_offset
on AllocInit
and mark it unsafe
This commit is contained in:
parent
bf6a46db31
commit
3ade8ae660
3 changed files with 39 additions and 30 deletions
|
@ -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 })
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 })
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue