diff options
| author | Tim Diekmann <tim.diekmann@3dvision.de> | 2020-07-28 12:41:18 +0200 |
|---|---|---|
| committer | Tim Diekmann <tim.diekmann@3dvision.de> | 2020-07-28 12:41:18 +0200 |
| commit | 076ef66ba2f647a627806f376c23b332fb04d3ff (patch) | |
| tree | e0b01276965228cd9fb1cb2577ed5beb1b9e1910 /library/alloc/src/alloc.rs | |
| parent | 1f5d69daccd1f04e42886d9aaf513f2691132d17 (diff) | |
| download | rust-076ef66ba2f647a627806f376c23b332fb04d3ff.tar.gz rust-076ef66ba2f647a627806f376c23b332fb04d3ff.zip | |
Remove in-place allocation and revert to separate methods for zeroed allocations
Fix docs
Diffstat (limited to 'library/alloc/src/alloc.rs')
| -rw-r--r-- | library/alloc/src/alloc.rs | 112 |
1 files changed, 69 insertions, 43 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 98c7ac3f2ef..16f3f5d5745 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -164,16 +164,26 @@ 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, init: AllocInit) -> Result<MemoryBlock, AllocErr> { + fn alloc(&mut self, layout: Layout) -> 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 raw_ptr = alloc(layout); + let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; + Ok(MemoryBlock { ptr, size }) + } + } + } + + fn alloc_zeroed(&mut self, layout: Layout) -> Result<MemoryBlock, AllocErr> { + unsafe { + let size = layout.size(); + if size == 0 { + Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) + } else { + let raw_ptr = alloc_zeroed(layout); let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; Ok(MemoryBlock { ptr, size }) } @@ -193,8 +203,6 @@ unsafe impl AllocRef for Global { ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - init: AllocInit, ) -> Result<MemoryBlock, AllocErr> { let size = layout.size(); debug_assert!( @@ -206,26 +214,49 @@ unsafe impl AllocRef for Global { return Ok(MemoryBlock { ptr, size }); } - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove if layout.size() == 0 => { - let new_layout = - unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; - self.alloc(new_layout, init) - } - ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size > size` or something similar. - let ptr = unsafe { - intrinsics::assume(new_size > size); - realloc(ptr.as_ptr(), layout, new_size) - }; - let memory = - MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }; - unsafe { - init.init_offset(memory, size); - } - Ok(memory) + if layout.size() == 0 { + let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; + self.alloc(new_layout) + } else { + // `realloc` probably checks for `new_size > size` or something similar. + let ptr = unsafe { + intrinsics::assume(new_size > size); + realloc(ptr.as_ptr(), layout, new_size) + }; + Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }) + } + } + + unsafe fn grow_zeroed( + &mut self, + ptr: NonNull<u8>, + layout: Layout, + new_size: usize, + ) -> Result<MemoryBlock, AllocErr> { + let size = layout.size(); + debug_assert!( + new_size >= size, + "`new_size` must be greater than or equal to `memory.size()`" + ); + + if size == new_size { + return Ok(MemoryBlock { ptr, size }); + } + + if layout.size() == 0 { + let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; + self.alloc(new_layout) + } else { + // `realloc` probably checks for `new_size > size` or something similar. + let ptr = unsafe { + intrinsics::assume(new_size > size); + realloc(ptr.as_ptr(), layout, new_size) + }; + let memory = MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }; + unsafe { + memory.ptr.as_ptr().add(size).write_bytes(0, memory.size - size); } + Ok(memory) } } @@ -235,7 +266,6 @@ unsafe impl AllocRef for Global { ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, ) -> Result<MemoryBlock, AllocErr> { let size = layout.size(); debug_assert!( @@ -247,22 +277,18 @@ unsafe impl AllocRef for Global { return Ok(MemoryBlock { ptr, size }); } - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove if new_size == 0 => { - unsafe { - self.dealloc(ptr, layout); - } - Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) - } - ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size < size` or something similar. - let ptr = unsafe { - intrinsics::assume(new_size < size); - realloc(ptr.as_ptr(), layout, new_size) - }; - Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }) + if new_size == 0 { + unsafe { + self.dealloc(ptr, layout); } + Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) + } else { + // `realloc` probably checks for `new_size < size` or something similar. + let ptr = unsafe { + intrinsics::assume(new_size < size); + realloc(ptr.as_ptr(), layout, new_size) + }; + Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }) } } } @@ -274,7 +300,7 @@ unsafe impl AllocRef for Global { #[inline] unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; - match Global.alloc(layout, AllocInit::Uninitialized) { + match Global.alloc(layout) { Ok(memory) => memory.ptr.as_ptr(), Err(_) => handle_alloc_error(layout), } |
