]> git.lizzy.rs Git - rust.git/blobdiff - src/liballoc/alloc.rs
Rollup merge of #71767 - tshepang:stack-stuff, r=jonas-schievink
[rust.git] / src / liballoc / alloc.rs
index 26524f6296221f9f1f15412c1654c7c7fc59b809..d31c73cc1bd8d576e3e2492d46bce1e0c3e34f36 100644 (file)
@@ -4,7 +4,6 @@
 
 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)]
@@ -165,18 +164,18 @@ 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<(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 })
             }
         }
     }
@@ -196,34 +195,32 @@ unsafe fn grow(
         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),
         }
     }
 
@@ -234,32 +231,29 @@ unsafe fn shrink(
         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),
         }
     }
 }
@@ -272,7 +266,7 @@ unsafe fn shrink(
 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),
     }
 }