Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize GlobalAlloc and #[global_allocator] #51241

Merged
merged 20 commits into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f6ab74b
Remove alloc::Opaque and use *mut u8 as pointer type for GlobalAlloc
glandium May 31, 2018
3373204
Replace `impl GlobalAlloc for Global` with a set of free functions
glandium May 31, 2018
8c30c51
Remove deprecated heap modules
SimonSapin May 30, 2018
11f992c
Remove the deprecated Heap type/const
SimonSapin May 30, 2018
0081d88
Remove some unneeded casts
SimonSapin May 30, 2018
e9fd063
Document memory allocation APIs
SimonSapin May 31, 2018
951bc28
Stablize the alloc module without changing stability of its contents.
SimonSapin May 31, 2018
75e17da
Mark as permanently-unstable some implementation details
SimonSapin May 31, 2018
77606f2
Stabilize alloc::Layout (with only some of its methods)
SimonSapin May 31, 2018
bbaff03
Stablize the GlobalAlloc trait
SimonSapin May 31, 2018
45d6d20
Stabilize alloc free functions for the global allocators.
SimonSapin May 31, 2018
125b259
Stabilize alloc::oom (but not set_oom_hook or take_oom_hook)
SimonSapin May 31, 2018
90d1972
Move set_oom_hook and take_oom_hook to a dedicated tracking issue
SimonSapin May 31, 2018
8111717
Stabilize the `System` allocator
SimonSapin May 31, 2018
999690c
Stabilize the #[global_allocator] attribute
SimonSapin May 31, 2018
fd6e08a
Remove some '#[feature]' attributes for stabilized features
SimonSapin May 31, 2018
a24924f
Move Unstable Book sections for #[global_allocator] and System to std…
SimonSapin May 31, 2018
b2d526c
Mark alloc_jemalloc as perma-unstable
SimonSapin May 31, 2018
9dcb64f
Alloc docs teaks
SimonSapin Jun 1, 2018
7f0d54d
More alloc docs tweaks
SimonSapin Jun 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 0 additions & 72 deletions src/doc/unstable-book/src/language-features/global-allocator.md

This file was deleted.

13 changes: 0 additions & 13 deletions src/doc/unstable-book/src/library-features/alloc-jemalloc.md

This file was deleted.

77 changes: 0 additions & 77 deletions src/doc/unstable-book/src/library-features/alloc-system.md

This file was deleted.

150 changes: 103 additions & 47 deletions src/liballoc/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![unstable(feature = "allocator_api",
reason = "the precise API and guarantees it provides may be tweaked \
slightly, especially to possibly take into account the \
types being stored to make room for a future \
tracing garbage collector",
issue = "32838")]
//! Memory allocation APIs

#![stable(feature = "alloc_module", since = "1.28.0")]

use core::intrinsics::{min_align_of_val, size_of_val};
use core::ptr::{NonNull, Unique};
use core::usize;

#[stable(feature = "alloc_module", since = "1.28.0")]
#[doc(inline)]
pub use core::alloc::*;

Expand All @@ -37,67 +35,112 @@ extern "Rust" {
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
}

/// The global memory allocator.
///
/// This type implements the [`Alloc`] trait by forwarding calls
/// to the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
#[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Copy, Clone, Default, Debug)]
pub struct Global;

#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_deprecated(since = "1.27.0", reason = "type renamed to `Global`")]
pub type Heap = Global;

#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_deprecated(since = "1.27.0", reason = "type renamed to `Global`")]
#[allow(non_upper_case_globals)]
pub const Heap: Global = Global;

unsafe impl GlobalAlloc for Global {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
let ptr = __rust_alloc(layout.size(), layout.align());
ptr as *mut Opaque
}
/// Allocate memory with the global allocator.
///
/// This function forwards calls to the [`GlobalAlloc::alloc`] method
/// of the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `alloc` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::alloc`].
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
__rust_alloc(layout.size(), layout.align())
}

#[inline]
unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
__rust_dealloc(ptr as *mut u8, layout.size(), layout.align())
}
/// Deallocate memory with the global allocator.
///
/// This function forwards calls to the [`GlobalAlloc::dealloc`] method
/// of the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `dealloc` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::dealloc`].
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
__rust_dealloc(ptr, layout.size(), layout.align())
}

#[inline]
unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(), new_size);
ptr as *mut Opaque
}
/// Reallocate memory with the global allocator.
///
/// This function forwards calls to the [`GlobalAlloc::realloc`] method
/// of the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `realloc` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::realloc`].
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
__rust_realloc(ptr, layout.size(), layout.align(), new_size)
}

#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
let ptr = __rust_alloc_zeroed(layout.size(), layout.align());
ptr as *mut Opaque
}
/// Allocate zero-initialized memory with the global allocator.
///
/// This function forwards calls to the [`GlobalAlloc::alloc_zeroed`] method
/// of the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `alloc_zeroed` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::alloc_zeroed`].
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
__rust_alloc_zeroed(layout.size(), layout.align())
}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl Alloc for Global {
#[inline]
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr)
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
NonNull::new(alloc(layout)).ok_or(AllocErr)
}

#[inline]
unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
dealloc(ptr.as_ptr(), layout)
}

#[inline]
unsafe fn realloc(&mut self,
ptr: NonNull<Opaque>,
ptr: NonNull<u8>,
layout: Layout,
new_size: usize)
-> Result<NonNull<Opaque>, AllocErr>
-> Result<NonNull<u8>, AllocErr>
{
NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
NonNull::new(realloc(ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
}

#[inline]
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr)
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr)
}
}

Expand All @@ -111,9 +154,9 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
align as *mut u8
} else {
let layout = Layout::from_size_align_unchecked(size, align);
let ptr = Global.alloc(layout);
let ptr = alloc(layout);
if !ptr.is_null() {
ptr as *mut u8
ptr
} else {
oom(layout)
}
Expand All @@ -129,10 +172,23 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
// We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
if size != 0 {
let layout = Layout::from_size_align_unchecked(size, align);
Global.dealloc(ptr as *mut Opaque, layout);
dealloc(ptr as *mut u8, layout);
}
}

/// Abort on memory allocation error or failure.
///
/// Callers of memory allocation APIs wishing to abort computation
/// in response to an allocation error are encouraged to call this function,
/// rather than directly invoking `panic!` or similar.
///
/// The default behavior of this function is to print a message to standard error
/// and abort the process.
/// It can be replaced with [`set_oom_hook`] and [`take_oom_hook`].
///
/// [`set_oom_hook`]: ../../std/alloc/fn.set_oom_hook.html
/// [`take_oom_hook`]: ../../std/alloc/fn.take_oom_hook.html
#[stable(feature = "global_alloc", since = "1.28.0")]
#[rustc_allocator_nounwind]
pub fn oom(layout: Layout) -> ! {
#[allow(improper_ctypes)]
Expand Down
Loading