From a24924f6834ea6e5bd813d006a12aef8e5dbd5e9 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 31 May 2018 20:22:59 +0200 Subject: Move Unstable Book sections for #[global_allocator] and System to std::alloc docs --- .../src/language-features/global-allocator.md | 72 -------------------- .../src/library-features/alloc-system.md | 76 ---------------------- src/liballoc_system/lib.rs | 23 +++++++ src/libstd/alloc.rs | 62 ++++++++++++++++++ 4 files changed, 85 insertions(+), 148 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/global-allocator.md delete mode 100644 src/doc/unstable-book/src/library-features/alloc-system.md (limited to 'src') diff --git a/src/doc/unstable-book/src/language-features/global-allocator.md b/src/doc/unstable-book/src/language-features/global-allocator.md deleted file mode 100644 index 7dfdc487731..00000000000 --- a/src/doc/unstable-book/src/language-features/global-allocator.md +++ /dev/null @@ -1,72 +0,0 @@ -# `global_allocator` - -The tracking issue for this feature is: [#27389] - -[#27389]: https://github.com/rust-lang/rust/issues/27389 - ------------------------- - -Rust programs may need to change the allocator that they're running with from -time to time. This use case is distinct from an allocator-per-collection (e.g. a -`Vec` with a custom allocator) and instead is more related to changing the -global default allocator, e.g. what `Vec` uses by default. - -Currently Rust programs don't have a specified global allocator. The compiler -may link to a version of [jemalloc] on some platforms, but this is not -guaranteed. Libraries, however, like cdylibs and staticlibs are guaranteed -to use the "system allocator" which means something like `malloc` on Unixes and -`HeapAlloc` on Windows. - -[jemalloc]: https://github.com/jemalloc/jemalloc - -The `#[global_allocator]` attribute, however, allows configuring this choice. -You can use this to implement a completely custom global allocator to route all -default allocation requests to a custom object. Defined in [RFC 1974] usage -looks like: - -[RFC 1974]: https://github.com/rust-lang/rfcs/pull/1974 - -```rust -#![feature(global_allocator, allocator_api, heap_api)] - -use std::alloc::{GlobalAlloc, System, Layout}; -use std::ptr::NonNull; - -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); -} -``` - -And that's it! The `#[global_allocator]` attribute is applied to a `static` -which implements the `Alloc` trait in the `std::alloc` module. Note, though, -that the implementation is defined for `&MyAllocator`, not just `MyAllocator`. -You may wish, however, to also provide `Alloc for MyAllocator` for other use -cases. - -A crate can only have one instance of `#[global_allocator]` and this instance -may be loaded through a dependency. For example `#[global_allocator]` above -could have been placed in one of the dependencies loaded through `extern crate`. - -Note that `Alloc` itself is an `unsafe` trait, with much documentation on the -trait itself about usage and for implementors. Extra care should be taken when -implementing a global allocator as well as the allocator may be called from many -portions of the standard library, such as the panicking routine. As a result it -is highly recommended to not panic during allocation and work in as many -situations with as few dependencies as possible as well. diff --git a/src/doc/unstable-book/src/library-features/alloc-system.md b/src/doc/unstable-book/src/library-features/alloc-system.md deleted file mode 100644 index 5663b354ac1..00000000000 --- a/src/doc/unstable-book/src/library-features/alloc-system.md +++ /dev/null @@ -1,76 +0,0 @@ -# `alloc_system` - -The tracking issue for this feature is: [#32838] - -[#32838]: https://github.com/rust-lang/rust/issues/32838 - -See also [`global_allocator`](language-features/global-allocator.html). - ------------------------- - -The compiler currently ships two default allocators: `alloc_system` and -`alloc_jemalloc` (some targets don't have jemalloc, however). These allocators -are normal Rust crates and contain an implementation of the routines to -allocate and deallocate memory. The standard library is not compiled assuming -either one, and the compiler will decide which allocator is in use at -compile-time depending on the type of output artifact being produced. - -Binaries generated by the compiler will use `alloc_jemalloc` by default (where -available). In this situation the compiler "controls the world" in the sense of -it has power over the final link. Primarily this means that the allocator -decision can be left up the compiler. - -Dynamic and static libraries, however, will use `alloc_system` by default. Here -Rust is typically a 'guest' in another application or another world where it -cannot authoritatively decide what allocator is in use. As a result it resorts -back to the standard APIs (e.g. `malloc` and `free`) for acquiring and releasing -memory. - -# Switching Allocators - -Although the compiler's default choices may work most of the time, it's often -necessary to tweak certain aspects. Overriding the compiler's decision about -which allocator is in use is done through the `#[global_allocator]` attribute: - -```rust,no_run -#![feature(alloc_system, global_allocator, allocator_api)] - -extern crate alloc_system; - -use alloc_system::System; - -#[global_allocator] -static A: System = System; - -fn main() { - let a = Box::new(4); // Allocates from the system allocator. - println!("{}", a); -} -``` - -In this example the binary generated will not link to jemalloc by default but -instead use the system allocator. Conversely to generate a dynamic library which -uses jemalloc by default one would write: - -(The `alloc_jemalloc` crate cannot be used to control the global allocator, -crate.io’s `jemallocator` crate provides equivalent functionality.) - -```toml -# Cargo.toml -[dependencies] -jemallocator = "0.1" -``` -```rust,ignore -#![crate_type = "dylib"] - -extern crate jemallocator; - -#[global_allocator] -static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; - -pub fn foo() { - let a = Box::new(4); // Allocates from jemalloc. - println!("{}", a); -} -# fn main() {} -``` diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 2b748c4702d..64348e05de7 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -44,6 +44,29 @@ use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout}; use core::ptr::NonNull; /// 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 can be used in a `static` item +/// with the `#[global_allocator]` attribute +/// to force the global allocator to be the system’s one. +/// (The default is jemalloc for executables, on some platforms.) +/// +/// ```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); +/// } +/// ``` +/// +/// It can also be used directly to allocate memory +/// independently of the standard library’s global allocator. #[stable(feature = "alloc_system_type", since = "1.28.0")] pub struct System; diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 6cae8aaa3db..ae74a71dd06 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -9,6 +9,68 @@ // except according to those terms. //! Memory allocation APIs +//! +//! In a given program, the standard library has one “global” memory allocator +//! that is used for example by `Box` and `Vec`. +//! +//! 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. #![stable(feature = "alloc_module", since = "1.28.0")] -- cgit 1.4.1-3-g733a5