about summary refs log tree commit diff
path: root/build_sysroot
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2020-04-03 11:54:18 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2020-04-03 11:54:18 +0200
commitac1c5d69544450d30785d001224f7233da48cbda (patch)
treede4195fc6dd1cc038c32f5b5e091bc1f7e43a56b /build_sysroot
parent17f99b4a964a4ade86da447088c0a3fc2de43270 (diff)
downloadrust-ac1c5d69544450d30785d001224f7233da48cbda.tar.gz
rust-ac1c5d69544450d30785d001224f7233da48cbda.zip
Rustup to rustc 1.44.0-nightly (537ccdf3a 2020-04-02)
Diffstat (limited to 'build_sysroot')
-rw-r--r--build_sysroot/alloc_system/lib.rs107
1 files changed, 89 insertions, 18 deletions
diff --git a/build_sysroot/alloc_system/lib.rs b/build_sysroot/alloc_system/lib.rs
index 8ad0a076d3d..bb0ceb229f4 100644
--- a/build_sysroot/alloc_system/lib.rs
+++ b/build_sysroot/alloc_system/lib.rs
@@ -18,6 +18,7 @@
 #![feature(nll)]
 #![feature(staged_api)]
 #![feature(rustc_attrs)]
+#![feature(alloc_layout_extra)]
 #![cfg_attr(
     all(target_arch = "wasm32", not(target_os = "emscripten")),
     feature(integer_atomics, stdsimd)
@@ -41,8 +42,10 @@ const MIN_ALIGN: usize = 8;
               target_arch = "sparc64")))]
 #[allow(dead_code)]
 const MIN_ALIGN: usize = 16;
-use core::alloc::{AllocRef, GlobalAlloc, AllocErr, Layout};
+use core::alloc::*;
 use core::ptr::NonNull;
+use core::intrinsics;
+
 /// The default memory allocator provided by the operating system.
 ///
 /// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
@@ -72,29 +75,97 @@ pub struct System;
 #[unstable(feature = "allocator_api", issue = "32838")]
 unsafe impl AllocRef for System {
     #[inline]
-    fn alloc(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
-        NonNull::new(unsafe { GlobalAlloc::alloc(self, layout) })
-            .ok_or(AllocErr)
-            .map(|p| (p, layout.size()))
+    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 => GlobalAlloc::alloc(self, layout),
+                    AllocInit::Zeroed => GlobalAlloc::alloc_zeroed(self, layout),
+                };
+                let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
+                Ok(MemoryBlock { ptr, size })
+            }
+        }
     }
+
     #[inline]
-    fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
-        NonNull::new(unsafe { GlobalAlloc::alloc_zeroed(self, layout) })
-            .ok_or(AllocErr)
-            .map(|p| (p, layout.size()))
+    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+        if layout.size() != 0 {
+            GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
+        }
     }
+
     #[inline]
-    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
-        GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
+    unsafe fn grow(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+        placement: ReallocPlacement,
+        init: AllocInit,
+    ) -> 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 });
+        }
+
+        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 => {
+                // `realloc` probably checks for `new_size > size` or something similar.
+                intrinsics::assume(new_size > size);
+                let ptr = GlobalAlloc::realloc(self, 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)
+            }
+        }
     }
+
     #[inline]
-    unsafe fn realloc(&mut self,
-                      ptr: NonNull<u8>,
-                      layout: Layout,
-                      new_size: usize) -> Result<(NonNull<u8>, usize), AllocErr> {
-        NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size))
-            .ok_or(AllocErr)
-            .map(|p| (p, layout.size()))
+    unsafe fn shrink(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+        placement: ReallocPlacement,
+    ) -> Result<MemoryBlock, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size <= size,
+            "`new_size` must be smaller than or equal to `memory.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 => {
+                // `realloc` probably checks for `new_size < size` or something similar.
+                intrinsics::assume(new_size < size);
+                let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size);
+                Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })
+            }
+        }
     }
 }
 #[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))]