From f6ab74b8e7efed01c1045773b6693f23f6ebd93c Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 31 May 2018 15:57:43 +0900 Subject: Remove alloc::Opaque and use *mut u8 as pointer type for GlobalAlloc --- src/liballoc/alloc.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 8753c495737..102910f4198 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -51,52 +51,49 @@ 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 + unsafe fn alloc(&self, 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()) + unsafe fn dealloc(&self, 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 + unsafe fn realloc(&self, 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 + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + __rust_alloc_zeroed(layout.size(), layout.align()) } } unsafe impl Alloc for Global { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr) } #[inline] - unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) } #[inline] unsafe fn realloc(&mut self, - ptr: NonNull, + ptr: NonNull, layout: Layout, new_size: usize) - -> Result, AllocErr> + -> Result, AllocErr> { NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr) } } @@ -113,7 +110,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { let layout = Layout::from_size_align_unchecked(size, align); let ptr = Global.alloc(layout); if !ptr.is_null() { - ptr as *mut u8 + ptr } else { oom(layout) } @@ -129,7 +126,7 @@ pub(crate) unsafe fn box_free(ptr: Unique) { // We do not allocate for Box 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); + Global.dealloc(ptr as *mut u8, layout); } } -- cgit 1.4.1-3-g733a5 From 3373204ac49ebdb7194020ea9c556ce87910f7b7 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 31 May 2018 16:10:01 +0900 Subject: Replace `impl GlobalAlloc for Global` with a set of free functions --- src/liballoc/alloc.rs | 48 ++++++++++++++++-------------- src/libstd/alloc.rs | 1 + src/test/run-pass/allocator/xcrate-use2.rs | 6 ++-- 3 files changed, 29 insertions(+), 26 deletions(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 102910f4198..8c2dda77226 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -49,37 +49,39 @@ pub type Heap = Global; #[allow(non_upper_case_globals)] pub const Heap: Global = Global; -unsafe impl GlobalAlloc for Global { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - __rust_alloc(layout.size(), layout.align()) - } +#[unstable(feature = "allocator_api", issue = "32838")] +#[inline] +pub unsafe fn alloc(layout: Layout) -> *mut u8 { + __rust_alloc(layout.size(), layout.align()) +} - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - __rust_dealloc(ptr, layout.size(), layout.align()) - } +#[unstable(feature = "allocator_api", issue = "32838")] +#[inline] +pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { + __rust_dealloc(ptr, layout.size(), layout.align()) +} - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - __rust_realloc(ptr, layout.size(), layout.align(), new_size) - } +#[unstable(feature = "allocator_api", issue = "32838")] +#[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 u8 { - __rust_alloc_zeroed(layout.size(), layout.align()) - } +#[unstable(feature = "allocator_api", issue = "32838")] +#[inline] +pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { + __rust_alloc_zeroed(layout.size(), layout.align()) } unsafe impl Alloc for Global { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { - NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr) + NonNull::new(alloc(layout)).ok_or(AllocErr) } #[inline] unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { - GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) + dealloc(ptr.as_ptr(), layout) } #[inline] @@ -89,12 +91,12 @@ unsafe impl Alloc for Global { new_size: usize) -> Result, 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, AllocErr> { - NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr) + NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr) } } @@ -108,7 +110,7 @@ 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 } else { @@ -126,7 +128,7 @@ pub(crate) unsafe fn box_free(ptr: Unique) { // We do not allocate for Box 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 u8, layout); + dealloc(ptr as *mut u8, layout); } } diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index ac7da5e9dba..3f31fa8e1dd 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -14,6 +14,7 @@ #[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_crate::alloc::{alloc, alloc_zeroed, dealloc, realloc}; #[doc(inline)] pub use alloc_system::System; #[doc(inline)] pub use core::alloc::*; diff --git a/src/test/run-pass/allocator/xcrate-use2.rs b/src/test/run-pass/allocator/xcrate-use2.rs index b8e844522dc..fbde7e855c2 100644 --- a/src/test/run-pass/allocator/xcrate-use2.rs +++ b/src/test/run-pass/allocator/xcrate-use2.rs @@ -19,7 +19,7 @@ extern crate custom; extern crate custom_as_global; extern crate helper; -use std::alloc::{Global, Alloc, GlobalAlloc, System, Layout}; +use std::alloc::{alloc, dealloc, GlobalAlloc, System, Layout}; use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT}; static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT); @@ -30,10 +30,10 @@ fn main() { let layout = Layout::from_size_align(4, 2).unwrap(); // Global allocator routes to the `custom_as_global` global - let ptr = Global.alloc(layout.clone()); + let ptr = alloc(layout.clone()); helper::work_with(&ptr); assert_eq!(custom_as_global::get(), n + 1); - Global.dealloc(ptr, layout.clone()); + dealloc(ptr, layout.clone()); assert_eq!(custom_as_global::get(), n + 2); // Usage of the system allocator avoids all globals -- cgit 1.4.1-3-g733a5 From 11f992c9584f05f56664627ac1ec42e4cd1f0e3e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 30 May 2018 21:15:40 +0200 Subject: Remove the deprecated Heap type/const --- src/liballoc/alloc.rs | 9 --------- src/libstd/alloc.rs | 1 - 2 files changed, 10 deletions(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 8c2dda77226..710da9a475b 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -40,15 +40,6 @@ extern "Rust" { #[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; - #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub unsafe fn alloc(layout: Layout) -> *mut u8 { diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 3f31fa8e1dd..9904634f1fa 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -12,7 +12,6 @@ #![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_crate::alloc::{alloc, alloc_zeroed, dealloc, realloc}; #[doc(inline)] pub use alloc_system::System; -- cgit 1.4.1-3-g733a5 From e9fd063edb4f6783fbd91a82a0f61626dacf8dad Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 31 May 2018 18:23:42 +0200 Subject: Document memory allocation APIs Add some docs where they were missing, attempt to fix them where they were out of date. --- src/liballoc/alloc.rs | 65 +++++++++++++ src/liballoc_system/lib.rs | 1 + src/libcore/alloc.rs | 227 +++++++++++++++++++++++++++++++++++---------- src/libstd/alloc.rs | 2 +- 4 files changed, 245 insertions(+), 50 deletions(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 710da9a475b..c9430a29e4c 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Memory allocation APIs + #![unstable(feature = "allocator_api", reason = "the precise API and guarantees it provides may be tweaked \ slightly, especially to possibly take into account the \ @@ -37,27 +39,80 @@ 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. #[derive(Copy, Clone, Default, Debug)] pub struct Global; +/// 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`]. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub unsafe fn alloc(layout: Layout) -> *mut u8 { __rust_alloc(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`]. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { __rust_dealloc(ptr, layout.size(), layout.align()) } +/// 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`]. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { __rust_realloc(ptr, layout.size(), layout.align(), new_size) } +/// 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`]. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { @@ -123,6 +178,16 @@ pub(crate) unsafe fn box_free(ptr: Unique) { } } +/// 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 [`std::alloc::set_oom_hook`] +/// and [`std::alloc::take_oom_hook`]. #[rustc_allocator_nounwind] pub fn oom(layout: Layout) -> ! { #[allow(improper_ctypes)] diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 82fda8d639e..85bf43a5429 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -44,6 +44,7 @@ const MIN_ALIGN: usize = 16; use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout}; use core::ptr::NonNull; +/// The default memory allocator provided by the operating system. #[unstable(feature = "allocator_api", issue = "32838")] pub struct System; diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 2815ef6400d..8fcd8555cdc 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Memory allocation APIs + #![unstable(feature = "allocator_api", reason = "the precise API and guarantees it provides may be tweaked \ slightly, especially to possibly take into account the \ @@ -315,8 +317,9 @@ impl Layout { } } -/// The parameters given to `Layout::from_size_align` do not satisfy -/// its documented constraints. +/// The parameters given to `Layout::from_size_align` +/// or some other `Layout` constructor +/// do not satisfy its documented constraints. #[derive(Clone, PartialEq, Eq, Debug)] pub struct LayoutErr { private: () @@ -329,8 +332,8 @@ impl fmt::Display for LayoutErr { } } -/// The `AllocErr` error specifies whether an allocation failure is -/// specifically due to resource exhaustion or if it is due to +/// The `AllocErr` error indicates an allocation failure +/// that may be due to resource exhaustion or to /// something wrong when combining the given input arguments with this /// allocator. #[derive(Clone, PartialEq, Eq, Debug)] @@ -346,6 +349,7 @@ impl fmt::Display for AllocErr { /// The `CannotReallocInPlace` error is used when `grow_in_place` or /// `shrink_in_place` were unable to reuse the given memory block for /// a requested layout. +// FIXME: should this be in libcore or liballoc? #[derive(Clone, PartialEq, Eq, Debug)] pub struct CannotReallocInPlace; @@ -363,6 +367,7 @@ impl fmt::Display for CannotReallocInPlace { } /// Augments `AllocErr` with a CapacityOverflow variant. +// FIXME: should this be in libcore or liballoc? #[derive(Clone, PartialEq, Eq, Debug)] #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] pub enum CollectionAllocErr { @@ -389,27 +394,125 @@ impl From for CollectionAllocErr { } } -/// A memory allocator that can be registered to be the one backing `std::alloc::Global` +/// A memory allocator that can be registered as the standard library’s default /// though the `#[global_allocator]` attributes. +/// +/// Some of the methods require that a memory block be *currently +/// allocated* via an allocator. This means that: +/// +/// * the starting address for that memory block was previously +/// returned by a previous call to an allocation method +/// such as `alloc`, and +/// +/// * the memory block has not been subsequently deallocated, where +/// blocks are deallocated either by being passed to a deallocation +/// method such as `dealloc` or by being +/// passed to a reallocation method that returns a non-null pointer. +/// +/// +/// # Example +/// +/// ```no_run +/// use std::alloc::{GlobalAlloc, Layout, alloc}; +/// use std::ptr::null_mut; +/// +/// struct MyAllocator; +/// +/// unsafe impl GlobalAlloc for MyAllocator { +/// unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() } +/// unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +/// } +/// +/// #[global_allocator] +/// static A: MyAllocator = MyAllocator; +/// +/// fn main() { +/// unsafe { +/// assert!(alloc(Layout::new::()).is_null()) +/// } +/// } +/// ``` +/// +/// # Unsafety +/// +/// The `GlobalAlloc` trait is an `unsafe` trait for a number of reasons, and +/// implementors must ensure that they adhere to these contracts: +/// +/// * Pointers returned from allocation functions must point to valid memory and +/// retain their validity until at least the instance of `GlobalAlloc` is dropped +/// itself. +/// +/// * It's undefined behavior if global allocators unwind. This restriction may +/// be lifted in the future, but currently a panic from any of these +/// functions may lead to memory unsafety. +/// +/// * `Layout` queries and calculations in general must be correct. Callers of +/// this trait are allowed to rely on the contracts defined on each method, +/// and implementors must ensure such contracts remain true. pub unsafe trait GlobalAlloc { /// Allocate memory as described by the given `layout`. /// /// Returns a pointer to newly-allocated memory, - /// or NULL to indicate allocation failure. + /// or null to indicate allocation failure. /// /// # Safety /// - /// **FIXME:** what are the exact requirements? + /// This function is unsafe because undefined behavior can result + /// if the caller does not ensure that `layout` has non-zero size. + /// + /// (Extension subtraits might provide more specific bounds on + /// behavior, e.g. guarantee a sentinel address or a null pointer + /// in response to a zero-size allocation request.) + /// + /// The allocated block of memory may or may not be initialized. + /// + /// # Errors + /// + /// Returning a null pointer indicates that either memory is exhausted + /// or `layout` does not meet allocator's size or alignment constraints. + /// + /// Implementations are encouraged to return null on memory + /// exhaustion rather than aborting, but this is not + /// a strict requirement. (Specifically: it is *legal* to + /// implement this trait atop an underlying native allocation + /// library that aborts on memory exhaustion.) + /// + /// Clients wishing to abort computation in response to an + /// allocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn alloc(&self, layout: Layout) -> *mut u8; /// Deallocate the block of memory at the given `ptr` pointer with the given `layout`. /// /// # Safety /// - /// **FIXME:** what are the exact requirements? - /// In particular around layout *fit*. (See docs for the `Alloc` trait.) + /// This function is unsafe because undefined behavior can result + /// if the caller does not ensure all of the following: + /// + /// * `ptr` must denote a block of memory currently allocated via + /// this allocator, + /// + /// * `layout` must be the same layout that was used + /// to allocated that block of memory, unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout); + /// Behaves like `alloc`, but also ensures that the contents + /// are set to zero before being returned. + /// + /// # Safety + /// + /// This function is unsafe for the same reasons that `alloc` is. + /// However the allocated block of memory is guaranteed to be initialized. + /// + /// # Errors + /// + /// Returning a null pointer indicates that either memory is exhausted + /// or `layout` does not meet allocator's size or alignment constraints, + /// just as in `alloc`. + /// + /// Clients wishing to abort computation in response to an + /// allocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { let size = layout.size(); let ptr = self.alloc(layout); @@ -422,19 +525,51 @@ pub unsafe trait GlobalAlloc { /// Shink or grow a block of memory to the given `new_size`. /// The block is described by the given `ptr` pointer and `layout`. /// - /// Return a new pointer (which may or may not be the same as `ptr`), - /// or NULL to indicate reallocation failure. + /// If this returns a non-null pointer, then ownership of the memory block + /// referenced by `ptr` has been transferred to this alloctor. + /// The memory may or may not have been deallocated, + /// and should be considered unusable (unless of course it was + /// transferred back to the caller again via the return value of + /// this method). /// - /// If reallocation is successful, the old `ptr` pointer is considered - /// to have been deallocated. + /// If this method returns null, then ownership of the memory + /// block has not been transferred to this allocator, and the + /// contents of the memory block are unaltered. /// /// # Safety /// - /// `new_size`, when rounded up to the nearest multiple of `old_layout.align()`, - /// must not overflow (i.e. the rounded value must be less than `usize::MAX`). + /// This function is unsafe because undefined behavior can result + /// if the caller does not ensure all of the following: + /// + /// * `ptr` must be currently allocated via this allocator, + /// + /// * `layout` must be the same layout that was used + /// to allocated that block of memory, + /// + /// * `new_size` must be greater than zero. + /// + /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, + /// must not overflow (i.e. the rounded value must be less than `usize::MAX`). + /// + /// (Extension subtraits might provide more specific bounds on + /// behavior, e.g. guarantee a sentinel address or a null pointer + /// in response to a zero-size allocation request.) + /// + /// # Errors + /// + /// Returns null if the new layout does not meet the size + /// and alignment constraints of the allocator, or if reallocation + /// otherwise fails. + /// + /// Implementations are encouraged to return null on memory + /// exhaustion rather than panicking or aborting, but this is not + /// a strict requirement. (Specifically: it is *legal* to + /// implement this trait atop an underlying native allocation + /// library that aborts on memory exhaustion.) /// - /// **FIXME:** what are the exact requirements? - /// In particular around layout *fit*. (See docs for the `Alloc` trait.) + /// Clients wishing to abort computation in response to a + /// reallocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); let new_ptr = self.alloc(new_layout); @@ -523,27 +658,21 @@ pub unsafe trait GlobalAlloc { /// retain their validity until at least the instance of `Alloc` is dropped /// itself. /// -/// * It's undefined behavior if global allocators unwind. This restriction may -/// be lifted in the future, but currently a panic from any of these -/// functions may lead to memory unsafety. Note that as of the time of this -/// writing allocators *not* intending to be global allocators can still panic -/// in their implementation without violating memory safety. -/// /// * `Layout` queries and calculations in general must be correct. Callers of /// this trait are allowed to rely on the contracts defined on each method, /// and implementors must ensure such contracts remain true. /// /// Note that this list may get tweaked over time as clarifications are made in -/// the future. Additionally global allocators may gain unique requirements for -/// how to safely implement one in the future as well. +/// the future. pub unsafe trait Alloc { - // (Note: existing allocators have unspecified but well-defined + // (Note: some existing allocators have unspecified but well-defined // behavior in response to a zero size allocation request ; // e.g. in C, `malloc` of 0 will either return a null pointer or a // unique pointer, but will not have arbitrary undefined - // behavior. Rust should consider revising the alloc::heap crate - // to reflect this reality.) + // behavior. + // However in jemalloc for example, + // `mallocx(0)` is documented as undefined behavior.) /// Returns a pointer meeting the size and alignment guarantees of /// `layout`. @@ -579,8 +708,8 @@ pub unsafe trait Alloc { /// library that aborts on memory exhaustion.) /// /// Clients wishing to abort computation in response to an - /// allocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// allocation error are encouraged to call the `oom` function, + /// rather than directly invoking `panic!` or similar. unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr>; /// Deallocate the memory referenced by `ptr`. @@ -686,9 +815,9 @@ pub unsafe trait Alloc { /// implement this trait atop an underlying native allocation /// library that aborts on memory exhaustion.) /// - /// Clients wishing to abort computation in response to an - /// reallocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// Clients wishing to abort computation in response to a + /// reallocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn realloc(&mut self, ptr: NonNull, layout: Layout, @@ -731,8 +860,8 @@ pub unsafe trait Alloc { /// constraints, just as in `alloc`. /// /// Clients wishing to abort computation in response to an - /// allocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// allocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { let size = layout.size(); let p = self.alloc(layout); @@ -757,8 +886,8 @@ pub unsafe trait Alloc { /// constraints, just as in `alloc`. /// /// Clients wishing to abort computation in response to an - /// allocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// allocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { let usable_size = self.usable_size(&layout); self.alloc(layout).map(|p| Excess(p, usable_size.1)) @@ -778,9 +907,9 @@ pub unsafe trait Alloc { /// `layout` does not meet allocator's size or alignment /// constraints, just as in `realloc`. /// - /// Clients wishing to abort computation in response to an - /// reallocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// Clients wishing to abort computation in response to a + /// reallocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn realloc_excess(&mut self, ptr: NonNull, layout: Layout, @@ -823,7 +952,7 @@ pub unsafe trait Alloc { /// could fit `layout`. /// /// Note that one cannot pass `CannotReallocInPlace` to the `oom` - /// method; clients are expected either to be able to recover from + /// function; clients are expected either to be able to recover from /// `grow_in_place` failures without aborting, or to fall back on /// another reallocation method before resorting to an abort. unsafe fn grow_in_place(&mut self, @@ -878,7 +1007,7 @@ pub unsafe trait Alloc { /// could fit `layout`. /// /// Note that one cannot pass `CannotReallocInPlace` to the `oom` - /// method; clients are expected either to be able to recover from + /// function; clients are expected either to be able to recover from /// `shrink_in_place` failures without aborting, or to fall back /// on another reallocation method before resorting to an abort. unsafe fn shrink_in_place(&mut self, @@ -926,8 +1055,8 @@ pub unsafe trait Alloc { /// will *not* yield undefined behavior. /// /// Clients wishing to abort computation in response to an - /// allocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// allocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. fn alloc_one(&mut self) -> Result, AllocErr> where Self: Sized { @@ -993,8 +1122,8 @@ pub unsafe trait Alloc { /// Always returns `Err` on arithmetic overflow. /// /// Clients wishing to abort computation in response to an - /// allocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// allocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. fn alloc_array(&mut self, n: usize) -> Result, AllocErr> where Self: Sized { @@ -1037,9 +1166,9 @@ pub unsafe trait Alloc { /// /// Always returns `Err` on arithmetic overflow. /// - /// Clients wishing to abort computation in response to an - /// reallocation error are encouraged to call the allocator's `oom` - /// method, rather than directly invoking `panic!` or similar. + /// Clients wishing to abort computation in response to a + /// reallocation error are encouraged to call the [`oom`] function, + /// rather than directly invoking `panic!` or similar. unsafe fn realloc_array(&mut self, ptr: NonNull, n_old: usize, diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 9904634f1fa..9126155a7c9 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! dox +//! Memory allocation APIs #![unstable(issue = "32838", feature = "allocator_api")] -- cgit 1.4.1-3-g733a5 From 951bc28fd09f5fed793021c6be1645e034394491 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 31 May 2018 18:36:51 +0200 Subject: Stablize the alloc module without changing stability of its contents. --- src/liballoc/alloc.rs | 11 ++++----- src/libcore/alloc.rs | 32 +++++++++++++++++++++----- src/libstd/alloc.rs | 19 ++++++++++----- src/test/compile-fail/lint-stability-fields.rs | 7 ++++++ 4 files changed, 51 insertions(+), 18 deletions(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index c9430a29e4c..fc3d0151ec0 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -10,17 +10,13 @@ //! Memory allocation APIs -#![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")] +#![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::*; @@ -44,6 +40,7 @@ extern "Rust" { /// 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; @@ -119,6 +116,7 @@ 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, AllocErr> { @@ -188,6 +186,7 @@ pub(crate) unsafe fn box_free(ptr: Unique) { /// and abort the process. /// It can be replaced with [`std::alloc::set_oom_hook`] /// and [`std::alloc::take_oom_hook`]. +#[unstable(feature = "allocator_api", issue = "32838")] #[rustc_allocator_nounwind] pub fn oom(layout: Layout) -> ! { #[allow(improper_ctypes)] diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 8fcd8555cdc..ae9f77d35cf 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -10,12 +10,7 @@ //! Memory allocation APIs -#![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")] +#![stable(feature = "alloc_module", since = "1.28.0")] use cmp; use fmt; @@ -24,11 +19,13 @@ use usize; use ptr::{self, NonNull}; use num::NonZeroUsize; +#[unstable(feature = "allocator_api", issue = "32838")] #[cfg(stage0)] pub type Opaque = u8; /// Represents the combination of a starting address and /// a total capacity of the returned block. +#[unstable(feature = "allocator_api", issue = "32838")] #[derive(Debug)] pub struct Excess(pub NonNull, pub usize); @@ -49,6 +46,7 @@ fn size_align() -> (usize, usize) { /// requests have positive size. A caller to the `Alloc::alloc` /// method must either ensure that conditions like this are met, or /// use specific allocators with looser requirements.) +#[unstable(feature = "allocator_api", issue = "32838")] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Layout { // size of the requested block of memory, measured in bytes. @@ -74,6 +72,7 @@ impl Layout { /// * `size`, when rounded up to the nearest multiple of `align`, /// must not overflow (i.e. the rounded value must be less than /// `usize::MAX`). + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn from_size_align(size: usize, align: usize) -> Result { if !align.is_power_of_two() { @@ -109,20 +108,24 @@ impl Layout { /// /// This function is unsafe as it does not verify the preconditions from /// [`Layout::from_size_align`](#method.from_size_align). + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self { Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) } } /// The minimum size in bytes for a memory block of this layout. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn size(&self) -> usize { self.size_ } /// The minimum byte alignment for a memory block of this layout. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn align(&self) -> usize { self.align_.get() } /// Constructs a `Layout` suitable for holding a value of type `T`. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new() -> Self { let (size, align) = size_align::(); @@ -139,6 +142,7 @@ impl Layout { /// Produces layout describing a record that could be used to /// allocate backing structure for `T` (which could be a trait /// or other unsized type like a slice). + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn for_value(t: &T) -> Self { let (size, align) = (mem::size_of_val(t), mem::align_of_val(t)); @@ -166,6 +170,7 @@ impl Layout { /// Panics if the combination of `self.size()` and the given `align` /// violates the conditions listed in /// [`Layout::from_size_align`](#method.from_size_align). + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn align_to(&self, align: usize) -> Self { Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap() @@ -187,6 +192,7 @@ impl Layout { /// to be less than or equal to the alignment of the starting /// address for the whole allocated block of memory. One way to /// satisfy this constraint is to ensure `align <= self.align()`. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn padding_needed_for(&self, align: usize) -> usize { let len = self.size(); @@ -223,6 +229,7 @@ impl Layout { /// of each element in the array. /// /// On arithmetic overflow, returns `LayoutErr`. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> { let padded_size = self.size().checked_add(self.padding_needed_for(self.align())) @@ -248,6 +255,7 @@ impl Layout { /// (assuming that the record itself starts at offset 0). /// /// On arithmetic overflow, returns `LayoutErr`. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> { let new_align = cmp::max(self.align(), next.align()); @@ -274,6 +282,7 @@ impl Layout { /// aligned. /// /// On arithmetic overflow, returns `LayoutErr`. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn repeat_packed(&self, n: usize) -> Result { let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?; @@ -295,6 +304,7 @@ impl Layout { /// `extend`.) /// /// On arithmetic overflow, returns `LayoutErr`. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> { let new_size = self.size().checked_add(next.size()) @@ -306,6 +316,7 @@ impl Layout { /// Creates a layout describing the record for a `[T; n]`. /// /// On arithmetic overflow, returns `LayoutErr`. + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn array(n: usize) -> Result { Layout::new::() @@ -320,12 +331,14 @@ impl Layout { /// The parameters given to `Layout::from_size_align` /// or some other `Layout` constructor /// do not satisfy its documented constraints. +#[unstable(feature = "allocator_api", issue = "32838")] #[derive(Clone, PartialEq, Eq, Debug)] pub struct LayoutErr { private: () } // (we need this for downstream impl of trait Error) +#[unstable(feature = "allocator_api", issue = "32838")] impl fmt::Display for LayoutErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("invalid parameters to Layout::from_size_align") @@ -336,10 +349,12 @@ impl fmt::Display for LayoutErr { /// that may be due to resource exhaustion or to /// something wrong when combining the given input arguments with this /// allocator. +#[unstable(feature = "allocator_api", issue = "32838")] #[derive(Clone, PartialEq, Eq, Debug)] pub struct AllocErr; // (we need this for downstream impl of trait Error) +#[unstable(feature = "allocator_api", issue = "32838")] impl fmt::Display for AllocErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("memory allocation failed") @@ -350,9 +365,11 @@ impl fmt::Display for AllocErr { /// `shrink_in_place` were unable to reuse the given memory block for /// a requested layout. // FIXME: should this be in libcore or liballoc? +#[unstable(feature = "allocator_api", issue = "32838")] #[derive(Clone, PartialEq, Eq, Debug)] pub struct CannotReallocInPlace; +#[unstable(feature = "allocator_api", issue = "32838")] impl CannotReallocInPlace { pub fn description(&self) -> &str { "cannot reallocate allocator's memory in place" @@ -360,6 +377,7 @@ impl CannotReallocInPlace { } // (we need this for downstream impl of trait Error) +#[unstable(feature = "allocator_api", issue = "32838")] impl fmt::Display for CannotReallocInPlace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) @@ -449,6 +467,7 @@ impl From for CollectionAllocErr { /// * `Layout` queries and calculations in general must be correct. Callers of /// this trait are allowed to rely on the contracts defined on each method, /// and implementors must ensure such contracts remain true. +#[unstable(feature = "allocator_api", issue = "32838")] pub unsafe trait GlobalAlloc { /// Allocate memory as described by the given `layout`. /// @@ -664,6 +683,7 @@ pub unsafe trait GlobalAlloc { /// /// Note that this list may get tweaked over time as clarifications are made in /// the future. +#[unstable(feature = "allocator_api", issue = "32838")] pub unsafe trait Alloc { // (Note: some existing allocators have unspecified but well-defined diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 9126155a7c9..1a4869f87c9 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -10,17 +10,20 @@ //! Memory allocation APIs -#![unstable(issue = "32838", feature = "allocator_api")] - -#[doc(inline)] pub use alloc_crate::alloc::{Global, Layout, oom}; -#[doc(inline)] pub use alloc_crate::alloc::{alloc, alloc_zeroed, dealloc, realloc}; -#[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::*; + +#[unstable(feature = "allocator_api", issue = "32838")] +#[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 +37,7 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); /// about the allocation that failed. /// /// The OOM hook is a global resource. +#[unstable(feature = "allocator_api", issue = "32838")] pub fn set_oom_hook(hook: fn(Layout)) { HOOK.store(hook as *mut (), Ordering::SeqCst); } @@ -43,6 +47,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 = "allocator_api", issue = "32838")] pub fn take_oom_hook() -> fn(Layout) { let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); if hook.is_null() { @@ -59,6 +64,7 @@ fn default_oom_hook(layout: Layout) { #[cfg(not(test))] #[doc(hidden)] #[lang = "oom"] +#[unstable(feature = "allocator_api", issue = "32838")] pub extern fn rust_oom(layout: Layout) -> ! { let hook = HOOK.load(Ordering::SeqCst); let hook: fn(Layout) = if hook.is_null() { @@ -73,6 +79,7 @@ pub extern fn rust_oom(layout: Layout) -> ! { #[cfg(not(test))] #[doc(hidden)] #[allow(unused_attributes)] +#[unstable(feature = "allocator_api", issue = "32838")] pub mod __default_lib_allocator { use super::{System, Layout, GlobalAlloc}; // for symbol names src/librustc/middle/allocator.rs diff --git a/src/test/compile-fail/lint-stability-fields.rs b/src/test/compile-fail/lint-stability-fields.rs index 1b605bdb893..b1b1a9a1fbf 100644 --- a/src/test/compile-fail/lint-stability-fields.rs +++ b/src/test/compile-fail/lint-stability-fields.rs @@ -18,6 +18,11 @@ mod cross_crate { extern crate lint_stability_fields; + mod reexport { + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::lint_stability_fields::*; + } + use self::lint_stability_fields::*; pub fn foo() { @@ -73,6 +78,8 @@ mod cross_crate { // the patterns are all fine: { .. } = x; + // Unstable items are still unstable even when used through a stable "pub use". + let x = reexport::Unstable2(1, 2, 3); //~ ERROR use of unstable let x = Unstable2(1, 2, 3); //~ ERROR use of unstable -- cgit 1.4.1-3-g733a5 From 45d6d207b00cb1353d0f66d4319f2bdcf1fbc892 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 31 May 2018 19:13:37 +0200 Subject: Stabilize alloc free functions for the global allocators. --- src/liballoc/alloc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index fc3d0151ec0..839b1bf99be 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -56,7 +56,7 @@ pub struct Global; /// # Safety /// /// See [`GlobalAlloc::alloc`]. -#[unstable(feature = "allocator_api", issue = "32838")] +#[stable(feature = "global_alloc", since = "1.28.0")] #[inline] pub unsafe fn alloc(layout: Layout) -> *mut u8 { __rust_alloc(layout.size(), layout.align()) @@ -74,7 +74,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { /// # Safety /// /// See [`GlobalAlloc::dealloc`]. -#[unstable(feature = "allocator_api", issue = "32838")] +#[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()) @@ -92,7 +92,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { /// # Safety /// /// See [`GlobalAlloc::realloc`]. -#[unstable(feature = "allocator_api", issue = "32838")] +#[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) @@ -110,7 +110,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 /// # Safety /// /// See [`GlobalAlloc::alloc_zeroed`]. -#[unstable(feature = "allocator_api", issue = "32838")] +#[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()) -- cgit 1.4.1-3-g733a5 From 125b259b3567f6370d5c242eb102ca0957ffe017 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 31 May 2018 19:13:57 +0200 Subject: Stabilize alloc::oom (but not set_oom_hook or take_oom_hook) --- src/liballoc/alloc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 839b1bf99be..fef668d2365 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -186,7 +186,7 @@ pub(crate) unsafe fn box_free(ptr: Unique) { /// and abort the process. /// It can be replaced with [`std::alloc::set_oom_hook`] /// and [`std::alloc::take_oom_hook`]. -#[unstable(feature = "allocator_api", issue = "32838")] +#[stable(feature = "global_alloc", since = "1.28.0")] #[rustc_allocator_nounwind] pub fn oom(layout: Layout) -> ! { #[allow(improper_ctypes)] -- cgit 1.4.1-3-g733a5 From 7f0d54d98842c786ab7a140c17c3ea32aea6aead Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 1 Jun 2018 09:18:25 +0200 Subject: More alloc docs tweaks --- src/liballoc/alloc.rs | 6 ++++-- src/libcore/alloc.rs | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'src/liballoc/alloc.rs') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index fef668d2365..04c8063ffeb 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -184,8 +184,10 @@ pub(crate) unsafe fn box_free(ptr: Unique) { /// /// The default behavior of this function is to print a message to standard error /// and abort the process. -/// It can be replaced with [`std::alloc::set_oom_hook`] -/// and [`std::alloc::take_oom_hook`]. +/// 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) -> ! { diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index b0ac43e50f5..353688d1b85 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -494,6 +494,8 @@ pub unsafe trait GlobalAlloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html #[stable(feature = "global_alloc", since = "1.28.0")] unsafe fn alloc(&self, layout: Layout) -> *mut u8; @@ -529,6 +531,8 @@ pub unsafe trait GlobalAlloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html #[stable(feature = "global_alloc", since = "1.28.0")] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { let size = layout.size(); @@ -587,6 +591,8 @@ pub unsafe trait GlobalAlloc { /// Clients wishing to abort computation in response to a /// reallocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html #[stable(feature = "global_alloc", since = "1.28.0")] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); @@ -727,8 +733,10 @@ pub unsafe trait Alloc { /// library that aborts on memory exhaustion.) /// /// Clients wishing to abort computation in response to an - /// allocation error are encouraged to call the `oom` function, + /// allocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr>; /// Deallocate the memory referenced by `ptr`. @@ -837,6 +845,8 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to a /// reallocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html unsafe fn realloc(&mut self, ptr: NonNull, layout: Layout, @@ -881,6 +891,8 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { let size = layout.size(); let p = self.alloc(layout); @@ -907,6 +919,8 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { let usable_size = self.usable_size(&layout); self.alloc(layout).map(|p| Excess(p, usable_size.1)) @@ -929,6 +943,8 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to a /// reallocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html unsafe fn realloc_excess(&mut self, ptr: NonNull, layout: Layout, @@ -1076,6 +1092,8 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html fn alloc_one(&mut self) -> Result, AllocErr> where Self: Sized { @@ -1143,6 +1161,8 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html fn alloc_array(&mut self, n: usize) -> Result, AllocErr> where Self: Sized { @@ -1188,6 +1208,8 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to a /// reallocation error are encouraged to call the [`oom`] function, /// rather than directly invoking `panic!` or similar. + /// + /// [`oom`]: ../../alloc/alloc/fn.oom.html unsafe fn realloc_array(&mut self, ptr: NonNull, n_old: usize, -- cgit 1.4.1-3-g733a5