about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-12 00:36:21 +0000
committerbors <bors@rust-lang.org>2018-06-12 00:36:21 +0000
commit4367e41ea2a105c373de27c2f080fc2527cc6927 (patch)
tree9ca30ec2dbf3311f0a0d0d6275d5abca8f23fc1f /src/libstd
parentf9944fde377b8b2575f96fff60f784eddce54002 (diff)
parent7f0d54d98842c786ab7a140c17c3ea32aea6aead (diff)
downloadrust-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.rs93
-rw-r--r--src/libstd/collections/hash/table.rs2
-rw-r--r--src/libstd/collections/mod.rs2
-rw-r--r--src/libstd/error.rs2
-rw-r--r--src/libstd/lib.rs8
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;