use core::intrinsics::{self, min_align_of_val, size_of_val};
use core::ptr::{NonNull, Unique};
-use core::usize;
#[stable(feature = "alloc_module", since = "1.28.0")]
#[doc(inline)]
#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl AllocRef for Global {
#[inline]
- fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<(NonNull<u8>, usize), AllocErr> {
- let new_size = layout.size();
- if new_size == 0 {
- Ok((layout.dangling(), 0))
- } else {
- unsafe {
+ fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
+ unsafe {
+ let size = layout.size();
+ if size == 0 {
+ Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
+ } else {
let raw_ptr = match init {
AllocInit::Uninitialized => alloc(layout),
AllocInit::Zeroed => alloc_zeroed(layout),
};
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
- Ok((ptr, new_size))
+ Ok(MemoryBlock { ptr, size })
}
}
}
new_size: usize,
placement: ReallocPlacement,
init: AllocInit,
- ) -> Result<(NonNull<u8>, usize), AllocErr> {
- let old_size = layout.size();
+ ) -> Result<MemoryBlock, AllocErr> {
+ let size = layout.size();
debug_assert!(
- new_size >= old_size,
- "`new_size` must be greater than or equal to `layout.size()`"
+ new_size >= size,
+ "`new_size` must be greater than or equal to `memory.size()`"
);
- if old_size == new_size {
- return Ok((ptr, new_size));
+ if size == new_size {
+ return Ok(MemoryBlock { ptr, size });
}
match placement {
+ ReallocPlacement::InPlace => Err(AllocErr),
+ ReallocPlacement::MayMove if layout.size() == 0 => {
+ let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
+ self.alloc(new_layout, init)
+ }
ReallocPlacement::MayMove => {
- if old_size == 0 {
- self.alloc(Layout::from_size_align_unchecked(new_size, layout.align()), init)
- } else {
- // `realloc` probably checks for `new_size > old_size` or something similar.
- // `new_size` must be greater than or equal to `old_size` due to the safety constraint,
- // and `new_size` == `old_size` was caught before
- intrinsics::assume(new_size > old_size);
- let ptr =
- NonNull::new(realloc(ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)?;
- let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
- init.initialize_offset(ptr, new_layout, old_size);
- Ok((ptr, new_size))
- }
+ // `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 memory =
+ MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
+ init.init_offset(memory, size);
+ Ok(memory)
}
- ReallocPlacement::InPlace => Err(AllocErr),
}
}
layout: Layout,
new_size: usize,
placement: ReallocPlacement,
- ) -> Result<(NonNull<u8>, usize), AllocErr> {
- let old_size = layout.size();
+ ) -> Result<MemoryBlock, AllocErr> {
+ let size = layout.size();
debug_assert!(
- new_size <= old_size,
- "`new_size` must be smaller than or equal to `layout.size()`"
+ new_size <= size,
+ "`new_size` must be smaller than or equal to `memory.size()`"
);
- if old_size == new_size {
- return Ok((ptr, new_size));
+ if size == new_size {
+ return Ok(MemoryBlock { ptr, size });
}
match placement {
+ ReallocPlacement::InPlace => Err(AllocErr),
+ ReallocPlacement::MayMove if new_size == 0 => {
+ self.dealloc(ptr, layout);
+ Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
+ }
ReallocPlacement::MayMove => {
- let ptr = if new_size == 0 {
- self.dealloc(ptr, layout);
- layout.dangling()
- } else {
- // `realloc` probably checks for `new_size > old_size` or something similar.
- // `new_size` must be smaller than or equal to `old_size` due to the safety constraint,
- // and `new_size` == `old_size` was caught before
- intrinsics::assume(new_size < old_size);
- NonNull::new(realloc(ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)?
- };
- Ok((ptr, new_size))
+ // `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 })
}
- ReallocPlacement::InPlace => Err(AllocErr),
}
}
}
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
let layout = Layout::from_size_align_unchecked(size, align);
match Global.alloc(layout, AllocInit::Uninitialized) {
- Ok((ptr, _)) => ptr.as_ptr(),
+ Ok(memory) => memory.ptr.as_ptr(),
Err(_) => handle_alloc_error(layout),
}
}