From cc7590341a6ac213909d0ef56a7ebc2834274c8b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 3 Nov 2018 11:15:48 -0700 Subject: std: Delete the `alloc_system` crate This commit deletes the `alloc_system` crate from the standard distribution. This unstable crate is no longer needed in the modern stable global allocator world, but rather its functionality is folded directly into the standard library. The standard library was already the only stable location to access this crate, and as a result this should not affect any stable code. --- src/libstd/alloc.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 2 deletions(-) (limited to 'src/libstd/alloc.rs') diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 1ff342fa7a7..485b2ffe197 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -73,15 +73,100 @@ use core::sync::atomic::{AtomicPtr, Ordering}; use core::{mem, ptr}; +use core::ptr::NonNull; use sys_common::util::dumb_print; #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] pub use alloc_crate::alloc::*; +/// The default memory allocator provided by the operating system. +/// +/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows, +/// plus related functions. +/// +/// This type implements the `GlobalAlloc` trait and Rust programs by deafult +/// work as if they had this definition: +/// +/// ```rust +/// use std::alloc::System; +/// +/// #[global_allocator] +/// static A: System = System; +/// +/// fn main() { +/// let a = Box::new(4); // Allocates from the system allocator. +/// println!("{}", a); +/// } +/// ``` +/// +/// You can also define your own wrapper around `System` if you'd like, such as +/// keeping track of the number of all bytes allocated: +/// +/// ```rust +/// use std::alloc::{System, GlobalAlloc, Layout}; +/// use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering::SeqCst}; +/// +/// struct Counter; +/// +/// static ALLOCATED: AtomicUsize = ATOMIC_USIZE_INIT; +/// +/// unsafe impl GlobalAlloc for Counter { +/// unsafe fn alloc(&self, layout: Layout) -> *mut u8 { +/// let ret = System.alloc(layout); +/// if !ret.is_null() { +/// ALLOCATED.fetch_add(layout.size(), SeqCst); +/// } +/// return ret +/// } +/// +/// unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { +/// System.dealloc(ptr, layout); +/// ALLOCATED.fetch_sub(layout.size(), SeqCst); +/// } +/// } +/// +/// #[global_allocator] +/// static A: Counter = Counter; +/// +/// fn main() { +/// println!("allocated bytes before main: {}", ALLOCATED.load(SeqCst)); +/// } +/// ``` +/// +/// It can also be used directly to allocate memory independently of whatever +/// global allocator has been selected for a Rust program. For example if a Rust +/// program opts in to using jemalloc as the global allocator, `System` will +/// still allocate memory using `malloc` and `HeapAlloc`. #[stable(feature = "alloc_system_type", since = "1.28.0")] -#[doc(inline)] -pub use alloc_system::System; +#[derive(Debug, Copy, Clone)] +pub struct System; + +#[unstable(feature = "allocator_api", issue = "32838")] +unsafe impl Alloc for System { + #[inline] + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { + NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr) + } + + #[inline] + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { + NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr) + } + + #[inline] + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) + } + + #[inline] + unsafe fn realloc(&mut self, + ptr: NonNull, + layout: Layout, + new_size: usize) -> Result, AllocErr> { + NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) + } +} static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); -- cgit 1.4.1-3-g733a5