diff options
| author | bors <bors@rust-lang.org> | 2018-06-12 00:36:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-06-12 00:36:21 +0000 |
| commit | 4367e41ea2a105c373de27c2f080fc2527cc6927 (patch) | |
| tree | 9ca30ec2dbf3311f0a0d0d6275d5abca8f23fc1f /src/libstd | |
| parent | f9944fde377b8b2575f96fff60f784eddce54002 (diff) | |
| parent | 7f0d54d98842c786ab7a140c17c3ea32aea6aead (diff) | |
| download | rust-4367e41ea2a105c373de27c2f080fc2527cc6927.tar.gz rust-4367e41ea2a105c373de27c2f080fc2527cc6927.zip | |
Auto merge of #51241 - glandium:globalalloc, r=sfackler,SimonSapin
Stabilize GlobalAlloc and #[global_allocator] This PR implements the changes discussed in https://github.com/rust-lang/rust/issues/49668#issuecomment-393263510 Fixes #49668 Fixes #27389 This does not change the default global allocator: #36963
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/alloc.rs | 93 | ||||
| -rw-r--r-- | src/libstd/collections/hash/table.rs | 2 | ||||
| -rw-r--r-- | src/libstd/collections/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/error.rs | 2 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 8 |
5 files changed, 84 insertions, 23 deletions
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 3b1a3a439e7..ae74a71dd06 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -8,19 +8,84 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! dox +//! Memory allocation APIs +//! +//! In a given program, the standard library has one “global” memory allocator +//! that is used for example by `Box<T>` and `Vec<T>`. +//! +//! Currently the default global allocator is unspecified. +//! The compiler may link to a version of [jemalloc] on some platforms, +//! but this is not guaranteed. +//! Libraries, however, like `cdylib`s and `staticlib`s are guaranteed +//! to use the [`System`] by default. +//! +//! [jemalloc]: https://github.com/jemalloc/jemalloc +//! [`System`]: struct.System.html +//! +//! # The `#[global_allocator]` attribute +//! +//! This attribute allows configuring the choice of global allocator. +//! You can use this to implement a completely custom global allocator +//! to route all default allocation requests to a custom object. +//! +//! ```rust +//! use std::alloc::{GlobalAlloc, System, Layout}; +//! +//! struct MyAllocator; +//! +//! unsafe impl GlobalAlloc for MyAllocator { +//! unsafe fn alloc(&self, layout: Layout) -> *mut u8 { +//! System.alloc(layout) +//! } +//! +//! unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { +//! System.dealloc(ptr, layout) +//! } +//! } +//! +//! #[global_allocator] +//! static GLOBAL: MyAllocator = MyAllocator; +//! +//! fn main() { +//! // This `Vec` will allocate memory through `GLOBAL` above +//! let mut v = Vec::new(); +//! v.push(1); +//! } +//! ``` +//! +//! The attribute is used on a `static` item whose type implements the +//! [`GlobalAlloc`] trait. This type can be provided by an external library: +//! +//! [`GlobalAlloc`]: ../../core/alloc/trait.GlobalAlloc.html +//! +//! ```rust,ignore (demonstrates crates.io usage) +//! extern crate jemallocator; +//! +//! use jemallacator::Jemalloc; +//! +//! #[global_allocator] +//! static GLOBAL: Jemalloc = Jemalloc; +//! +//! fn main() {} +//! ``` +//! +//! The `#[global_allocator]` can only be used once in a crate +//! or its recursive dependencies. -#![unstable(issue = "32838", feature = "allocator_api")] - -#[doc(inline)] #[allow(deprecated)] pub use alloc_crate::alloc::Heap; -#[doc(inline)] pub use alloc_crate::alloc::{Global, Layout, oom}; -#[doc(inline)] pub use alloc_system::System; -#[doc(inline)] pub use core::alloc::*; +#![stable(feature = "alloc_module", since = "1.28.0")] use core::sync::atomic::{AtomicPtr, Ordering}; use core::{mem, ptr}; use sys_common::util::dumb_print; +#[stable(feature = "alloc_module", since = "1.28.0")] +#[doc(inline)] +pub use alloc_crate::alloc::*; + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +#[doc(inline)] +pub use alloc_system::System; + static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); /// Registers a custom OOM hook, replacing any that was previously registered. @@ -34,6 +99,7 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); /// about the allocation that failed. /// /// The OOM hook is a global resource. +#[unstable(feature = "oom_hook", issue = "51245")] pub fn set_oom_hook(hook: fn(Layout)) { HOOK.store(hook as *mut (), Ordering::SeqCst); } @@ -43,6 +109,7 @@ pub fn set_oom_hook(hook: fn(Layout)) { /// *See also the function [`set_oom_hook`].* /// /// If no custom hook is registered, the default hook will be returned. +#[unstable(feature = "oom_hook", issue = "51245")] pub fn take_oom_hook() -> fn(Layout) { let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); if hook.is_null() { @@ -59,6 +126,7 @@ fn default_oom_hook(layout: Layout) { #[cfg(not(test))] #[doc(hidden)] #[lang = "oom"] +#[unstable(feature = "alloc_internals", issue = "0")] pub extern fn rust_oom(layout: Layout) -> ! { let hook = HOOK.load(Ordering::SeqCst); let hook: fn(Layout) = if hook.is_null() { @@ -73,8 +141,9 @@ pub extern fn rust_oom(layout: Layout) -> ! { #[cfg(not(test))] #[doc(hidden)] #[allow(unused_attributes)] +#[unstable(feature = "alloc_internals", issue = "0")] pub mod __default_lib_allocator { - use super::{System, Layout, GlobalAlloc, Opaque}; + use super::{System, Layout, GlobalAlloc}; // for symbol names src/librustc/middle/allocator.rs // for signatures src/librustc_allocator/lib.rs @@ -85,7 +154,7 @@ pub mod __default_lib_allocator { #[rustc_std_internal_symbol] pub unsafe extern fn __rdl_alloc(size: usize, align: usize) -> *mut u8 { let layout = Layout::from_size_align_unchecked(size, align); - System.alloc(layout) as *mut u8 + System.alloc(layout) } #[no_mangle] @@ -93,7 +162,7 @@ pub mod __default_lib_allocator { pub unsafe extern fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize) { - System.dealloc(ptr as *mut Opaque, Layout::from_size_align_unchecked(size, align)) + System.dealloc(ptr, Layout::from_size_align_unchecked(size, align)) } #[no_mangle] @@ -103,13 +172,13 @@ pub mod __default_lib_allocator { align: usize, new_size: usize) -> *mut u8 { let old_layout = Layout::from_size_align_unchecked(old_size, align); - System.realloc(ptr as *mut Opaque, old_layout, new_size) as *mut u8 + System.realloc(ptr, old_layout, new_size) } #[no_mangle] #[rustc_std_internal_symbol] pub unsafe extern fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 { let layout = Layout::from_size_align_unchecked(size, align); - System.alloc_zeroed(layout) as *mut u8 + System.alloc_zeroed(layout) } } diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index d997fb28d42..55f9f4f7cfe 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -1124,7 +1124,7 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> { let (layout, _) = calculate_layout::<K, V>(self.capacity()) .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() }); unsafe { - Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).as_opaque(), layout); + Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).cast(), layout); // Remember how everything was allocated out of one buffer // during initialization? We only need one call to free here. } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index d8e79b97970..42113414183 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -438,7 +438,7 @@ pub use self::hash_map::HashMap; pub use self::hash_set::HashSet; #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] -pub use heap::CollectionAllocErr; +pub use alloc::CollectionAllocErr; mod hash; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 817eea5eaf1..3160485375f 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -23,13 +23,13 @@ // coherence challenge (e.g., specialization, neg impls, etc) we can // reconsider what crate these items belong in. +use alloc::{AllocErr, LayoutErr, CannotReallocInPlace}; use any::TypeId; use borrow::Cow; use cell; use char; use core::array; use fmt::{self, Debug, Display}; -use heap::{AllocErr, LayoutErr, CannotReallocInPlace}; use mem::transmute; use num; use str; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 144977460b6..1bdc1dc2b7c 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -264,7 +264,6 @@ #![feature(fnbox)] #![feature(futures_api)] #![feature(hashmap_internals)] -#![feature(heap_api)] #![feature(int_error_internals)] #![feature(integer_atomics)] #![feature(into_cow)] @@ -500,13 +499,6 @@ pub mod process; pub mod sync; pub mod time; -#[unstable(feature = "allocator_api", issue = "32838")] -#[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")] -/// Use the `alloc` module instead. -pub mod heap { - pub use alloc::*; -} - // Platform-abstraction modules #[macro_use] mod sys_common; |
