//! 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::*;
/// 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;
__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<u8>, AllocErr> {
/// 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)]
//! 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;
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<u8>, pub 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.
/// * `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<Self, LayoutErr> {
if !align.is_power_of_two() {
///
/// 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<T>() -> Self {
let (size, align) = size_align::<T>();
/// 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: ?Sized>(t: &T) -> Self {
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
/// 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()
/// 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();
/// 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()))
/// (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());
/// aligned.
///
/// On arithmetic overflow, returns `LayoutErr`.
+ #[unstable(feature = "allocator_api", issue = "32838")]
#[inline]
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
/// `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())
/// 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<T>(n: usize) -> Result<Self, LayoutErr> {
Layout::new::<T>()
/// 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")
/// 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")
/// `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"
}
// (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())
/// * `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`.
///
///
/// 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
//! 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.
/// 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);
}
/// *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() {
#[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() {
#[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