Make AllocErr a zero-size unit struct
This commit is contained in:
parent
a4caac5e93
commit
ba7081a033
7 changed files with 51 additions and 135 deletions
|
@ -16,7 +16,7 @@
|
|||
issue = "32838")]
|
||||
|
||||
use core::intrinsics::{min_align_of_val, size_of_val};
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
use core::mem;
|
||||
use core::usize;
|
||||
|
||||
#[doc(inline)]
|
||||
|
@ -86,12 +86,12 @@ pub const Heap: Global = Global;
|
|||
unsafe impl Alloc for Global {
|
||||
#[inline]
|
||||
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
||||
let mut err = ManuallyDrop::new(mem::uninitialized::<AllocErr>());
|
||||
let mut err = AllocErr;
|
||||
let ptr = __rust_alloc(layout.size(),
|
||||
layout.align(),
|
||||
&mut *err as *mut AllocErr as *mut u8);
|
||||
&mut err as *mut AllocErr as *mut u8);
|
||||
if ptr.is_null() {
|
||||
Err(ManuallyDrop::into_inner(err))
|
||||
Err(AllocErr)
|
||||
} else {
|
||||
Ok(ptr)
|
||||
}
|
||||
|
@ -129,15 +129,15 @@ unsafe impl Alloc for Global {
|
|||
new_layout: Layout)
|
||||
-> Result<*mut u8, AllocErr>
|
||||
{
|
||||
let mut err = ManuallyDrop::new(mem::uninitialized::<AllocErr>());
|
||||
let mut err = AllocErr;
|
||||
let ptr = __rust_realloc(ptr,
|
||||
layout.size(),
|
||||
layout.align(),
|
||||
new_layout.size(),
|
||||
new_layout.align(),
|
||||
&mut *err as *mut AllocErr as *mut u8);
|
||||
&mut err as *mut AllocErr as *mut u8);
|
||||
if ptr.is_null() {
|
||||
Err(ManuallyDrop::into_inner(err))
|
||||
Err(AllocErr)
|
||||
} else {
|
||||
mem::forget(err);
|
||||
Ok(ptr)
|
||||
|
@ -146,12 +146,12 @@ unsafe impl Alloc for Global {
|
|||
|
||||
#[inline]
|
||||
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
||||
let mut err = ManuallyDrop::new(mem::uninitialized::<AllocErr>());
|
||||
let mut err = AllocErr;
|
||||
let ptr = __rust_alloc_zeroed(layout.size(),
|
||||
layout.align(),
|
||||
&mut *err as *mut AllocErr as *mut u8);
|
||||
&mut err as *mut AllocErr as *mut u8);
|
||||
if ptr.is_null() {
|
||||
Err(ManuallyDrop::into_inner(err))
|
||||
Err(AllocErr)
|
||||
} else {
|
||||
Ok(ptr)
|
||||
}
|
||||
|
@ -159,14 +159,14 @@ unsafe impl Alloc for Global {
|
|||
|
||||
#[inline]
|
||||
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
|
||||
let mut err = ManuallyDrop::new(mem::uninitialized::<AllocErr>());
|
||||
let mut err = AllocErr;
|
||||
let mut size = 0;
|
||||
let ptr = __rust_alloc_excess(layout.size(),
|
||||
layout.align(),
|
||||
&mut size,
|
||||
&mut *err as *mut AllocErr as *mut u8);
|
||||
&mut err as *mut AllocErr as *mut u8);
|
||||
if ptr.is_null() {
|
||||
Err(ManuallyDrop::into_inner(err))
|
||||
Err(AllocErr)
|
||||
} else {
|
||||
Ok(Excess(ptr, size))
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ unsafe impl Alloc for Global {
|
|||
ptr: *mut u8,
|
||||
layout: Layout,
|
||||
new_layout: Layout) -> Result<Excess, AllocErr> {
|
||||
let mut err = ManuallyDrop::new(mem::uninitialized::<AllocErr>());
|
||||
let mut err = AllocErr;
|
||||
let mut size = 0;
|
||||
let ptr = __rust_realloc_excess(ptr,
|
||||
layout.size(),
|
||||
|
@ -185,9 +185,9 @@ unsafe impl Alloc for Global {
|
|||
new_layout.size(),
|
||||
new_layout.align(),
|
||||
&mut size,
|
||||
&mut *err as *mut AllocErr as *mut u8);
|
||||
&mut err as *mut AllocErr as *mut u8);
|
||||
if ptr.is_null() {
|
||||
Err(ManuallyDrop::into_inner(err))
|
||||
Err(AllocErr)
|
||||
} else {
|
||||
Ok(Excess(ptr, size))
|
||||
}
|
||||
|
|
|
@ -760,7 +760,7 @@ mod tests {
|
|||
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
||||
let size = layout.size();
|
||||
if size > self.fuel {
|
||||
return Err(AllocErr::Unsupported { details: "fuel exhausted" });
|
||||
return Err(AllocErr);
|
||||
}
|
||||
match Global.alloc(layout) {
|
||||
ok @ Ok(_) => { self.fuel -= size; ok }
|
||||
|
|
|
@ -30,8 +30,6 @@ extern crate libc;
|
|||
pub use contents::*;
|
||||
#[cfg(not(dummy_jemalloc))]
|
||||
mod contents {
|
||||
use core::ptr;
|
||||
|
||||
use core::alloc::{Alloc, AllocErr, Layout};
|
||||
use alloc_system::System;
|
||||
use libc::{c_int, c_void, size_t};
|
||||
|
@ -106,14 +104,9 @@ mod contents {
|
|||
#[rustc_std_internal_symbol]
|
||||
pub unsafe extern fn __rde_alloc(size: usize,
|
||||
align: usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
let flags = align_to_flags(align, size);
|
||||
let ptr = mallocx(size as size_t, flags) as *mut u8;
|
||||
if ptr.is_null() {
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
ptr::write(err as *mut AllocErr,
|
||||
AllocErr::Exhausted { request: layout });
|
||||
}
|
||||
ptr
|
||||
}
|
||||
|
||||
|
@ -155,20 +148,13 @@ mod contents {
|
|||
old_align: usize,
|
||||
new_size: usize,
|
||||
new_align: usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
if new_align != old_align {
|
||||
ptr::write(err as *mut AllocErr,
|
||||
AllocErr::Unsupported { details: "can't change alignments" });
|
||||
return 0 as *mut u8
|
||||
}
|
||||
|
||||
let flags = align_to_flags(new_align, new_size);
|
||||
let ptr = rallocx(ptr as *mut c_void, new_size, flags) as *mut u8;
|
||||
if ptr.is_null() {
|
||||
let layout = Layout::from_size_align_unchecked(new_size, new_align);
|
||||
ptr::write(err as *mut AllocErr,
|
||||
AllocErr::Exhausted { request: layout });
|
||||
}
|
||||
ptr
|
||||
}
|
||||
|
||||
|
@ -176,18 +162,13 @@ mod contents {
|
|||
#[rustc_std_internal_symbol]
|
||||
pub unsafe extern fn __rde_alloc_zeroed(size: usize,
|
||||
align: usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
let ptr = if align <= MIN_ALIGN && align <= size {
|
||||
calloc(size as size_t, 1) as *mut u8
|
||||
} else {
|
||||
let flags = align_to_flags(align, size) | MALLOCX_ZERO;
|
||||
mallocx(size as size_t, flags) as *mut u8
|
||||
};
|
||||
if ptr.is_null() {
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
ptr::write(err as *mut AllocErr,
|
||||
AllocErr::Exhausted { request: layout });
|
||||
}
|
||||
ptr
|
||||
}
|
||||
|
||||
|
|
|
@ -133,9 +133,7 @@ mod platform {
|
|||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
if layout.align() > (1 << 31) {
|
||||
return Err(AllocErr::Unsupported {
|
||||
details: "requested alignment too large"
|
||||
})
|
||||
return Err(AllocErr)
|
||||
}
|
||||
}
|
||||
aligned_malloc(&layout)
|
||||
|
@ -143,7 +141,7 @@ mod platform {
|
|||
if !ptr.is_null() {
|
||||
Ok(ptr)
|
||||
} else {
|
||||
Err(AllocErr::Exhausted { request: layout })
|
||||
Err(AllocErr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +154,7 @@ mod platform {
|
|||
if !ptr.is_null() {
|
||||
Ok(ptr)
|
||||
} else {
|
||||
Err(AllocErr::Exhausted { request: layout })
|
||||
Err(AllocErr)
|
||||
}
|
||||
} else {
|
||||
let ret = self.alloc(layout.clone());
|
||||
|
@ -178,9 +176,7 @@ mod platform {
|
|||
old_layout: Layout,
|
||||
new_layout: Layout) -> Result<*mut u8, AllocErr> {
|
||||
if old_layout.align() != new_layout.align() {
|
||||
return Err(AllocErr::Unsupported {
|
||||
details: "cannot change alignment on `realloc`",
|
||||
})
|
||||
return Err(AllocErr)
|
||||
}
|
||||
|
||||
if new_layout.align() <= MIN_ALIGN && new_layout.align() <= new_layout.size(){
|
||||
|
@ -188,7 +184,7 @@ mod platform {
|
|||
if !ptr.is_null() {
|
||||
Ok(ptr as *mut u8)
|
||||
} else {
|
||||
Err(AllocErr::Exhausted { request: new_layout })
|
||||
Err(AllocErr)
|
||||
}
|
||||
} else {
|
||||
let res = self.alloc(new_layout.clone());
|
||||
|
@ -342,7 +338,7 @@ mod platform {
|
|||
}
|
||||
};
|
||||
if ptr.is_null() {
|
||||
Err(AllocErr::Exhausted { request: layout })
|
||||
Err(AllocErr)
|
||||
} else {
|
||||
Ok(ptr as *mut u8)
|
||||
}
|
||||
|
@ -382,9 +378,7 @@ mod platform {
|
|||
old_layout: Layout,
|
||||
new_layout: Layout) -> Result<*mut u8, AllocErr> {
|
||||
if old_layout.align() != new_layout.align() {
|
||||
return Err(AllocErr::Unsupported {
|
||||
details: "cannot change alignment on `realloc`",
|
||||
})
|
||||
return Err(AllocErr)
|
||||
}
|
||||
|
||||
if new_layout.align() <= MIN_ALIGN {
|
||||
|
@ -395,7 +389,7 @@ mod platform {
|
|||
if !ptr.is_null() {
|
||||
Ok(ptr as *mut u8)
|
||||
} else {
|
||||
Err(AllocErr::Exhausted { request: new_layout })
|
||||
Err(AllocErr)
|
||||
}
|
||||
} else {
|
||||
let res = self.alloc(new_layout.clone());
|
||||
|
@ -505,7 +499,7 @@ mod platform {
|
|||
if !ptr.is_null() {
|
||||
Ok(ptr)
|
||||
} else {
|
||||
Err(AllocErr::Unsupported { details: "" })
|
||||
Err(AllocErr)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -320,50 +320,12 @@ impl Layout {
|
|||
/// something wrong when combining the given input arguments with this
|
||||
/// allocator.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum AllocErr {
|
||||
/// Error due to hitting some resource limit or otherwise running
|
||||
/// out of memory. This condition strongly implies that *some*
|
||||
/// series of deallocations would allow a subsequent reissuing of
|
||||
/// the original allocation request to succeed.
|
||||
Exhausted { request: Layout },
|
||||
|
||||
/// Error due to allocator being fundamentally incapable of
|
||||
/// satisfying the original request. This condition implies that
|
||||
/// such an allocation request will never succeed on the given
|
||||
/// allocator, regardless of environment, memory pressure, or
|
||||
/// other contextual conditions.
|
||||
///
|
||||
/// For example, an allocator that does not support requests for
|
||||
/// large memory blocks might return this error variant.
|
||||
Unsupported { details: &'static str },
|
||||
}
|
||||
|
||||
impl AllocErr {
|
||||
#[inline]
|
||||
pub fn invalid_input(details: &'static str) -> Self {
|
||||
AllocErr::Unsupported { details: details }
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_memory_exhausted(&self) -> bool {
|
||||
if let AllocErr::Exhausted { .. } = *self { true } else { false }
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_request_unsupported(&self) -> bool {
|
||||
if let AllocErr::Unsupported { .. } = *self { true } else { false }
|
||||
}
|
||||
#[inline]
|
||||
pub fn description(&self) -> &str {
|
||||
match *self {
|
||||
AllocErr::Exhausted { .. } => "allocator memory exhausted",
|
||||
AllocErr::Unsupported { .. } => "unsupported allocator request",
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct AllocErr;
|
||||
|
||||
// (we need this for downstream impl of trait Error)
|
||||
impl fmt::Display for AllocErr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.description())
|
||||
f.write_str("memory allocation failed")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -592,12 +554,8 @@ pub unsafe trait Alloc {
|
|||
/// aborting.
|
||||
///
|
||||
/// `oom` is meant to be used by clients unable to cope with an
|
||||
/// unsatisfied allocation request (signaled by an error such as
|
||||
/// `AllocErr::Exhausted`), and wish to abandon computation rather
|
||||
/// than attempt to recover locally. Such clients should pass the
|
||||
/// signaling error value back into `oom`, where the allocator
|
||||
/// may incorporate that error value into its diagnostic report
|
||||
/// before aborting.
|
||||
/// unsatisfied allocation request, and wish to abandon
|
||||
/// computation rather than attempt to recover locally.
|
||||
///
|
||||
/// Implementations of the `oom` method are discouraged from
|
||||
/// infinitely regressing in nested calls to `oom`. In
|
||||
|
@ -963,7 +921,7 @@ pub unsafe trait Alloc {
|
|||
if k.size() > 0 {
|
||||
unsafe { self.alloc(k).map(|p| NonNull::new_unchecked(p as *mut T)) }
|
||||
} else {
|
||||
Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
|
||||
Err(AllocErr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1036,7 +994,7 @@ pub unsafe trait Alloc {
|
|||
})
|
||||
}
|
||||
}
|
||||
_ => Err(AllocErr::invalid_input("invalid layout for alloc_array")),
|
||||
_ => Err(AllocErr),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1084,7 +1042,7 @@ pub unsafe trait Alloc {
|
|||
.map(|p| NonNull::new_unchecked(p as *mut T))
|
||||
}
|
||||
_ => {
|
||||
Err(AllocErr::invalid_input("invalid layout for realloc_array"))
|
||||
Err(AllocErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1118,7 +1076,7 @@ pub unsafe trait Alloc {
|
|||
Ok(self.dealloc(raw_ptr, k.clone()))
|
||||
}
|
||||
_ => {
|
||||
Err(AllocErr::invalid_input("invalid layout for dealloc_array"))
|
||||
Err(AllocErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,7 @@
|
|||
#[doc(hidden)]
|
||||
#[allow(unused_attributes)]
|
||||
pub mod __default_lib_allocator {
|
||||
use super::{System, Layout, Alloc, AllocErr};
|
||||
use ptr;
|
||||
|
||||
use super::{System, Layout, Alloc, AllocErr, CannotReallocInPlace};
|
||||
// for symbol names src/librustc/middle/allocator.rs
|
||||
// for signatures src/librustc_allocator/lib.rs
|
||||
|
||||
|
@ -34,14 +32,11 @@ pub mod __default_lib_allocator {
|
|||
#[rustc_std_internal_symbol]
|
||||
pub unsafe extern fn __rdl_alloc(size: usize,
|
||||
align: usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
match System.alloc(layout) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
ptr::write(err as *mut AllocErr, e);
|
||||
0 as *mut u8
|
||||
}
|
||||
Err(AllocErr) => 0 as *mut u8,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,15 +71,12 @@ pub mod __default_lib_allocator {
|
|||
old_align: usize,
|
||||
new_size: usize,
|
||||
new_align: usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
|
||||
let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
|
||||
match System.realloc(ptr, old_layout, new_layout) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
ptr::write(err as *mut AllocErr, e);
|
||||
0 as *mut u8
|
||||
}
|
||||
Err(AllocErr) => 0 as *mut u8,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,14 +84,11 @@ pub mod __default_lib_allocator {
|
|||
#[rustc_std_internal_symbol]
|
||||
pub unsafe extern fn __rdl_alloc_zeroed(size: usize,
|
||||
align: usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
match System.alloc_zeroed(layout) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
ptr::write(err as *mut AllocErr, e);
|
||||
0 as *mut u8
|
||||
}
|
||||
Err(AllocErr) => 0 as *mut u8,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,17 +97,14 @@ pub mod __default_lib_allocator {
|
|||
pub unsafe extern fn __rdl_alloc_excess(size: usize,
|
||||
align: usize,
|
||||
excess: *mut usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
match System.alloc_excess(layout) {
|
||||
Ok(p) => {
|
||||
*excess = p.1;
|
||||
p.0
|
||||
}
|
||||
Err(e) => {
|
||||
ptr::write(err as *mut AllocErr, e);
|
||||
0 as *mut u8
|
||||
}
|
||||
Err(AllocErr) => 0 as *mut u8,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +116,7 @@ pub mod __default_lib_allocator {
|
|||
new_size: usize,
|
||||
new_align: usize,
|
||||
excess: *mut usize,
|
||||
err: *mut u8) -> *mut u8 {
|
||||
_err: *mut u8) -> *mut u8 {
|
||||
let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
|
||||
let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
|
||||
match System.realloc_excess(ptr, old_layout, new_layout) {
|
||||
|
@ -138,10 +124,7 @@ pub mod __default_lib_allocator {
|
|||
*excess = p.1;
|
||||
p.0
|
||||
}
|
||||
Err(e) => {
|
||||
ptr::write(err as *mut AllocErr, e);
|
||||
0 as *mut u8
|
||||
}
|
||||
Err(AllocErr) => 0 as *mut u8,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +139,7 @@ pub mod __default_lib_allocator {
|
|||
let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
|
||||
match System.grow_in_place(ptr, old_layout, new_layout) {
|
||||
Ok(()) => 1,
|
||||
Err(_) => 0,
|
||||
Err(CannotReallocInPlace) => 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,7 +154,7 @@ pub mod __default_lib_allocator {
|
|||
let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
|
||||
match System.shrink_in_place(ptr, old_layout, new_layout) {
|
||||
Ok(()) => 1,
|
||||
Err(_) => 0,
|
||||
Err(CannotReallocInPlace) => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,7 +243,7 @@ impl Error for ! {
|
|||
issue = "32838")]
|
||||
impl Error for AllocErr {
|
||||
fn description(&self) -> &str {
|
||||
AllocErr::description(self)
|
||||
"memory allocation failed"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue