From 5e5a0c21fc1416e77ae8e4db74b93e3601241e22 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 3 Apr 2018 20:58:50 +0200 Subject: Separate alloc::heap::Alloc trait for stage0 #[global_allocator] --- src/liballoc_system/Cargo.toml | 1 - src/liballoc_system/lib.rs | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc_system/Cargo.toml b/src/liballoc_system/Cargo.toml index 936e20a32e1..c34e2f203a8 100644 --- a/src/liballoc_system/Cargo.toml +++ b/src/liballoc_system/Cargo.toml @@ -10,7 +10,6 @@ test = false doc = false [dependencies] -alloc = { path = "../liballoc" } core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index cdcb732f635..2d5adca7fcb 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -41,7 +41,7 @@ const MIN_ALIGN: usize = 8; #[allow(dead_code)] const MIN_ALIGN: usize = 16; -use core::heap::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace}; +use core::alloc::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace}; #[unstable(feature = "allocator_api", issue = "32838")] pub struct System; @@ -121,7 +121,7 @@ mod platform { use MIN_ALIGN; use System; - use core::heap::{Alloc, AllocErr, Layout}; + use core::alloc::{Alloc, AllocErr, Layout}; #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl<'a> Alloc for &'a System { @@ -283,7 +283,7 @@ mod platform { use MIN_ALIGN; use System; - use core::heap::{Alloc, AllocErr, Layout, CannotReallocInPlace}; + use core::alloc::{Alloc, AllocErr, Layout, CannotReallocInPlace}; type LPVOID = *mut u8; type HANDLE = LPVOID; @@ -495,7 +495,7 @@ mod platform { mod platform { extern crate dlmalloc; - use core::heap::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace}; + use core::alloc::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace}; use System; use self::dlmalloc::GlobalDlmalloc; -- cgit 1.4.1-3-g733a5 From a4caac5e93b801411fb59eeafa399240a7aa5fec Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 9 Apr 2018 11:51:57 -0700 Subject: Update to most recent version of dlmalloc Inline the definition of `GlobalAlloc` for `dlmalloc` on wasm and don't rely on usage of unstable features in `dlmalloc` itself. --- src/Cargo.lock | 1 - src/dlmalloc | 2 +- src/liballoc_system/lib.rs | 62 ++++++++++++-------------------------- src/rustc/dlmalloc_shim/Cargo.toml | 1 - 4 files changed, 20 insertions(+), 46 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/Cargo.lock b/src/Cargo.lock index f573abadc31..e5297d1482e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -540,7 +540,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "dlmalloc" version = "0.0.0" dependencies = [ - "alloc 0.0.0", "compiler_builtins 0.0.0", "core 0.0.0", ] diff --git a/src/dlmalloc b/src/dlmalloc index 9b2dcac06c3..c99638dc2ec 160000 --- a/src/dlmalloc +++ b/src/dlmalloc @@ -1 +1 @@ -Subproject commit 9b2dcac06c3e23235f8997b3c5f2325a6d3382df +Subproject commit c99638dc2ecfc750cc1656f6edb2bd062c1e0981 diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 2d5adca7fcb..6f928287ef2 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -495,27 +495,35 @@ mod platform { mod platform { extern crate dlmalloc; - use core::alloc::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace}; + use core::alloc::{Alloc, AllocErr, Layout}; use System; - use self::dlmalloc::GlobalDlmalloc; + + // No need for synchronization here as wasm is currently single-threaded + static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT; + + fn to_result(ptr: *mut u8) -> Result<*mut u8, AllocErr> { + if !ptr.is_null() { + Ok(ptr) + } else { + Err(AllocErr::Unsupported { details: "" }) + } + } #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl<'a> Alloc for &'a System { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - GlobalDlmalloc.alloc(layout) + to_result(DLMALLOC.malloc(layout.size(), layout.align())) } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> - { - GlobalDlmalloc.alloc_zeroed(layout) + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + to_result(DLMALLOC.calloc(layout.size(), layout.align())) } #[inline] unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - GlobalDlmalloc.dealloc(ptr, layout) + DLMALLOC.free(ptr, layout.size(), layout.align()) } #[inline] @@ -523,41 +531,9 @@ mod platform { ptr: *mut u8, old_layout: Layout, new_layout: Layout) -> Result<*mut u8, AllocErr> { - GlobalDlmalloc.realloc(ptr, old_layout, new_layout) - } - - #[inline] - fn usable_size(&self, layout: &Layout) -> (usize, usize) { - GlobalDlmalloc.usable_size(layout) - } - - #[inline] - unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { - GlobalDlmalloc.alloc_excess(layout) - } - - #[inline] - unsafe fn realloc_excess(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result { - GlobalDlmalloc.realloc_excess(ptr, layout, new_layout) - } - - #[inline] - unsafe fn grow_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - GlobalDlmalloc.grow_in_place(ptr, layout, new_layout) - } - - #[inline] - unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - GlobalDlmalloc.shrink_in_place(ptr, layout, new_layout) + to_result(DLMALLOC.realloc( + ptr, old_layout.size(), old_layout.align(), new_layout.size(), + )) } } } diff --git a/src/rustc/dlmalloc_shim/Cargo.toml b/src/rustc/dlmalloc_shim/Cargo.toml index d2fe159d806..b6f8550829f 100644 --- a/src/rustc/dlmalloc_shim/Cargo.toml +++ b/src/rustc/dlmalloc_shim/Cargo.toml @@ -12,4 +12,3 @@ doc = false [dependencies] core = { path = "../../libcore" } compiler_builtins = { path = "../../rustc/compiler_builtins_shim" } -alloc = { path = "../../liballoc" } -- cgit 1.4.1-3-g733a5 From ba7081a033de4981ccad1e1525c8b5191ce02208 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 3 Apr 2018 15:41:09 +0200 Subject: Make AllocErr a zero-size unit struct --- src/liballoc/alloc.rs | 32 ++++++++++++------------ src/liballoc/raw_vec.rs | 2 +- src/liballoc_jemalloc/lib.rs | 25 +++---------------- src/liballoc_system/lib.rs | 24 +++++++----------- src/libcore/alloc.rs | 58 ++++++-------------------------------------- src/libstd/alloc.rs | 43 ++++++++++---------------------- src/libstd/error.rs | 2 +- 7 files changed, 51 insertions(+), 135 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 00a8b2c0e25..b975ff6be58 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -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::()); + 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::()); + 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::()); + 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 { - let mut err = ManuallyDrop::new(mem::uninitialized::()); + 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 { - let mut err = ManuallyDrop::new(mem::uninitialized::()); + 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)) } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 51f39dc6cc7..caedb971ddc 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -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 } diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 616181d99bc..59a7e87e1ec 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -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 } diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 6f928287ef2..5dca05cf085 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -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) } } diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 5c51bb2b51b..b6626ff9f26 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -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) } } } diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index eb0c960732d..533ad3ad473 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -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, } } } diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 4edb897350e..ec55a3c021a 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -243,7 +243,7 @@ impl Error for ! { issue = "32838")] impl Error for AllocErr { fn description(&self) -> &str { - AllocErr::description(self) + "memory allocation failed" } } -- cgit 1.4.1-3-g733a5 From eb69593f73be1e41d9e2ef065010a47478c14924 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 3 Apr 2018 17:51:03 +0200 Subject: Implement GlobalAlloc for System --- src/liballoc_system/lib.rs | 269 ++++++++++++++++++++++++--------------------- src/libcore/alloc.rs | 4 + 2 files changed, 145 insertions(+), 128 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 5dca05cf085..0480be8d913 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -50,19 +50,19 @@ pub struct System; unsafe impl Alloc for System { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - (&*self).alloc(layout) + Alloc::alloc(&mut &*self, layout) } #[inline] unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - (&*self).alloc_zeroed(layout) + Alloc::alloc_zeroed(&mut &*self, layout) } #[inline] unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - (&*self).dealloc(ptr, layout) + Alloc::dealloc(&mut &*self, ptr, layout) } #[inline] @@ -70,21 +70,21 @@ unsafe impl Alloc for System { ptr: *mut u8, old_layout: Layout, new_layout: Layout) -> Result<*mut u8, AllocErr> { - (&*self).realloc(ptr, old_layout, new_layout) + Alloc::realloc(&mut &*self, ptr, old_layout, new_layout) } fn oom(&mut self, err: AllocErr) -> ! { - (&*self).oom(err) + Alloc::oom(&mut &*self, err) } #[inline] fn usable_size(&self, layout: &Layout) -> (usize, usize) { - (&self).usable_size(layout) + Alloc::usable_size(&mut &*self, layout) } #[inline] unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { - (&*self).alloc_excess(layout) + Alloc::alloc_excess(&mut &*self, layout) } #[inline] @@ -92,7 +92,7 @@ unsafe impl Alloc for System { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result { - (&*self).realloc_excess(ptr, layout, new_layout) + Alloc::realloc_excess(&mut &*self, ptr, layout, new_layout) } #[inline] @@ -100,7 +100,7 @@ unsafe impl Alloc for System { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { - (&*self).grow_in_place(ptr, layout, new_layout) + Alloc::grow_in_place(&mut &*self, ptr, layout, new_layout) } #[inline] @@ -108,7 +108,76 @@ unsafe impl Alloc for System { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { - (&*self).shrink_in_place(ptr, layout, new_layout) + Alloc::shrink_in_place(&mut &*self, ptr, layout, new_layout) + } +} + +#[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))] +mod realloc_fallback { + use core::alloc::{GlobalAlloc, Void, Layout}; + use core::cmp; + use core::ptr; + + impl super::System { + pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut Void, old_layout: Layout, + new_size: usize) -> *mut Void { + // Docs for GlobalAlloc::realloc require this to be valid: + let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); + + let new_ptr = GlobalAlloc::alloc(self, new_layout); + if !new_ptr.is_null() { + let size = cmp::min(old_layout.size(), new_size); + ptr::copy_nonoverlapping(ptr as *mut u8, new_ptr as *mut u8, size); + GlobalAlloc::dealloc(self, ptr, old_layout); + } + new_ptr + } + } +} + +macro_rules! alloc_methods_based_on_global_alloc { + () => { + #[inline] + unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + let ptr = GlobalAlloc::alloc(*self, layout); + if !ptr.is_null() { + Ok(ptr as *mut u8) + } else { + Err(AllocErr) + } + } + + #[inline] + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + let ptr = GlobalAlloc::alloc_zeroed(*self, layout); + if !ptr.is_null() { + Ok(ptr as *mut u8) + } else { + Err(AllocErr) + } + } + + #[inline] + unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + GlobalAlloc::dealloc(*self, ptr as *mut Void, layout) + } + + #[inline] + unsafe fn realloc(&mut self, + ptr: *mut u8, + old_layout: Layout, + new_layout: Layout) -> Result<*mut u8, AllocErr> { + if old_layout.align() != new_layout.align() { + return Err(AllocErr) + } + + let ptr = GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_layout.size()); + if !ptr.is_null() { + Ok(ptr as *mut u8) + } else { + Err(AllocErr) + } + } } } @@ -116,86 +185,62 @@ unsafe impl Alloc for System { mod platform { extern crate libc; - use core::cmp; use core::ptr; use MIN_ALIGN; use System; - use core::alloc::{Alloc, AllocErr, Layout}; + use core::alloc::{GlobalAlloc, Alloc, AllocErr, Layout, Void}; #[unstable(feature = "allocator_api", issue = "32838")] - unsafe impl<'a> Alloc for &'a System { + unsafe impl GlobalAlloc for System { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::malloc(layout.size()) as *mut u8 + unsafe fn alloc(&self, layout: Layout) -> *mut Void { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + libc::malloc(layout.size()) as *mut Void } else { #[cfg(target_os = "macos")] { if layout.align() > (1 << 31) { - return Err(AllocErr) + // FIXME: use Void::null_mut https://github.com/rust-lang/rust/issues/49659 + return 0 as *mut Void } } aligned_malloc(&layout) - }; - if !ptr.is_null() { - Ok(ptr) - } else { - Err(AllocErr) } } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> - { + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - let ptr = libc::calloc(layout.size(), 1) as *mut u8; - if !ptr.is_null() { - Ok(ptr) - } else { - Err(AllocErr) - } + libc::calloc(layout.size(), 1) as *mut Void } else { - let ret = self.alloc(layout.clone()); - if let Ok(ptr) = ret { - ptr::write_bytes(ptr, 0, layout.size()); + let ptr = self.alloc(layout.clone()); + if !ptr.is_null() { + ptr::write_bytes(ptr as *mut u8, 0, layout.size()); } - ret + ptr } } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, _layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Void, _layout: Layout) { libc::free(ptr as *mut libc::c_void) } #[inline] - unsafe fn realloc(&mut self, - ptr: *mut u8, - old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - if old_layout.align() != new_layout.align() { - return Err(AllocErr) - } - - if new_layout.align() <= MIN_ALIGN && new_layout.align() <= new_layout.size(){ - let ptr = libc::realloc(ptr as *mut libc::c_void, new_layout.size()); - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr) - } + unsafe fn realloc(&self, ptr: *mut Void, old_layout: Layout, new_size: usize) -> *mut Void { + let align = old_layout.align(); + if align <= MIN_ALIGN && align <= new_size { + libc::realloc(ptr as *mut libc::c_void, new_size) as *mut Void } else { - let res = self.alloc(new_layout.clone()); - if let Ok(new_ptr) = res { - let size = cmp::min(old_layout.size(), new_layout.size()); - ptr::copy_nonoverlapping(ptr, new_ptr, size); - self.dealloc(ptr, old_layout); - } - res + self.realloc_fallback(ptr, old_layout, new_size) } } + } + + #[unstable(feature = "allocator_api", issue = "32838")] + unsafe impl<'a> Alloc for &'a System { + alloc_methods_based_on_global_alloc!(); fn oom(&mut self, err: AllocErr) -> ! { use core::fmt::{self, Write}; @@ -237,7 +282,7 @@ mod platform { #[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))] #[inline] - unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { + unsafe fn aligned_malloc(layout: &Layout) -> *mut Void { // On android we currently target API level 9 which unfortunately // doesn't have the `posix_memalign` API used below. Instead we use // `memalign`, but this unfortunately has the property on some systems @@ -255,18 +300,18 @@ mod platform { // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579 // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/ // /memory/aligned_memory.cc - libc::memalign(layout.align(), layout.size()) as *mut u8 + libc::memalign(layout.align(), layout.size()) as *mut Void } #[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))] #[inline] - unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { + unsafe fn aligned_malloc(layout: &Layout) -> *mut Void { let mut out = ptr::null_mut(); let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); if ret != 0 { - ptr::null_mut() + 0 as *mut Void } else { - out as *mut u8 + out as *mut Void } } } @@ -274,12 +319,11 @@ mod platform { #[cfg(windows)] #[allow(bad_style)] mod platform { - use core::cmp; use core::ptr; use MIN_ALIGN; use System; - use core::alloc::{Alloc, AllocErr, Layout, CannotReallocInPlace}; + use core::alloc::{GlobalAlloc, Alloc, Void, AllocErr, Layout, CannotReallocInPlace}; type LPVOID = *mut u8; type HANDLE = LPVOID; @@ -323,9 +367,7 @@ mod platform { } #[inline] - unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) - -> Result<*mut u8, AllocErr> - { + unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut Void { let ptr = if layout.align() <= MIN_ALIGN { HeapAlloc(GetProcessHeap(), flags, layout.size()) } else { @@ -337,35 +379,29 @@ mod platform { align_ptr(ptr, layout.align()) } }; - if ptr.is_null() { - Err(AllocErr) - } else { - Ok(ptr as *mut u8) - } + ptr as *mut Void } #[unstable(feature = "allocator_api", issue = "32838")] - unsafe impl<'a> Alloc for &'a System { + unsafe impl GlobalAlloc for System { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&self, layout: Layout) -> *mut Void { allocate_with_flags(layout, 0) } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> - { + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { allocate_with_flags(layout, HEAP_ZERO_MEMORY) } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { if layout.align() <= MIN_ALIGN { let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); } else { - let header = get_header(ptr); + let header = get_header(ptr as *mut u8); let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); @@ -373,34 +409,19 @@ mod platform { } #[inline] - unsafe fn realloc(&mut self, - ptr: *mut u8, - old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - if old_layout.align() != new_layout.align() { - return Err(AllocErr) - } - - if new_layout.align() <= MIN_ALIGN { - let ptr = HeapReAlloc(GetProcessHeap(), - 0, - ptr as LPVOID, - new_layout.size()); - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr) - } + unsafe fn realloc(&self, ptr: *mut Void, old_layout: Layout, new_size: usize) -> *mut Void { + let align = old_layout.align(); + if align <= MIN_ALIGN { + HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut Void } else { - let res = self.alloc(new_layout.clone()); - if let Ok(new_ptr) = res { - let size = cmp::min(old_layout.size(), new_layout.size()); - ptr::copy_nonoverlapping(ptr, new_ptr, size); - self.dealloc(ptr, old_layout); - } - res + self.realloc_fallback(ptr, old_layout, new_size) } } + } + + #[unstable(feature = "allocator_api", issue = "32838")] + unsafe impl<'a> Alloc for &'a System { + alloc_methods_based_on_global_alloc!(); #[inline] unsafe fn grow_in_place(&mut self, @@ -489,45 +510,37 @@ mod platform { mod platform { extern crate dlmalloc; - use core::alloc::{Alloc, AllocErr, Layout}; + use core::alloc::{GlobalAlloc, Alloc, AllocErr, Layout, Void}; use System; // No need for synchronization here as wasm is currently single-threaded static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT; - fn to_result(ptr: *mut u8) -> Result<*mut u8, AllocErr> { - if !ptr.is_null() { - Ok(ptr) - } else { - Err(AllocErr) - } - } - #[unstable(feature = "allocator_api", issue = "32838")] - unsafe impl<'a> Alloc for &'a System { + unsafe impl GlobalAlloc for System { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - to_result(DLMALLOC.malloc(layout.size(), layout.align())) + unsafe fn alloc(&self, layout: Layout) -> *mut Void { + DLMALLOC.malloc(layout.size(), layout.align()) as *mut Void } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - to_result(DLMALLOC.calloc(layout.size(), layout.align())) + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { + DLMALLOC.calloc(layout.size(), layout.align()) as *mut Void } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - DLMALLOC.free(ptr, layout.size(), layout.align()) + unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + DLMALLOC.free(ptr as *mut u8, layout.size(), layout.align()) } #[inline] - unsafe fn realloc(&mut self, - ptr: *mut u8, - old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - to_result(DLMALLOC.realloc( - ptr, old_layout.size(), old_layout.align(), new_layout.size(), - )) + unsafe fn realloc(&self, ptr: *mut Void, layout: Layout, new_size: usize) -> *mut Void { + DLMALLOC.realloc(ptr as *mut u8, layout.size(), layout.align(), new_size) as *mut Void } } + + #[unstable(feature = "allocator_api", issue = "32838")] + unsafe impl<'a> Alloc for &'a System { + alloc_methods_based_on_global_alloc!(); + } } diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index b6626ff9f26..1c764dab000 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -381,6 +381,10 @@ pub unsafe trait GlobalAlloc { ptr } + /// # 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`). unsafe fn realloc(&self, ptr: *mut Void, old_layout: Layout, new_size: usize) -> *mut Void { let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); let new_ptr = self.alloc(new_layout); -- cgit 1.4.1-3-g733a5 From 157ff8cd0562eefdd7aa296395c38a7bc259a4b9 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 3 Apr 2018 16:00:04 +0200 Subject: Remove the now-unit-struct AllocErr parameter of oom() --- src/liballoc/alloc.rs | 6 +++--- src/liballoc/arc.rs | 2 +- src/liballoc/heap.rs | 4 ++-- src/liballoc/raw_vec.rs | 12 ++++++------ src/liballoc/rc.rs | 2 +- src/liballoc_system/lib.rs | 12 ++++++------ src/libcore/alloc.rs | 2 +- src/libstd/collections/hash/map.rs | 2 +- src/libstd/collections/hash/table.rs | 4 ++-- src/test/run-pass/allocator-alloc-one.rs | 4 ++-- src/test/run-pass/realloc-16687.rs | 4 ++-- src/test/run-pass/regions-mock-trans.rs | 2 +- 12 files changed, 28 insertions(+), 28 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 73bc78eb8a2..a7b5864016c 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -136,8 +136,8 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { align as *mut u8 } else { let layout = Layout::from_size_align_unchecked(size, align); - Global.alloc(layout).unwrap_or_else(|err| { - Global.oom(err) + Global.alloc(layout).unwrap_or_else(|_| { + Global.oom() }) } } @@ -166,7 +166,7 @@ mod tests { unsafe { let layout = Layout::from_size_align(1024, 1).unwrap(); let ptr = Global.alloc_zeroed(layout.clone()) - .unwrap_or_else(|e| Global.oom(e)); + .unwrap_or_else(|_| Global.oom()); let end = ptr.offset(layout.size() as isize); let mut i = ptr; diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index d63ed24aa4f..f0a325530ba 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -555,7 +555,7 @@ impl Arc { let layout = Layout::for_value(&*fake_ptr); let mem = Global.alloc(layout) - .unwrap_or_else(|e| Global.oom(e)); + .unwrap_or_else(|_| Global.oom()); // Initialize the real ArcInner let inner = set_data_ptr(ptr as *mut T, mem) as *mut ArcInner; diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index a44ff04bd1b..765fb8458d1 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -52,8 +52,8 @@ unsafe impl Alloc for T where T: CoreAlloc { CoreAlloc::dealloc(self, ptr, layout) } - fn oom(&mut self, err: AllocErr) -> ! { - CoreAlloc::oom(self, err) + fn oom(&mut self, _: AllocErr) -> ! { + CoreAlloc::oom(self) } fn usable_size(&self, layout: &Layout) -> (usize, usize) { diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index caedb971ddc..25d759764a5 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -100,7 +100,7 @@ impl RawVec { }; match result { Ok(ptr) => ptr, - Err(err) => a.oom(err), + Err(_) => a.oom(), } }; @@ -316,7 +316,7 @@ impl RawVec { new_layout); match ptr_res { Ok(ptr) => (new_cap, Unique::new_unchecked(ptr as *mut T)), - Err(e) => self.a.oom(e), + Err(_) => self.a.oom(), } } None => { @@ -325,7 +325,7 @@ impl RawVec { let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 }; match self.a.alloc_array::(new_cap) { Ok(ptr) => (new_cap, ptr.into()), - Err(e) => self.a.oom(e), + Err(_) => self.a.oom(), } } }; @@ -444,7 +444,7 @@ impl RawVec { pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) { match self.try_reserve_exact(used_cap, needed_extra_cap) { Err(CapacityOverflow) => panic!("capacity overflow"), - Err(AllocErr(e)) => self.a.oom(e), + Err(AllocErr(_)) => self.a.oom(), Ok(()) => { /* yay */ } } } @@ -554,7 +554,7 @@ impl RawVec { pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) { match self.try_reserve(used_cap, needed_extra_cap) { Err(CapacityOverflow) => panic!("capacity overflow"), - Err(AllocErr(e)) => self.a.oom(e), + Err(AllocErr(_)) => self.a.oom(), Ok(()) => { /* yay */ } } } @@ -669,7 +669,7 @@ impl RawVec { old_layout, new_layout) { Ok(p) => self.ptr = Unique::new_unchecked(p as *mut T), - Err(err) => self.a.oom(err), + Err(_) => self.a.oom(), } } self.cap = amount; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index c134b181158..3c0b11bfe74 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -668,7 +668,7 @@ impl Rc { let layout = Layout::for_value(&*fake_ptr); let mem = Global.alloc(layout) - .unwrap_or_else(|e| Global.oom(e)); + .unwrap_or_else(|_| Global.oom()); // Initialize the real RcBox let inner = set_data_ptr(ptr as *mut T, mem) as *mut RcBox; diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 0480be8d913..5e6b3b5ca11 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -73,8 +73,8 @@ unsafe impl Alloc for System { Alloc::realloc(&mut &*self, ptr, old_layout, new_layout) } - fn oom(&mut self, err: AllocErr) -> ! { - Alloc::oom(&mut &*self, err) + fn oom(&mut self) -> ! { + Alloc::oom(&mut &*self) } #[inline] @@ -242,7 +242,7 @@ mod platform { unsafe impl<'a> Alloc for &'a System { alloc_methods_based_on_global_alloc!(); - fn oom(&mut self, err: AllocErr) -> ! { + fn oom(&mut self) -> ! { use core::fmt::{self, Write}; // Print a message to stderr before aborting to assist with @@ -250,7 +250,7 @@ mod platform { // memory since we are in an OOM situation. Any errors are ignored // while printing since there's nothing we can do about them and we // are about to exit anyways. - drop(writeln!(Stderr, "fatal runtime error: {}", err)); + drop(writeln!(Stderr, "fatal runtime error: {}", AllocErr)); unsafe { ::core::intrinsics::abort(); } @@ -459,11 +459,11 @@ mod platform { } } - fn oom(&mut self, err: AllocErr) -> ! { + fn oom(&mut self) -> ! { use core::fmt::{self, Write}; // Same as with unix we ignore all errors here - drop(writeln!(Stderr, "fatal runtime error: {}", err)); + drop(writeln!(Stderr, "fatal runtime error: {}", AllocErr)); unsafe { ::core::intrinsics::abort(); } diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 1c764dab000..1ba4c641065 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -572,7 +572,7 @@ pub unsafe trait Alloc { /// instead they should return an appropriate error from the /// invoked method, and let the client decide whether to invoke /// this `oom` method in response. - fn oom(&mut self, _: AllocErr) -> ! { + fn oom(&mut self) -> ! { unsafe { ::intrinsics::abort() } } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index c4ef9e62577..2a00241afc6 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -784,7 +784,7 @@ impl HashMap pub fn reserve(&mut self, additional: usize) { match self.try_reserve(additional) { Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), - Err(CollectionAllocErr::AllocErr(e)) => Global.oom(e), + Err(CollectionAllocErr::AllocErr(_)) => Global.oom(), Ok(()) => { /* yay */ } } } diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 10bab5df8b5..fcc2eb8fef2 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -772,7 +772,7 @@ impl RawTable { unsafe fn new_uninitialized(capacity: usize) -> RawTable { match Self::try_new_uninitialized(capacity) { Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), - Err(CollectionAllocErr::AllocErr(e)) => Global.oom(e), + Err(CollectionAllocErr::AllocErr(_)) => Global.oom(), Ok(table) => { table } } } @@ -811,7 +811,7 @@ impl RawTable { pub fn new(capacity: usize) -> RawTable { match Self::try_new(capacity) { Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), - Err(CollectionAllocErr::AllocErr(e)) => Global.oom(e), + Err(CollectionAllocErr::AllocErr(_)) => Global.oom(), Ok(table) => { table } } } diff --git a/src/test/run-pass/allocator-alloc-one.rs b/src/test/run-pass/allocator-alloc-one.rs index eaa5bc90805..38b8ab50cc7 100644 --- a/src/test/run-pass/allocator-alloc-one.rs +++ b/src/test/run-pass/allocator-alloc-one.rs @@ -14,8 +14,8 @@ use std::heap::{Heap, Alloc}; fn main() { unsafe { - let ptr = Heap.alloc_one::().unwrap_or_else(|e| { - Heap.oom(e) + let ptr = Heap.alloc_one::().unwrap_or_else(|_| { + Heap.oom() }); *ptr.as_ptr() = 4; assert_eq!(*ptr.as_ptr(), 4); diff --git a/src/test/run-pass/realloc-16687.rs b/src/test/run-pass/realloc-16687.rs index eddcd5a584a..a562165d21b 100644 --- a/src/test/run-pass/realloc-16687.rs +++ b/src/test/run-pass/realloc-16687.rs @@ -50,7 +50,7 @@ unsafe fn test_triangle() -> bool { println!("allocate({:?})", layout); } - let ret = Heap.alloc(layout.clone()).unwrap_or_else(|e| Heap.oom(e)); + let ret = Heap.alloc(layout.clone()).unwrap_or_else(|_| Heap.oom()); if PRINT { println!("allocate({:?}) = {:?}", layout, ret); @@ -73,7 +73,7 @@ unsafe fn test_triangle() -> bool { } let ret = Heap.realloc(ptr, old.clone(), new.clone()) - .unwrap_or_else(|e| Heap.oom(e)); + .unwrap_or_else(|_| Heap.oom()); if PRINT { println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", diff --git a/src/test/run-pass/regions-mock-trans.rs b/src/test/run-pass/regions-mock-trans.rs index 8f278a315d1..7d34b8fd00f 100644 --- a/src/test/run-pass/regions-mock-trans.rs +++ b/src/test/run-pass/regions-mock-trans.rs @@ -32,7 +32,7 @@ struct Ccx { fn alloc<'a>(_bcx : &'a arena) -> &'a Bcx<'a> { unsafe { let ptr = Heap.alloc(Layout::new::()) - .unwrap_or_else(|e| Heap.oom(e)); + .unwrap_or_else(|_| Heap.oom()); &*(ptr as *const _) } } -- cgit 1.4.1-3-g733a5 From f9c96d70bd1471f662aa2ffdfe30ab6df69629d1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 12:10:34 +0200 Subject: Add FIXME comments for Void::null_mut usage --- src/liballoc_system/lib.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/liballoc_system') diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 5e6b3b5ca11..48a6c1e150a 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -309,6 +309,7 @@ mod platform { let mut out = ptr::null_mut(); let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); if ret != 0 { + // FIXME: use Void::null_mut https://github.com/rust-lang/rust/issues/49659 0 as *mut Void } else { out as *mut Void -- cgit 1.4.1-3-g733a5 From c957e99b305ecee113442a7ce0edd6b565200ca9 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 17:19:16 +0200 Subject: realloc with a new size only, not a full new layout. Changing the alignment with realloc is not supported. --- src/liballoc/alloc.rs | 22 +++++------- src/liballoc/heap.rs | 8 ++--- src/liballoc/raw_vec.rs | 17 +++++---- src/liballoc_system/lib.rs | 42 +++++++++------------- src/libcore/alloc.rs | 87 +++++++++++++++++++--------------------------- 5 files changed, 74 insertions(+), 102 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index a7b5864016c..a6fc8d5004c 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -91,21 +91,17 @@ unsafe impl Alloc for Global { unsafe fn realloc(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) + new_size: usize) -> Result<*mut u8, AllocErr> { - if layout.align() == new_layout.align() { - #[cfg(not(stage0))] - let ptr = __rust_realloc(ptr, layout.size(), layout.align(), new_layout.size()); - #[cfg(stage0)] - let ptr = __rust_realloc(ptr, layout.size(), layout.align(), - new_layout.size(), new_layout.align(), &mut 0); - - if !ptr.is_null() { - Ok(ptr) - } else { - Err(AllocErr) - } + #[cfg(not(stage0))] + let ptr = __rust_realloc(ptr, layout.size(), layout.align(), new_size); + #[cfg(stage0)] + let ptr = __rust_realloc(ptr, layout.size(), layout.align(), + new_size, layout.align(), &mut 0); + + if !ptr.is_null() { + Ok(ptr) } else { Err(AllocErr) } diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 765fb8458d1..e79383331e1 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -64,7 +64,7 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<*mut u8, AllocErr> { - CoreAlloc::realloc(self, ptr, layout, new_layout) + CoreAlloc::realloc(self, ptr, layout, new_layout.size()) } unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { @@ -79,20 +79,20 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result { - CoreAlloc::realloc_excess(self, ptr, layout, new_layout) + CoreAlloc::realloc_excess(self, ptr, layout, new_layout.size()) } unsafe fn grow_in_place(&mut self, ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { - CoreAlloc::grow_in_place(self, ptr, layout, new_layout) + CoreAlloc::grow_in_place(self, ptr, layout, new_layout.size()) } unsafe fn shrink_in_place(&mut self, ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { - CoreAlloc::shrink_in_place(self, ptr, layout, new_layout) + CoreAlloc::shrink_in_place(self, ptr, layout, new_layout.size()) } } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 18aaf1de08e..80b816878fb 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -309,11 +309,10 @@ impl RawVec { // `from_size_align_unchecked`. let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; - let new_layout = Layout::from_size_align_unchecked(new_size, cur.align()); alloc_guard(new_size).expect("capacity overflow"); let ptr_res = self.a.realloc(self.ptr.as_ptr() as *mut u8, cur, - new_layout); + new_size); match ptr_res { Ok(ptr) => (new_cap, Unique::new_unchecked(ptr as *mut T)), Err(_) => self.a.oom(), @@ -371,8 +370,7 @@ impl RawVec { let new_size = new_cap * elem_size; alloc_guard(new_size).expect("capacity overflow"); let ptr = self.ptr() as *mut _; - let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); - match self.a.grow_in_place(ptr, old_layout, new_layout) { + match self.a.grow_in_place(ptr, old_layout, new_size) { Ok(_) => { // We can't directly divide `size`. self.cap = new_cap; @@ -428,8 +426,9 @@ impl RawVec { let res = match self.current_layout() { Some(layout) => { + debug_assert!(new_layout.align() == layout.align()); let old_ptr = self.ptr.as_ptr() as *mut u8; - self.a.realloc(old_ptr, layout, new_layout) + self.a.realloc(old_ptr, layout, new_layout.size()) } None => self.a.alloc(new_layout), }; @@ -537,8 +536,9 @@ impl RawVec { let res = match self.current_layout() { Some(layout) => { + debug_assert!(new_layout.align() == layout.align()); let old_ptr = self.ptr.as_ptr() as *mut u8; - self.a.realloc(old_ptr, layout, new_layout) + self.a.realloc(old_ptr, layout, new_layout.size()) } None => self.a.alloc(new_layout), }; @@ -604,7 +604,7 @@ impl RawVec { let new_layout = Layout::new::().repeat(new_cap).unwrap().0; // FIXME: may crash and burn on over-reserve alloc_guard(new_layout.size()).expect("capacity overflow"); - match self.a.grow_in_place(ptr, old_layout, new_layout) { + match self.a.grow_in_place(ptr, old_layout, new_layout.size()) { Ok(_) => { self.cap = new_cap; true @@ -664,10 +664,9 @@ impl RawVec { let new_size = elem_size * amount; let align = mem::align_of::(); let old_layout = Layout::from_size_align_unchecked(old_size, align); - let new_layout = Layout::from_size_align_unchecked(new_size, align); match self.a.realloc(self.ptr.as_ptr() as *mut u8, old_layout, - new_layout) { + new_size) { Ok(p) => self.ptr = Unique::new_unchecked(p as *mut T), Err(_) => self.a.oom(), } diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 48a6c1e150a..7b788a5f989 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -69,8 +69,8 @@ unsafe impl Alloc for System { unsafe fn realloc(&mut self, ptr: *mut u8, old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - Alloc::realloc(&mut &*self, ptr, old_layout, new_layout) + new_size: usize) -> Result<*mut u8, AllocErr> { + Alloc::realloc(&mut &*self, ptr, old_layout, new_size) } fn oom(&mut self) -> ! { @@ -91,24 +91,24 @@ unsafe impl Alloc for System { unsafe fn realloc_excess(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result { - Alloc::realloc_excess(&mut &*self, ptr, layout, new_layout) + new_size: usize) -> Result { + Alloc::realloc_excess(&mut &*self, ptr, layout, new_size) } #[inline] unsafe fn grow_in_place(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - Alloc::grow_in_place(&mut &*self, ptr, layout, new_layout) + new_size: usize) -> Result<(), CannotReallocInPlace> { + Alloc::grow_in_place(&mut &*self, ptr, layout, new_size) } #[inline] unsafe fn shrink_in_place(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - Alloc::shrink_in_place(&mut &*self, ptr, layout, new_layout) + new_size: usize) -> Result<(), CannotReallocInPlace> { + Alloc::shrink_in_place(&mut &*self, ptr, layout, new_size) } } @@ -166,12 +166,8 @@ macro_rules! alloc_methods_based_on_global_alloc { unsafe fn realloc(&mut self, ptr: *mut u8, old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - if old_layout.align() != new_layout.align() { - return Err(AllocErr) - } - - let ptr = GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_layout.size()); + new_size: usize) -> Result<*mut u8, AllocErr> { + let ptr = GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_size); if !ptr.is_null() { Ok(ptr as *mut u8) } else { @@ -428,30 +424,26 @@ mod platform { unsafe fn grow_in_place(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - self.shrink_in_place(ptr, layout, new_layout) + new_size: usize) -> Result<(), CannotReallocInPlace> { + self.shrink_in_place(ptr, layout, new_size) } #[inline] unsafe fn shrink_in_place(&mut self, ptr: *mut u8, - old_layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - if old_layout.align() != new_layout.align() { - return Err(CannotReallocInPlace) - } - - let new = if new_layout.align() <= MIN_ALIGN { + layout: Layout, + new_size: usize) -> Result<(), CannotReallocInPlace> { + let new = if layout.align() <= MIN_ALIGN { HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, ptr as LPVOID, - new_layout.size()) + new_size) } else { let header = get_header(ptr); HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, header.0 as LPVOID, - new_layout.size() + new_layout.align()) + new_size + layout.align()) }; if new.is_null() { Err(CannotReallocInPlace) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 0acaf54e0d9..757f06e731f 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -633,9 +633,10 @@ pub unsafe trait Alloc { // realloc. alloc_excess, realloc_excess /// Returns a pointer suitable for holding data described by - /// `new_layout`, meeting its size and alignment guarantees. To + /// a new layout with `layout`’s alginment and a size given + /// by `new_size`. To /// accomplish this, this may extend or shrink the allocation - /// referenced by `ptr` to fit `new_layout`. + /// referenced by `ptr` to fit the new layout. /// /// If this returns `Ok`, then ownership of the memory block /// referenced by `ptr` has been transferred to this @@ -648,12 +649,6 @@ pub unsafe trait Alloc { /// block has not been transferred to this allocator, and the /// contents of the memory block are unaltered. /// - /// For best results, `new_layout` should not impose a different - /// alignment constraint than `layout`. (In other words, - /// `new_layout.align()` should equal `layout.align()`.) However, - /// behavior is well-defined (though underspecified) when this - /// constraint is violated; further discussion below. - /// /// # Safety /// /// This function is unsafe because undefined behavior can result @@ -661,12 +656,13 @@ pub unsafe trait Alloc { /// /// * `ptr` must be currently allocated via this allocator, /// - /// * `layout` must *fit* the `ptr` (see above). (The `new_layout` + /// * `layout` must *fit* the `ptr` (see above). (The `new_size` /// argument need not fit it.) /// - /// * `new_layout` must have size greater than zero. + /// * `new_size` must be greater than zero. /// - /// * the alignment of `new_layout` is non-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 @@ -674,18 +670,11 @@ pub unsafe trait Alloc { /// /// # Errors /// - /// Returns `Err` only if `new_layout` does not match the - /// alignment of `layout`, or does not meet the allocator's size + /// Returns `Err` only if the new layout + /// does not meet the allocator's size /// and alignment constraints of the allocator, or if reallocation /// otherwise fails. /// - /// (Note the previous sentence did not say "if and only if" -- in - /// particular, an implementation of this method *can* return `Ok` - /// if `new_layout.align() != old_layout.align()`; or it can - /// return `Err` in that scenario, depending on whether this - /// allocator can dynamically adjust the alignment constraint for - /// the block.) - /// /// Implementations are encouraged to return `Err` on memory /// exhaustion rather than panicking or aborting, but this is not /// a strict requirement. (Specifically: it is *legal* to @@ -698,22 +687,21 @@ pub unsafe trait Alloc { unsafe fn realloc(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - let new_size = new_layout.size(); + new_size: usize) -> Result<*mut u8, AllocErr> { let old_size = layout.size(); - let aligns_match = layout.align == new_layout.align; - if new_size >= old_size && aligns_match { - if let Ok(()) = self.grow_in_place(ptr, layout.clone(), new_layout.clone()) { + if new_size >= old_size { + if let Ok(()) = self.grow_in_place(ptr, layout.clone(), new_size) { return Ok(ptr); } - } else if new_size < old_size && aligns_match { - if let Ok(()) = self.shrink_in_place(ptr, layout.clone(), new_layout.clone()) { + } else if new_size < old_size { + if let Ok(()) = self.shrink_in_place(ptr, layout.clone(), new_size) { return Ok(ptr); } } // otherwise, fall back on alloc + copy + dealloc. + let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); let result = self.alloc(new_layout); if let Ok(new_ptr) = result { ptr::copy_nonoverlapping(ptr as *const u8, new_ptr, cmp::min(old_size, new_size)); @@ -789,17 +777,19 @@ pub unsafe trait Alloc { unsafe fn realloc_excess(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result { + new_size: usize) -> Result { + let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); let usable_size = self.usable_size(&new_layout); - self.realloc(ptr, layout, new_layout) + self.realloc(ptr, layout, new_size) .map(|p| Excess(p, usable_size.1)) } - /// Attempts to extend the allocation referenced by `ptr` to fit `new_layout`. + /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`. /// /// If this returns `Ok`, then the allocator has asserted that the - /// memory block referenced by `ptr` now fits `new_layout`, and thus can - /// be used to carry data of that layout. (The allocator is allowed to + /// memory block referenced by `ptr` now fits `new_size`, and thus can + /// be used to carry data of a layout of that size and same alignment as + /// `layout`. (The allocator is allowed to /// expend effort to accomplish this, such as extending the memory block to /// include successor blocks, or virtual memory tricks.) /// @@ -815,11 +805,9 @@ pub unsafe trait Alloc { /// * `ptr` must be currently allocated via this allocator, /// /// * `layout` must *fit* the `ptr` (see above); note the - /// `new_layout` argument need not fit it, + /// `new_size` argument need not fit it, /// - /// * `new_layout.size()` must not be less than `layout.size()`, - /// - /// * `new_layout.align()` must equal `layout.align()`. + /// * `new_size` must not be less than `layout.size()`, /// /// # Errors /// @@ -834,24 +822,23 @@ pub unsafe trait Alloc { unsafe fn grow_in_place(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { + new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. - debug_assert!(new_layout.size >= layout.size); - debug_assert!(new_layout.align == layout.align); + debug_assert!(new_size >= layout.size); let (_l, u) = self.usable_size(&layout); // _l <= layout.size() [guaranteed by usable_size()] // layout.size() <= new_layout.size() [required by this method] - if new_layout.size <= u { + if new_size <= u { return Ok(()); } else { return Err(CannotReallocInPlace); } } - /// Attempts to shrink the allocation referenced by `ptr` to fit `new_layout`. + /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`. /// /// If this returns `Ok`, then the allocator has asserted that the - /// memory block referenced by `ptr` now fits `new_layout`, and + /// memory block referenced by `ptr` now fits `new_size`, and /// thus can only be used to carry data of that smaller /// layout. (The allocator is allowed to take advantage of this, /// carving off portions of the block for reuse elsewhere.) The @@ -872,13 +859,11 @@ pub unsafe trait Alloc { /// * `ptr` must be currently allocated via this allocator, /// /// * `layout` must *fit* the `ptr` (see above); note the - /// `new_layout` argument need not fit it, + /// `new_size` argument need not fit it, /// - /// * `new_layout.size()` must not be greater than `layout.size()` + /// * `new_size` must not be greater than `layout.size()` /// (and must be greater than zero), /// - /// * `new_layout.align()` must equal `layout.align()`. - /// /// # Errors /// /// Returns `Err(CannotReallocInPlace)` when the allocator is @@ -892,14 +877,13 @@ pub unsafe trait Alloc { unsafe fn shrink_in_place(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { + new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. - debug_assert!(new_layout.size <= layout.size); - debug_assert!(new_layout.align == layout.align); + debug_assert!(new_size <= layout.size); let (l, _u) = self.usable_size(&layout); // layout.size() <= _u [guaranteed by usable_size()] // new_layout.size() <= layout.size() [required by this method] - if l <= new_layout.size { + if l <= new_size { return Ok(()); } else { return Err(CannotReallocInPlace); @@ -1061,7 +1045,8 @@ pub unsafe trait Alloc { { match (Layout::array::(n_old), Layout::array::(n_new), ptr.as_ptr()) { (Ok(ref k_old), Ok(ref k_new), ptr) if k_old.size() > 0 && k_new.size() > 0 => { - self.realloc(ptr as *mut u8, k_old.clone(), k_new.clone()) + debug_assert!(k_old.align() == k_new.align()); + self.realloc(ptr as *mut u8, k_old.clone(), k_new.size()) .map(|p| NonNull::new_unchecked(p as *mut T)) } _ => { -- cgit 1.4.1-3-g733a5 From 747cc749430d66bd2fca8e81fd8a1c994e36dcf1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 18:09:39 +0200 Subject: Conversions between Result<*mut u8, AllocErr>> and *mut Void --- src/liballoc_system/lib.rs | 21 +++------------------ src/libcore/alloc.rs | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 7b788a5f989..6ffbd029281 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -139,22 +139,12 @@ macro_rules! alloc_methods_based_on_global_alloc { () => { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - let ptr = GlobalAlloc::alloc(*self, layout); - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr) - } + GlobalAlloc::alloc(*self, layout).into() } #[inline] unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - let ptr = GlobalAlloc::alloc_zeroed(*self, layout); - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr) - } + GlobalAlloc::alloc_zeroed(*self, layout).into() } #[inline] @@ -167,12 +157,7 @@ macro_rules! alloc_methods_based_on_global_alloc { ptr: *mut u8, old_layout: Layout, new_size: usize) -> Result<*mut u8, AllocErr> { - let ptr = GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_size); - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr) - } + GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_size).into() } } } diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 757f06e731f..cfa7df06a40 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -41,6 +41,27 @@ impl Void { } } +/// Convert from a return value of GlobalAlloc::alloc to that of Alloc::alloc +impl From<*mut Void> for Result<*mut u8, AllocErr> { + fn from(ptr: *mut Void) -> Self { + if !ptr.is_null() { + Ok(ptr as *mut u8) + } else { + Err(AllocErr) + } + } +} + +/// Convert from a return value of Alloc::alloc to that of GlobalAlloc::alloc +impl From> for *mut Void { + fn from(result: Result<*mut u8, AllocErr>) -> Self { + match result { + Ok(ptr) => ptr as *mut Void, + Err(_) => Void::null_mut(), + } + } +} + /// Represents the combination of a starting address and /// a total capacity of the returned block. #[derive(Debug)] -- cgit 1.4.1-3-g733a5 From c033f1ff5f29ecac41dee668e373c9fc870f2d43 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 18:43:28 +0200 Subject: Move platform-specific OOM handling to functions --- src/liballoc_system/lib.rs | 131 ++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 73 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 6ffbd029281..8cb5c5d5be9 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -224,40 +224,7 @@ mod platform { alloc_methods_based_on_global_alloc!(); fn oom(&mut self) -> ! { - use core::fmt::{self, Write}; - - // Print a message to stderr before aborting to assist with - // debugging. It is critical that this code does not allocate any - // memory since we are in an OOM situation. Any errors are ignored - // while printing since there's nothing we can do about them and we - // are about to exit anyways. - drop(writeln!(Stderr, "fatal runtime error: {}", AllocErr)); - unsafe { - ::core::intrinsics::abort(); - } - - struct Stderr; - - impl Write for Stderr { - #[cfg(target_os = "cloudabi")] - fn write_str(&mut self, _: &str) -> fmt::Result { - // CloudABI does not have any reserved file descriptor - // numbers. We should not attempt to write to file - // descriptor #2, as it may be associated with any kind of - // resource. - Ok(()) - } - - #[cfg(not(target_os = "cloudabi"))] - fn write_str(&mut self, s: &str) -> fmt::Result { - unsafe { - libc::write(libc::STDERR_FILENO, - s.as_ptr() as *const libc::c_void, - s.len()); - } - Ok(()) - } - } + ::oom() } } @@ -301,8 +268,6 @@ mod platform { #[cfg(windows)] #[allow(bad_style)] mod platform { - use core::ptr; - use MIN_ALIGN; use System; use core::alloc::{GlobalAlloc, Alloc, Void, AllocErr, Layout, CannotReallocInPlace}; @@ -312,10 +277,6 @@ mod platform { type SIZE_T = usize; type DWORD = u32; type BOOL = i32; - type LPDWORD = *mut DWORD; - type LPOVERLAPPED = *mut u8; - - const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; extern "system" { fn GetProcessHeap() -> HANDLE; @@ -323,20 +284,12 @@ mod platform { fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; fn GetLastError() -> DWORD; - fn WriteFile(hFile: HANDLE, - lpBuffer: LPVOID, - nNumberOfBytesToWrite: DWORD, - lpNumberOfBytesWritten: LPDWORD, - lpOverlapped: LPOVERLAPPED) - -> BOOL; - fn GetStdHandle(which: DWORD) -> HANDLE; } #[repr(C)] struct Header(*mut u8); const HEAP_ZERO_MEMORY: DWORD = 0x00000008; - const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010; unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { &mut *(ptr as *mut Header).offset(-1) @@ -438,31 +391,7 @@ mod platform { } fn oom(&mut self) -> ! { - use core::fmt::{self, Write}; - - // Same as with unix we ignore all errors here - drop(writeln!(Stderr, "fatal runtime error: {}", AllocErr)); - unsafe { - ::core::intrinsics::abort(); - } - - struct Stderr; - - impl Write for Stderr { - fn write_str(&mut self, s: &str) -> fmt::Result { - unsafe { - // WriteFile silently fails if it is passed an invalid - // handle, so there is no need to check the result of - // GetStdHandle. - WriteFile(GetStdHandle(STD_ERROR_HANDLE), - s.as_ptr() as LPVOID, - s.len() as DWORD, - ptr::null_mut(), - ptr::null_mut()); - } - Ok(()) - } - } + ::oom() } } } @@ -522,3 +451,59 @@ mod platform { alloc_methods_based_on_global_alloc!(); } } + +fn oom() -> ! { + write_to_stderr("fatal runtime error: memory allocation failed"); + unsafe { + ::core::intrinsics::abort(); + } +} + +#[cfg(any(unix, target_os = "redox"))] +fn write_to_stderr(s: &str) { + extern crate libc; + + unsafe { + libc::write(libc::STDERR_FILENO, + s.as_ptr() as *const libc::c_void, + s.len()); + } +} + +#[cfg(windows)] +fn write_to_stderr(s: &str) { + use core::ptr; + + type LPVOID = *mut u8; + type HANDLE = LPVOID; + type DWORD = u32; + type BOOL = i32; + type LPDWORD = *mut DWORD; + type LPOVERLAPPED = *mut u8; + + const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; + + extern "system" { + fn WriteFile(hFile: HANDLE, + lpBuffer: LPVOID, + nNumberOfBytesToWrite: DWORD, + lpNumberOfBytesWritten: LPDWORD, + lpOverlapped: LPOVERLAPPED) + -> BOOL; + fn GetStdHandle(which: DWORD) -> HANDLE; + } + + unsafe { + // WriteFile silently fails if it is passed an invalid + // handle, so there is no need to check the result of + // GetStdHandle. + WriteFile(GetStdHandle(STD_ERROR_HANDLE), + s.as_ptr() as LPVOID, + s.len() as DWORD, + ptr::null_mut(), + ptr::null_mut()); + } +} + +#[cfg(not(any(windows, unix, target_os = "redox")))] +fn write_to_stderr(_: &str) {} -- cgit 1.4.1-3-g733a5 From 96c9d225a9667bc5ffcbc1594d44c29b201e999c Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 18:50:25 +0200 Subject: Remove `impl Alloc for &'a System` This was relevant to `#[global_allocator]`, which is now based on `GlobalAlloc` trait instead. --- src/liballoc_system/lib.rs | 141 +++++++++------------------------------------ 1 file changed, 28 insertions(+), 113 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 8cb5c5d5be9..4516664e97c 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -41,7 +41,7 @@ const MIN_ALIGN: usize = 8; #[allow(dead_code)] const MIN_ALIGN: usize = 16; -use core::alloc::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace}; +use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout, Void}; #[unstable(feature = "allocator_api", issue = "32838")] pub struct System; @@ -50,19 +50,17 @@ pub struct System; unsafe impl Alloc for System { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - Alloc::alloc(&mut &*self, layout) + GlobalAlloc::alloc(self, layout).into() } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> - { - Alloc::alloc_zeroed(&mut &*self, layout) + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + GlobalAlloc::alloc_zeroed(self, layout).into() } #[inline] unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - Alloc::dealloc(&mut &*self, ptr, layout) + GlobalAlloc::dealloc(self, ptr as *mut Void, layout) } #[inline] @@ -70,45 +68,44 @@ unsafe impl Alloc for System { ptr: *mut u8, old_layout: Layout, new_size: usize) -> Result<*mut u8, AllocErr> { - Alloc::realloc(&mut &*self, ptr, old_layout, new_size) + GlobalAlloc::realloc(self, ptr as *mut Void, old_layout, new_size).into() } + #[inline] fn oom(&mut self) -> ! { - Alloc::oom(&mut &*self) + ::oom() } +} +#[cfg(stage0)] +#[unstable(feature = "allocator_api", issue = "32838")] +unsafe impl<'a> Alloc for &'a System { #[inline] - fn usable_size(&self, layout: &Layout) -> (usize, usize) { - Alloc::usable_size(&mut &*self, layout) + unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + GlobalAlloc::alloc(*self, layout).into() } #[inline] - unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { - Alloc::alloc_excess(&mut &*self, layout) + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + GlobalAlloc::alloc_zeroed(*self, layout).into() } #[inline] - unsafe fn realloc_excess(&mut self, - ptr: *mut u8, - layout: Layout, - new_size: usize) -> Result { - Alloc::realloc_excess(&mut &*self, ptr, layout, new_size) + unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + GlobalAlloc::dealloc(*self, ptr as *mut Void, layout) } #[inline] - unsafe fn grow_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { - Alloc::grow_in_place(&mut &*self, ptr, layout, new_size) + unsafe fn realloc(&mut self, + ptr: *mut u8, + old_layout: Layout, + new_size: usize) -> Result<*mut u8, AllocErr> { + GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_size).into() } #[inline] - unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { - Alloc::shrink_in_place(&mut &*self, ptr, layout, new_size) + fn oom(&mut self) -> ! { + ::oom() } } @@ -135,33 +132,6 @@ mod realloc_fallback { } } -macro_rules! alloc_methods_based_on_global_alloc { - () => { - #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - GlobalAlloc::alloc(*self, layout).into() - } - - #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - GlobalAlloc::alloc_zeroed(*self, layout).into() - } - - #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - GlobalAlloc::dealloc(*self, ptr as *mut Void, layout) - } - - #[inline] - unsafe fn realloc(&mut self, - ptr: *mut u8, - old_layout: Layout, - new_size: usize) -> Result<*mut u8, AllocErr> { - GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_size).into() - } - } -} - #[cfg(any(unix, target_os = "cloudabi", target_os = "redox"))] mod platform { extern crate libc; @@ -170,7 +140,7 @@ mod platform { use MIN_ALIGN; use System; - use core::alloc::{GlobalAlloc, Alloc, AllocErr, Layout, Void}; + use core::alloc::{GlobalAlloc, Layout, Void}; #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl GlobalAlloc for System { @@ -219,15 +189,6 @@ mod platform { } } - #[unstable(feature = "allocator_api", issue = "32838")] - unsafe impl<'a> Alloc for &'a System { - alloc_methods_based_on_global_alloc!(); - - fn oom(&mut self) -> ! { - ::oom() - } - } - #[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut Void { @@ -270,7 +231,7 @@ mod platform { mod platform { use MIN_ALIGN; use System; - use core::alloc::{GlobalAlloc, Alloc, Void, AllocErr, Layout, CannotReallocInPlace}; + use core::alloc::{GlobalAlloc, Void, Layout}; type LPVOID = *mut u8; type HANDLE = LPVOID; @@ -353,47 +314,6 @@ mod platform { } } } - - #[unstable(feature = "allocator_api", issue = "32838")] - unsafe impl<'a> Alloc for &'a System { - alloc_methods_based_on_global_alloc!(); - - #[inline] - unsafe fn grow_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { - self.shrink_in_place(ptr, layout, new_size) - } - - #[inline] - unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { - let new = if layout.align() <= MIN_ALIGN { - HeapReAlloc(GetProcessHeap(), - HEAP_REALLOC_IN_PLACE_ONLY, - ptr as LPVOID, - new_size) - } else { - let header = get_header(ptr); - HeapReAlloc(GetProcessHeap(), - HEAP_REALLOC_IN_PLACE_ONLY, - header.0 as LPVOID, - new_size + layout.align()) - }; - if new.is_null() { - Err(CannotReallocInPlace) - } else { - Ok(()) - } - } - - fn oom(&mut self) -> ! { - ::oom() - } - } } // This is an implementation of a global allocator on the wasm32 platform when @@ -417,7 +337,7 @@ mod platform { mod platform { extern crate dlmalloc; - use core::alloc::{GlobalAlloc, Alloc, AllocErr, Layout, Void}; + use core::alloc::{GlobalAlloc, Layout, Void}; use System; // No need for synchronization here as wasm is currently single-threaded @@ -445,11 +365,6 @@ mod platform { DLMALLOC.realloc(ptr as *mut u8, layout.size(), layout.align(), new_size) as *mut Void } } - - #[unstable(feature = "allocator_api", issue = "32838")] - unsafe impl<'a> Alloc for &'a System { - alloc_methods_based_on_global_alloc!(); - } } fn oom() -> ! { -- cgit 1.4.1-3-g733a5 From eae0d468932660ca383e35bb9d8b0cb4943a82ae Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 18:57:48 +0200 Subject: Restore Global.oom() functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … now that #[global_allocator] does not define a symbol for it --- src/Cargo.lock | 1 + src/liballoc/alloc.rs | 16 ++++++++++++++++ src/liballoc/lib.rs | 1 + src/liballoc_jemalloc/Cargo.toml | 1 + src/liballoc_jemalloc/lib.rs | 10 ++++++++++ src/liballoc_system/lib.rs | 4 ++++ src/libcore/alloc.rs | 4 ++++ src/librustc_allocator/expand.rs | 5 +++++ src/librustc_allocator/lib.rs | 6 ++++++ src/librustc_trans/allocator.rs | 2 ++ src/libstd/alloc.rs | 6 ++++++ src/test/compile-fail/allocator/not-an-allocator.rs | 1 + 12 files changed, 57 insertions(+) (limited to 'src/liballoc_system') diff --git a/src/Cargo.lock b/src/Cargo.lock index 2e969f4ec2b..e5297d1482e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -19,6 +19,7 @@ dependencies = [ name = "alloc_jemalloc" version = "0.0.0" dependencies = [ + "alloc_system 0.0.0", "build_helper 0.1.0", "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.0.0", diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index a6fc8d5004c..beae52726a6 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -26,6 +26,9 @@ extern "Rust" { #[allocator] #[rustc_allocator_nounwind] fn __rust_alloc(size: usize, align: usize, err: *mut u8) -> *mut u8; + #[cold] + #[rustc_allocator_nounwind] + fn __rust_oom(err: *const u8) -> !; #[rustc_allocator_nounwind] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); #[rustc_allocator_nounwind] @@ -44,6 +47,9 @@ extern "Rust" { #[allocator] #[rustc_allocator_nounwind] fn __rust_alloc(size: usize, align: usize) -> *mut u8; + #[cold] + #[rustc_allocator_nounwind] + fn __rust_oom() -> !; #[rustc_allocator_nounwind] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); #[rustc_allocator_nounwind] @@ -120,6 +126,16 @@ unsafe impl Alloc for Global { Err(AllocErr) } } + + #[inline] + fn oom(&mut self) -> ! { + unsafe { + #[cfg(not(stage0))] + __rust_oom(); + #[cfg(stage0)] + __rust_oom(&mut 0); + } + } } /// The allocator for unique pointers. diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index f6598fe5e89..a10820ebefd 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -97,6 +97,7 @@ #![feature(from_ref)] #![feature(fundamental)] #![feature(lang_items)] +#![feature(libc)] #![feature(needs_allocator)] #![feature(nonzero)] #![feature(optin_builtin_traits)] diff --git a/src/liballoc_jemalloc/Cargo.toml b/src/liballoc_jemalloc/Cargo.toml index 7986d5dd2eb..02435170374 100644 --- a/src/liballoc_jemalloc/Cargo.toml +++ b/src/liballoc_jemalloc/Cargo.toml @@ -12,6 +12,7 @@ test = false doc = false [dependencies] +alloc_system = { path = "../liballoc_system" } core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 661d7ab78da..2b66c293f21 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -14,6 +14,7 @@ reason = "this library is unlikely to be stabilized in its current \ form or name", issue = "27783")] +#![feature(alloc_system)] #![feature(libc)] #![feature(linkage)] #![feature(staged_api)] @@ -22,12 +23,15 @@ #![cfg_attr(not(dummy_jemalloc), feature(allocator_api))] #![rustc_alloc_kind = "exe"] +extern crate alloc_system; extern crate libc; #[cfg(not(dummy_jemalloc))] pub use contents::*; #[cfg(not(dummy_jemalloc))] mod contents { + use core::alloc::GlobalAlloc; + use alloc_system::System; use libc::{c_int, c_void, size_t}; // Note that the symbols here are prefixed by default on macOS and Windows (we @@ -96,6 +100,12 @@ mod contents { ptr } + #[no_mangle] + #[rustc_std_internal_symbol] + pub unsafe extern fn __rde_oom() -> ! { + System.oom() + } + #[no_mangle] #[rustc_std_internal_symbol] pub unsafe extern fn __rde_dealloc(ptr: *mut u8, diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 4516664e97c..c6507282b24 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -367,6 +367,7 @@ mod platform { } } +#[inline] fn oom() -> ! { write_to_stderr("fatal runtime error: memory allocation failed"); unsafe { @@ -375,6 +376,7 @@ fn oom() -> ! { } #[cfg(any(unix, target_os = "redox"))] +#[inline] fn write_to_stderr(s: &str) { extern crate libc; @@ -386,6 +388,7 @@ fn write_to_stderr(s: &str) { } #[cfg(windows)] +#[inline] fn write_to_stderr(s: &str) { use core::ptr; @@ -421,4 +424,5 @@ fn write_to_stderr(s: &str) { } #[cfg(not(any(windows, unix, target_os = "redox")))] +#[inline] fn write_to_stderr(_: &str) {} diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index cfa7df06a40..7334f986f2b 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -438,6 +438,10 @@ pub unsafe trait GlobalAlloc { } new_ptr } + + fn oom(&self) -> ! { + unsafe { ::intrinsics::abort() } + } } /// An implementation of `Alloc` can allocate, reallocate, and diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index ce41fe1f3bc..58d4c7f289c 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -231,6 +231,7 @@ impl<'a> AllocFnFactory<'a> { } AllocatorTy::ResultPtr | + AllocatorTy::Bang | AllocatorTy::Unit => { panic!("can't convert AllocatorTy to an argument") } @@ -248,6 +249,10 @@ impl<'a> AllocFnFactory<'a> { (self.ptr_u8(), expr) } + AllocatorTy::Bang => { + (self.cx.ty(self.span, TyKind::Never), expr) + } + AllocatorTy::Unit => { (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr) } diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs index 969086815de..706eab72d44 100644 --- a/src/librustc_allocator/lib.rs +++ b/src/librustc_allocator/lib.rs @@ -23,6 +23,11 @@ pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ inputs: &[AllocatorTy::Layout], output: AllocatorTy::ResultPtr, }, + AllocatorMethod { + name: "oom", + inputs: &[], + output: AllocatorTy::Bang, + }, AllocatorMethod { name: "dealloc", inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout], @@ -47,6 +52,7 @@ pub struct AllocatorMethod { } pub enum AllocatorTy { + Bang, Layout, Ptr, ResultPtr, diff --git a/src/librustc_trans/allocator.rs b/src/librustc_trans/allocator.rs index ffebb959ebf..f2dd2ed8460 100644 --- a/src/librustc_trans/allocator.rs +++ b/src/librustc_trans/allocator.rs @@ -43,11 +43,13 @@ pub(crate) unsafe fn trans(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) AllocatorTy::Ptr => args.push(i8p), AllocatorTy::Usize => args.push(usize), + AllocatorTy::Bang | AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), } } let output = match method.output { + AllocatorTy::Bang => None, AllocatorTy::ResultPtr => Some(i8p), AllocatorTy::Unit => None, diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 335dc7e0412..4e728df010a 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -35,6 +35,12 @@ pub mod __default_lib_allocator { System.alloc(layout) as *mut u8 } + #[no_mangle] + #[rustc_std_internal_symbol] + pub unsafe extern fn __rdl_oom() -> ! { + System.oom() + } + #[no_mangle] #[rustc_std_internal_symbol] pub unsafe extern fn __rdl_dealloc(ptr: *mut u8, diff --git a/src/test/compile-fail/allocator/not-an-allocator.rs b/src/test/compile-fail/allocator/not-an-allocator.rs index 140cad22f34..1479d0b6264 100644 --- a/src/test/compile-fail/allocator/not-an-allocator.rs +++ b/src/test/compile-fail/allocator/not-an-allocator.rs @@ -16,5 +16,6 @@ static A: usize = 0; //~| the trait bound `usize: //~| the trait bound `usize: //~| the trait bound `usize: +//~| the trait bound `usize: fn main() {} -- cgit 1.4.1-3-g733a5 From fddf51ee0b9765484fc316dbf3d4feb8ceea715d Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 3 Apr 2018 08:51:02 +0900 Subject: Use NonNull instead of *mut u8 in the Alloc trait Fixes #49608 --- src/doc/nomicon | 2 +- .../src/language-features/global-allocator.md | 1 + src/liballoc/alloc.rs | 19 +++---- src/liballoc/arc.rs | 16 +++--- src/liballoc/btree/node.rs | 16 +++--- src/liballoc/heap.rs | 22 ++++++-- src/liballoc/lib.rs | 1 + src/liballoc/raw_vec.rs | 40 +++++++-------- src/liballoc/rc.rs | 18 +++---- src/liballoc/tests/heap.rs | 3 +- src/liballoc_system/lib.rs | 29 +++++------ src/libcore/alloc.rs | 58 ++++++++++------------ src/libcore/ptr.rs | 8 +++ src/libstd/collections/hash/table.rs | 6 +-- src/libstd/lib.rs | 1 + src/test/run-pass/allocator/xcrate-use2.rs | 2 +- src/test/run-pass/realloc-16687.rs | 18 +++---- src/test/run-pass/regions-mock-trans.rs | 5 +- 18 files changed, 136 insertions(+), 129 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/doc/nomicon b/src/doc/nomicon index 6a8f0a27e9a..498ac299742 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 6a8f0a27e9a58c55c89d07bc43a176fdae5e051c +Subproject commit 498ac2997420f7b25f7cd0a3f8202950d8ad93ec diff --git a/src/doc/unstable-book/src/language-features/global-allocator.md b/src/doc/unstable-book/src/language-features/global-allocator.md index 6ce12ba684d..a3f3ee65bf0 100644 --- a/src/doc/unstable-book/src/language-features/global-allocator.md +++ b/src/doc/unstable-book/src/language-features/global-allocator.md @@ -30,6 +30,7 @@ looks like: #![feature(global_allocator, allocator_api, heap_api)] use std::alloc::{GlobalAlloc, System, Layout, Void}; +use std::ptr::NonNull; struct MyAllocator; diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 063f0543ec4..af48aa7961e 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -16,6 +16,7 @@ issue = "32838")] use core::intrinsics::{min_align_of_val, size_of_val}; +use core::ptr::NonNull; use core::usize; #[doc(inline)] @@ -120,27 +121,27 @@ unsafe impl GlobalAlloc for Global { unsafe impl Alloc for Global { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { GlobalAlloc::alloc(self, layout).into() } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - GlobalAlloc::dealloc(self, ptr as *mut Void, layout) + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) } #[inline] unsafe fn realloc(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_size: usize) - -> Result<*mut u8, AllocErr> + -> Result, AllocErr> { - GlobalAlloc::realloc(self, ptr as *mut Void, layout, new_size).into() + GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size).into() } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { GlobalAlloc::alloc_zeroed(self, layout).into() } @@ -195,8 +196,8 @@ mod tests { let ptr = Global.alloc_zeroed(layout.clone()) .unwrap_or_else(|_| Global.oom()); - let end = ptr.offset(layout.size() as isize); - let mut i = ptr; + let mut i = ptr.cast::().as_ptr(); + let end = i.offset(layout.size() as isize); while i < end { assert_eq!(*i, 0); i = i.offset(1); diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index f0a325530ba..88754ace3ce 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -512,15 +512,13 @@ impl Arc { // Non-inlined part of `drop`. #[inline(never)] unsafe fn drop_slow(&mut self) { - let ptr = self.ptr.as_ptr(); - // Destroy the data at this time, even though we may not free the box // allocation itself (there may still be weak pointers lying around). ptr::drop_in_place(&mut self.ptr.as_mut().data); if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); - Global.dealloc(ptr as *mut u8, Layout::for_value(&*ptr)) + Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())) } } @@ -558,7 +556,7 @@ impl Arc { .unwrap_or_else(|_| Global.oom()); // Initialize the real ArcInner - let inner = set_data_ptr(ptr as *mut T, mem) as *mut ArcInner; + let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner; ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1)); ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1)); @@ -625,7 +623,7 @@ impl ArcFromSlice for Arc<[T]> { // In the event of a panic, elements that have been written // into the new ArcInner will be dropped, then the memory freed. struct Guard { - mem: *mut u8, + mem: NonNull, elems: *mut T, layout: Layout, n_elems: usize, @@ -639,7 +637,7 @@ impl ArcFromSlice for Arc<[T]> { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); - Global.dealloc(self.mem, self.layout.clone()); + Global.dealloc(self.mem.as_void(), self.layout.clone()); } } } @@ -655,7 +653,7 @@ impl ArcFromSlice for Arc<[T]> { let elems = &mut (*ptr).data as *mut [T] as *mut T; let mut guard = Guard{ - mem: mem, + mem: NonNull::new_unchecked(mem), elems: elems, layout: layout, n_elems: 0, @@ -1147,8 +1145,6 @@ impl Drop for Weak { /// assert!(other_weak_foo.upgrade().is_none()); /// ``` fn drop(&mut self) { - let ptr = self.ptr.as_ptr(); - // If we find out that we were the last weak pointer, then its time to // deallocate the data entirely. See the discussion in Arc::drop() about // the memory orderings @@ -1160,7 +1156,7 @@ impl Drop for Weak { if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); unsafe { - Global.dealloc(ptr as *mut u8, Layout::for_value(&*ptr)) + Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())) } } } diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index 8e23228bd28..64aa40ac166 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -236,7 +236,7 @@ impl Root { pub fn pop_level(&mut self) { debug_assert!(self.height > 0); - let top = self.node.ptr.as_ptr() as *mut u8; + let top = self.node.ptr; self.node = unsafe { BoxedNode::from_ptr(self.as_mut() @@ -249,7 +249,7 @@ impl Root { self.as_mut().as_leaf_mut().parent = ptr::null(); unsafe { - Global.dealloc(top, Layout::new::>()); + Global.dealloc(NonNull::from(top).as_void(), Layout::new::>()); } } } @@ -433,9 +433,9 @@ impl NodeRef { marker::Edge > > { - let ptr = self.as_leaf() as *const LeafNode as *const u8 as *mut u8; + let node = self.node; let ret = self.ascend().ok(); - Global.dealloc(ptr, Layout::new::>()); + Global.dealloc(node.as_void(), Layout::new::>()); ret } } @@ -454,9 +454,9 @@ impl NodeRef { marker::Edge > > { - let ptr = self.as_internal() as *const InternalNode as *const u8 as *mut u8; + let node = self.node; let ret = self.ascend().ok(); - Global.dealloc(ptr, Layout::new::>()); + Global.dealloc(node.as_void(), Layout::new::>()); ret } } @@ -1239,12 +1239,12 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } Global.dealloc( - right_node.node.as_ptr() as *mut u8, + right_node.node.as_void(), Layout::new::>(), ); } else { Global.dealloc( - right_node.node.as_ptr() as *mut u8, + right_node.node.as_void(), Layout::new::>(), ); } diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index e79383331e1..cfb6504e743 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -8,14 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use alloc::{Excess, Layout, AllocErr, CannotReallocInPlace}; +#![allow(deprecated)] + +pub use alloc::{Layout, AllocErr, CannotReallocInPlace, Void}; use core::alloc::Alloc as CoreAlloc; +use core::ptr::NonNull; #[doc(hidden)] pub mod __core { pub use core::*; } +#[derive(Debug)] +pub struct Excess(pub *mut u8, pub usize); + /// Compatibility with older versions of #[global_allocator] during bootstrap pub unsafe trait Alloc { unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>; @@ -42,13 +48,13 @@ pub unsafe trait Alloc { new_layout: Layout) -> Result<(), CannotReallocInPlace>; } -#[allow(deprecated)] unsafe impl Alloc for T where T: CoreAlloc { unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - CoreAlloc::alloc(self, layout) + CoreAlloc::alloc(self, layout).map(|ptr| ptr.cast().as_ptr()) } unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + let ptr = NonNull::new_unchecked(ptr as *mut Void); CoreAlloc::dealloc(self, ptr, layout) } @@ -64,28 +70,33 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<*mut u8, AllocErr> { - CoreAlloc::realloc(self, ptr, layout, new_layout.size()) + let ptr = NonNull::new_unchecked(ptr as *mut Void); + CoreAlloc::realloc(self, ptr, layout, new_layout.size()).map(|ptr| ptr.cast().as_ptr()) } unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - CoreAlloc::alloc_zeroed(self, layout) + CoreAlloc::alloc_zeroed(self, layout).map(|ptr| ptr.cast().as_ptr()) } unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { CoreAlloc::alloc_excess(self, layout) + .map(|e| Excess(e.0 .cast().as_ptr(), e.1)) } unsafe fn realloc_excess(&mut self, ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result { + let ptr = NonNull::new_unchecked(ptr as *mut Void); CoreAlloc::realloc_excess(self, ptr, layout, new_layout.size()) + .map(|e| Excess(e.0 .cast().as_ptr(), e.1)) } unsafe fn grow_in_place(&mut self, ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { + let ptr = NonNull::new_unchecked(ptr as *mut Void); CoreAlloc::grow_in_place(self, ptr, layout, new_layout.size()) } @@ -93,6 +104,7 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { + let ptr = NonNull::new_unchecked(ptr as *mut Void); CoreAlloc::shrink_in_place(self, ptr, layout, new_layout.size()) } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index a10820ebefd..3a106a2ff5c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -99,6 +99,7 @@ #![feature(lang_items)] #![feature(libc)] #![feature(needs_allocator)] +#![feature(nonnull_cast)] #![feature(nonzero)] #![feature(optin_builtin_traits)] #![feature(pattern)] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 80b816878fb..d72301f5ad6 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -12,7 +12,7 @@ use alloc::{Alloc, Layout, Global}; use core::cmp; use core::mem; use core::ops::Drop; -use core::ptr::{self, Unique}; +use core::ptr::{self, NonNull, Unique}; use core::slice; use super::boxed::Box; use super::allocator::CollectionAllocErr; @@ -90,7 +90,7 @@ impl RawVec { // handles ZSTs and `cap = 0` alike let ptr = if alloc_size == 0 { - mem::align_of::() as *mut u8 + NonNull::::dangling().as_void() } else { let align = mem::align_of::(); let result = if zeroed { @@ -105,7 +105,7 @@ impl RawVec { }; RawVec { - ptr: Unique::new_unchecked(ptr as *mut _), + ptr: ptr.cast().into(), cap, a, } @@ -310,11 +310,11 @@ impl RawVec { let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; alloc_guard(new_size).expect("capacity overflow"); - let ptr_res = self.a.realloc(self.ptr.as_ptr() as *mut u8, + let ptr_res = self.a.realloc(NonNull::from(self.ptr).as_void(), cur, new_size); match ptr_res { - Ok(ptr) => (new_cap, Unique::new_unchecked(ptr as *mut T)), + Ok(ptr) => (new_cap, ptr.cast().into()), Err(_) => self.a.oom(), } } @@ -369,8 +369,7 @@ impl RawVec { let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; alloc_guard(new_size).expect("capacity overflow"); - let ptr = self.ptr() as *mut _; - match self.a.grow_in_place(ptr, old_layout, new_size) { + match self.a.grow_in_place(NonNull::from(self.ptr).as_void(), old_layout, new_size) { Ok(_) => { // We can't directly divide `size`. self.cap = new_cap; @@ -427,13 +426,12 @@ impl RawVec { let res = match self.current_layout() { Some(layout) => { debug_assert!(new_layout.align() == layout.align()); - let old_ptr = self.ptr.as_ptr() as *mut u8; - self.a.realloc(old_ptr, layout, new_layout.size()) + self.a.realloc(NonNull::from(self.ptr).as_void(), layout, new_layout.size()) } None => self.a.alloc(new_layout), }; - self.ptr = Unique::new_unchecked(res? as *mut T); + self.ptr = res?.cast().into(); self.cap = new_cap; Ok(()) @@ -537,13 +535,12 @@ impl RawVec { let res = match self.current_layout() { Some(layout) => { debug_assert!(new_layout.align() == layout.align()); - let old_ptr = self.ptr.as_ptr() as *mut u8; - self.a.realloc(old_ptr, layout, new_layout.size()) + self.a.realloc(NonNull::from(self.ptr).as_void(), layout, new_layout.size()) } None => self.a.alloc(new_layout), }; - self.ptr = Unique::new_unchecked(res? as *mut T); + self.ptr = res?.cast().into(); self.cap = new_cap; Ok(()) @@ -600,11 +597,12 @@ impl RawVec { // (regardless of whether `self.cap - used_cap` wrapped). // Therefore we can safely call grow_in_place. - let ptr = self.ptr() as *mut _; let new_layout = Layout::new::().repeat(new_cap).unwrap().0; // FIXME: may crash and burn on over-reserve alloc_guard(new_layout.size()).expect("capacity overflow"); - match self.a.grow_in_place(ptr, old_layout, new_layout.size()) { + match self.a.grow_in_place( + NonNull::from(self.ptr).as_void(), old_layout, new_layout.size(), + ) { Ok(_) => { self.cap = new_cap; true @@ -664,10 +662,10 @@ impl RawVec { let new_size = elem_size * amount; let align = mem::align_of::(); let old_layout = Layout::from_size_align_unchecked(old_size, align); - match self.a.realloc(self.ptr.as_ptr() as *mut u8, + match self.a.realloc(NonNull::from(self.ptr).as_void(), old_layout, new_size) { - Ok(p) => self.ptr = Unique::new_unchecked(p as *mut T), + Ok(p) => self.ptr = p.cast().into(), Err(_) => self.a.oom(), } } @@ -700,8 +698,7 @@ impl RawVec { let elem_size = mem::size_of::(); if elem_size != 0 { if let Some(layout) = self.current_layout() { - let ptr = self.ptr() as *mut u8; - self.a.dealloc(ptr, layout); + self.a.dealloc(NonNull::from(self.ptr).as_void(), layout); } } } @@ -737,6 +734,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> { #[cfg(test)] mod tests { use super::*; + use alloc::Void; #[test] fn allocator_param() { @@ -756,7 +754,7 @@ mod tests { // before allocation attempts start failing. struct BoundedAlloc { fuel: usize } unsafe impl Alloc for BoundedAlloc { - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { let size = layout.size(); if size > self.fuel { return Err(AllocErr); @@ -766,7 +764,7 @@ mod tests { err @ Err(_) => err, } } - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { Global.dealloc(ptr, layout) } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 3c0b11bfe74..1c835fe50de 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -259,7 +259,7 @@ use core::ops::CoerceUnsized; use core::ptr::{self, NonNull}; use core::convert::From; -use alloc::{Global, Alloc, Layout, box_free}; +use alloc::{Global, Alloc, Layout, Void, box_free}; use string::String; use vec::Vec; @@ -671,7 +671,7 @@ impl Rc { .unwrap_or_else(|_| Global.oom()); // Initialize the real RcBox - let inner = set_data_ptr(ptr as *mut T, mem) as *mut RcBox; + let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox; ptr::write(&mut (*inner).strong, Cell::new(1)); ptr::write(&mut (*inner).weak, Cell::new(1)); @@ -737,7 +737,7 @@ impl RcFromSlice for Rc<[T]> { // In the event of a panic, elements that have been written // into the new RcBox will be dropped, then the memory freed. struct Guard { - mem: *mut u8, + mem: NonNull, elems: *mut T, layout: Layout, n_elems: usize, @@ -760,14 +760,14 @@ impl RcFromSlice for Rc<[T]> { let v_ptr = v as *const [T]; let ptr = Self::allocate_for_ptr(v_ptr); - let mem = ptr as *mut _ as *mut u8; + let mem = ptr as *mut _ as *mut Void; let layout = Layout::for_value(&*ptr); // Pointer to first element let elems = &mut (*ptr).value as *mut [T] as *mut T; let mut guard = Guard{ - mem: mem, + mem: NonNull::new_unchecked(mem), elems: elems, layout: layout, n_elems: 0, @@ -834,8 +834,6 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc { /// ``` fn drop(&mut self) { unsafe { - let ptr = self.ptr.as_ptr(); - self.dec_strong(); if self.strong() == 0 { // destroy the contained object @@ -846,7 +844,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc { self.dec_weak(); if self.weak() == 0 { - Global.dealloc(ptr as *mut u8, Layout::for_value(&*ptr)); + Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())); } } } @@ -1266,13 +1264,11 @@ impl Drop for Weak { /// ``` fn drop(&mut self) { unsafe { - let ptr = self.ptr.as_ptr(); - self.dec_weak(); // the weak count starts at 1, and will only go to zero if all // the strong pointers have disappeared. if self.weak() == 0 { - Global.dealloc(ptr as *mut u8, Layout::for_value(&*ptr)); + Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())); } } } diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs index 328131e2fef..6fa88ce969a 100644 --- a/src/liballoc/tests/heap.rs +++ b/src/liballoc/tests/heap.rs @@ -34,7 +34,8 @@ fn check_overalign_requests(mut allocator: T) { allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() }).collect(); for &ptr in &pointers { - assert_eq!((ptr as usize) % align, 0, "Got a pointer less aligned than requested") + assert_eq!((ptr.as_ptr() as usize) % align, 0, + "Got a pointer less aligned than requested") } // Clean up diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index c6507282b24..bf27e972177 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -42,6 +42,7 @@ const MIN_ALIGN: usize = 8; const MIN_ALIGN: usize = 16; use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout, Void}; +use core::ptr::NonNull; #[unstable(feature = "allocator_api", issue = "32838")] pub struct System; @@ -49,26 +50,26 @@ pub struct System; #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl Alloc for System { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { GlobalAlloc::alloc(self, layout).into() } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { GlobalAlloc::alloc_zeroed(self, layout).into() } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - GlobalAlloc::dealloc(self, ptr as *mut Void, layout) + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) } #[inline] unsafe fn realloc(&mut self, - ptr: *mut u8, + ptr: NonNull, old_layout: Layout, - new_size: usize) -> Result<*mut u8, AllocErr> { - GlobalAlloc::realloc(self, ptr as *mut Void, old_layout, new_size).into() + new_size: usize) -> Result, AllocErr> { + GlobalAlloc::realloc(self, ptr.as_ptr(), old_layout, new_size).into() } #[inline] @@ -81,26 +82,26 @@ unsafe impl Alloc for System { #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl<'a> Alloc for &'a System { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { GlobalAlloc::alloc(*self, layout).into() } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { GlobalAlloc::alloc_zeroed(*self, layout).into() } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - GlobalAlloc::dealloc(*self, ptr as *mut Void, layout) + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + GlobalAlloc::dealloc(*self, ptr.as_ptr(), layout) } #[inline] unsafe fn realloc(&mut self, - ptr: *mut u8, + ptr: NonNull, old_layout: Layout, - new_size: usize) -> Result<*mut u8, AllocErr> { - GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_size).into() + new_size: usize) -> Result, AllocErr> { + GlobalAlloc::realloc(*self, ptr.as_ptr(), old_layout, new_size).into() } #[inline] diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 7334f986f2b..632eed96049 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -42,21 +42,17 @@ impl Void { } /// Convert from a return value of GlobalAlloc::alloc to that of Alloc::alloc -impl From<*mut Void> for Result<*mut u8, AllocErr> { +impl From<*mut Void> for Result, AllocErr> { fn from(ptr: *mut Void) -> Self { - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr) - } + NonNull::new(ptr).ok_or(AllocErr) } } /// Convert from a return value of Alloc::alloc to that of GlobalAlloc::alloc -impl From> for *mut Void { - fn from(result: Result<*mut u8, AllocErr>) -> Self { +impl From, AllocErr>> for *mut Void { + fn from(result: Result, AllocErr>) -> Self { match result { - Ok(ptr) => ptr as *mut Void, + Ok(ptr) => ptr.as_ptr(), Err(_) => Void::null_mut(), } } @@ -65,7 +61,7 @@ impl From> for *mut Void { /// Represents the combination of a starting address and /// a total capacity of the returned block. #[derive(Debug)] -pub struct Excess(pub *mut u8, pub usize); +pub struct Excess(pub NonNull, pub usize); fn size_align() -> (usize, usize) { (mem::size_of::(), mem::align_of::()) @@ -575,7 +571,7 @@ pub unsafe trait 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. - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>; + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr>; /// Deallocate the memory referenced by `ptr`. /// @@ -592,7 +588,7 @@ pub unsafe trait Alloc { /// * In addition to fitting the block of memory `layout`, the /// alignment of the `layout` must match the alignment used /// to allocate that block of memory. - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout); + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout); /// Allocator-specific method for signaling an out-of-memory /// condition. @@ -710,9 +706,9 @@ pub unsafe trait Alloc { /// reallocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. unsafe fn realloc(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, - new_size: usize) -> Result<*mut u8, AllocErr> { + new_size: usize) -> Result, AllocErr> { let old_size = layout.size(); if new_size >= old_size { @@ -729,7 +725,9 @@ pub unsafe trait Alloc { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); let result = self.alloc(new_layout); if let Ok(new_ptr) = result { - ptr::copy_nonoverlapping(ptr as *const u8, new_ptr, cmp::min(old_size, new_size)); + ptr::copy_nonoverlapping(ptr.as_ptr() as *const u8, + new_ptr.as_ptr() as *mut u8, + cmp::min(old_size, new_size)); self.dealloc(ptr, layout); } result @@ -751,11 +749,11 @@ pub unsafe trait 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. - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { let size = layout.size(); let p = self.alloc(layout); if let Ok(p) = p { - ptr::write_bytes(p, 0, size); + ptr::write_bytes(p.as_ptr() as *mut u8, 0, size); } p } @@ -800,7 +798,7 @@ pub unsafe trait Alloc { /// reallocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. unsafe fn realloc_excess(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_size: usize) -> Result { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); @@ -845,7 +843,7 @@ pub unsafe trait Alloc { /// `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, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. @@ -900,7 +898,7 @@ pub unsafe trait Alloc { /// `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, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. @@ -951,7 +949,7 @@ pub unsafe trait Alloc { { let k = Layout::new::(); if k.size() > 0 { - unsafe { self.alloc(k).map(|p| NonNull::new_unchecked(p as *mut T)) } + unsafe { self.alloc(k).map(|p| p.cast()) } } else { Err(AllocErr) } @@ -977,10 +975,9 @@ pub unsafe trait Alloc { unsafe fn dealloc_one(&mut self, ptr: NonNull) where Self: Sized { - let raw_ptr = ptr.as_ptr() as *mut u8; let k = Layout::new::(); if k.size() > 0 { - self.dealloc(raw_ptr, k); + self.dealloc(ptr.as_void(), k); } } @@ -1020,10 +1017,7 @@ pub unsafe trait Alloc { match Layout::array::(n) { Ok(ref layout) if layout.size() > 0 => { unsafe { - self.alloc(layout.clone()) - .map(|p| { - NonNull::new_unchecked(p as *mut T) - }) + self.alloc(layout.clone()).map(|p| p.cast()) } } _ => Err(AllocErr), @@ -1068,11 +1062,10 @@ pub unsafe trait Alloc { n_new: usize) -> Result, AllocErr> where Self: Sized { - match (Layout::array::(n_old), Layout::array::(n_new), ptr.as_ptr()) { - (Ok(ref k_old), Ok(ref k_new), ptr) if k_old.size() > 0 && k_new.size() > 0 => { + match (Layout::array::(n_old), Layout::array::(n_new)) { + (Ok(ref k_old), Ok(ref k_new)) if k_old.size() > 0 && k_new.size() > 0 => { debug_assert!(k_old.align() == k_new.align()); - self.realloc(ptr as *mut u8, k_old.clone(), k_new.size()) - .map(|p| NonNull::new_unchecked(p as *mut T)) + self.realloc(ptr.as_void(), k_old.clone(), k_new.size()).map(NonNull::cast) } _ => { Err(AllocErr) @@ -1103,10 +1096,9 @@ pub unsafe trait Alloc { unsafe fn dealloc_array(&mut self, ptr: NonNull, n: usize) -> Result<(), AllocErr> where Self: Sized { - let raw_ptr = ptr.as_ptr() as *mut u8; match Layout::array::(n) { Ok(ref k) if k.size() > 0 => { - Ok(self.dealloc(raw_ptr, k.clone())) + Ok(self.dealloc(ptr.as_void(), k.clone())) } _ => { Err(AllocErr) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index c1e150e9fb9..f4e668328ce 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2750,6 +2750,14 @@ impl NonNull { NonNull::new_unchecked(self.as_ptr() as *mut U) } } + + /// Cast to a `Void` pointer + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn as_void(self) -> NonNull<::alloc::Void> { + unsafe { + NonNull::new_unchecked(self.as_ptr() as _) + } + } } #[stable(feature = "nonnull", since = "1.25.0")] diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 50263705143..38c99373788 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -757,12 +757,10 @@ impl RawTable { let buffer = Global.alloc(Layout::from_size_align(size, alignment) .map_err(|_| CollectionAllocErr::CapacityOverflow)?)?; - let hashes = buffer as *mut HashUint; - Ok(RawTable { capacity_mask: capacity.wrapping_sub(1), size: 0, - hashes: TaggedHashUintPtr::new(hashes), + hashes: TaggedHashUintPtr::new(buffer.cast().as_ptr()), marker: marker::PhantomData, }) } @@ -1185,7 +1183,7 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable { debug_assert!(!oflo, "should be impossible"); unsafe { - Global.dealloc(self.hashes.ptr() as *mut u8, + Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).as_void(), Layout::from_size_align(size, align).unwrap()); // Remember how everything was allocated out of one buffer // during initialization? We only need one call to free here. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 25ba75fd35e..a34fcb5a7f9 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -275,6 +275,7 @@ #![feature(macro_reexport)] #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] +#![feature(nonnull_cast)] #![feature(exhaustive_patterns)] #![feature(nonzero)] #![feature(num_bits_bytes)] diff --git a/src/test/run-pass/allocator/xcrate-use2.rs b/src/test/run-pass/allocator/xcrate-use2.rs index 52eb963efdb..b8e844522dc 100644 --- a/src/test/run-pass/allocator/xcrate-use2.rs +++ b/src/test/run-pass/allocator/xcrate-use2.rs @@ -30,7 +30,7 @@ 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()).unwrap(); + let ptr = Global.alloc(layout.clone()); helper::work_with(&ptr); assert_eq!(custom_as_global::get(), n + 1); Global.dealloc(ptr, layout.clone()); diff --git a/src/test/run-pass/realloc-16687.rs b/src/test/run-pass/realloc-16687.rs index a562165d21b..49ab0ee3310 100644 --- a/src/test/run-pass/realloc-16687.rs +++ b/src/test/run-pass/realloc-16687.rs @@ -13,10 +13,10 @@ // Ideally this would be revised to use no_std, but for now it serves // well enough to reproduce (and illustrate) the bug from #16687. -#![feature(heap_api, allocator_api)] +#![feature(heap_api, allocator_api, nonnull_cast)] -use std::heap::{Heap, Alloc, Layout}; -use std::ptr; +use std::alloc::{Global, Alloc, Layout}; +use std::ptr::{self, NonNull}; fn main() { unsafe { @@ -50,13 +50,13 @@ unsafe fn test_triangle() -> bool { println!("allocate({:?})", layout); } - let ret = Heap.alloc(layout.clone()).unwrap_or_else(|_| Heap.oom()); + let ret = Global.alloc(layout.clone()).unwrap_or_else(|_| Global.oom()); if PRINT { println!("allocate({:?}) = {:?}", layout, ret); } - ret + ret.cast().as_ptr() } unsafe fn deallocate(ptr: *mut u8, layout: Layout) { @@ -64,7 +64,7 @@ unsafe fn test_triangle() -> bool { println!("deallocate({:?}, {:?}", ptr, layout); } - Heap.dealloc(ptr, layout); + Global.dealloc(NonNull::new_unchecked(ptr).as_void(), layout); } unsafe fn reallocate(ptr: *mut u8, old: Layout, new: Layout) -> *mut u8 { @@ -72,14 +72,14 @@ unsafe fn test_triangle() -> bool { println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new); } - let ret = Heap.realloc(ptr, old.clone(), new.clone()) - .unwrap_or_else(|_| Heap.oom()); + let ret = Global.realloc(NonNull::new_unchecked(ptr).as_void(), old.clone(), new.size()) + .unwrap_or_else(|_| Global.oom()); if PRINT { println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, ret); } - ret + ret.cast().as_ptr() } fn idx_to_size(i: usize) -> usize { (i+1) * 10 } diff --git a/src/test/run-pass/regions-mock-trans.rs b/src/test/run-pass/regions-mock-trans.rs index 7d34b8fd00f..3c37243c8b9 100644 --- a/src/test/run-pass/regions-mock-trans.rs +++ b/src/test/run-pass/regions-mock-trans.rs @@ -13,6 +13,7 @@ #![feature(allocator_api)] use std::heap::{Alloc, Heap, Layout}; +use std::ptr::NonNull; struct arena(()); @@ -33,7 +34,7 @@ fn alloc<'a>(_bcx : &'a arena) -> &'a Bcx<'a> { unsafe { let ptr = Heap.alloc(Layout::new::()) .unwrap_or_else(|_| Heap.oom()); - &*(ptr as *const _) + &*(ptr.as_ptr() as *const _) } } @@ -45,7 +46,7 @@ fn g(fcx : &Fcx) { let bcx = Bcx { fcx: fcx }; let bcx2 = h(&bcx); unsafe { - Heap.dealloc(bcx2 as *const _ as *mut _, Layout::new::()); + Heap.dealloc(NonNull::new_unchecked(bcx2 as *const _ as *mut _), Layout::new::()); } } -- cgit 1.4.1-3-g733a5 From ed297777599081d11c4a337cf19c9b1a1112136b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 11 Apr 2018 16:28:37 +0200 Subject: Remove conversions for allocated pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One was now unused, and `NonNull::new(…).ok_or(AllocErr)` feels short enough for the few cases that need the other conversion. --- src/liballoc/alloc.rs | 6 +++--- src/liballoc_system/lib.rs | 16 ++++++++-------- src/libcore/alloc.rs | 17 ----------------- 3 files changed, 11 insertions(+), 28 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index af48aa7961e..031babe5f6d 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -122,7 +122,7 @@ unsafe impl GlobalAlloc for Global { unsafe impl Alloc for Global { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { - GlobalAlloc::alloc(self, layout).into() + NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr) } #[inline] @@ -137,12 +137,12 @@ unsafe impl Alloc for Global { new_size: usize) -> Result, AllocErr> { - GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size).into() + 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> { - GlobalAlloc::alloc_zeroed(self, layout).into() + NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr) } #[inline] diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index bf27e972177..7fea6061169 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -51,12 +51,12 @@ pub struct System; unsafe impl Alloc for System { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { - GlobalAlloc::alloc(self, layout).into() + NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr) } #[inline] unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { - GlobalAlloc::alloc_zeroed(self, layout).into() + NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr) } #[inline] @@ -67,9 +67,9 @@ unsafe impl Alloc for System { #[inline] unsafe fn realloc(&mut self, ptr: NonNull, - old_layout: Layout, + layout: Layout, new_size: usize) -> Result, AllocErr> { - GlobalAlloc::realloc(self, ptr.as_ptr(), old_layout, new_size).into() + NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) } #[inline] @@ -83,12 +83,12 @@ unsafe impl Alloc for System { unsafe impl<'a> Alloc for &'a System { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { - GlobalAlloc::alloc(*self, layout).into() + NonNull::new(GlobalAlloc::alloc(*self, layout)).ok_or(AllocErr) } #[inline] unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { - GlobalAlloc::alloc_zeroed(*self, layout).into() + NonNull::new(GlobalAlloc::alloc_zeroed(*self, layout)).ok_or(AllocErr) } #[inline] @@ -99,9 +99,9 @@ unsafe impl<'a> Alloc for &'a System { #[inline] unsafe fn realloc(&mut self, ptr: NonNull, - old_layout: Layout, + layout: Layout, new_size: usize) -> Result, AllocErr> { - GlobalAlloc::realloc(*self, ptr.as_ptr(), old_layout, new_size).into() + NonNull::new(GlobalAlloc::realloc(*self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) } #[inline] diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 632eed96049..97a49703baf 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -41,23 +41,6 @@ impl Void { } } -/// Convert from a return value of GlobalAlloc::alloc to that of Alloc::alloc -impl From<*mut Void> for Result, AllocErr> { - fn from(ptr: *mut Void) -> Self { - NonNull::new(ptr).ok_or(AllocErr) - } -} - -/// Convert from a return value of Alloc::alloc to that of GlobalAlloc::alloc -impl From, AllocErr>> for *mut Void { - fn from(result: Result, AllocErr>) -> Self { - match result { - Ok(ptr) => ptr.as_ptr(), - Err(_) => Void::null_mut(), - } - } -} - /// Represents the combination of a starting address and /// a total capacity of the returned block. #[derive(Debug)] -- cgit 1.4.1-3-g733a5 From f607a3872addf380846cae28661a777ec3e3c9a2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 11 Apr 2018 17:19:48 +0200 Subject: Rename alloc::Void to alloc::Opaque --- src/doc/nomicon | 2 +- .../src/language-features/global-allocator.md | 6 +- src/liballoc/alloc.rs | 26 +++--- src/liballoc/arc.rs | 6 +- src/liballoc/btree/node.rs | 10 +- src/liballoc/heap.rs | 12 +-- src/liballoc/raw_vec.rs | 22 ++--- src/liballoc/rc.rs | 10 +- src/liballoc_system/lib.rs | 103 ++++++++++----------- src/libcore/alloc.rs | 38 ++++---- src/libcore/ptr.rs | 4 +- src/librustc_allocator/expand.rs | 12 +-- src/libstd/alloc.rs | 6 +- src/libstd/collections/hash/table.rs | 2 +- src/test/run-make-fulldeps/std-core-cycle/bar.rs | 4 +- src/test/run-pass/allocator/auxiliary/custom.rs | 6 +- src/test/run-pass/allocator/custom.rs | 6 +- src/test/run-pass/realloc-16687.rs | 4 +- 18 files changed, 139 insertions(+), 140 deletions(-) (limited to 'src/liballoc_system') diff --git a/src/doc/nomicon b/src/doc/nomicon index 498ac299742..3c56329d1bd 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 498ac2997420f7b25f7cd0a3f8202950d8ad93ec +Subproject commit 3c56329d1bd9038e5341f1962bcd8d043312a712 diff --git a/src/doc/unstable-book/src/language-features/global-allocator.md b/src/doc/unstable-book/src/language-features/global-allocator.md index a3f3ee65bf0..031b6347445 100644 --- a/src/doc/unstable-book/src/language-features/global-allocator.md +++ b/src/doc/unstable-book/src/language-features/global-allocator.md @@ -29,17 +29,17 @@ looks like: ```rust #![feature(global_allocator, allocator_api, heap_api)] -use std::alloc::{GlobalAlloc, System, Layout, Void}; +use std::alloc::{GlobalAlloc, System, Layout, Opaque}; use std::ptr::NonNull; struct MyAllocator; unsafe impl GlobalAlloc for MyAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut Void { + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { System.alloc(layout) } - unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) { System.dealloc(ptr, layout) } } diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 031babe5f6d..68a617e0ffe 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -76,36 +76,36 @@ pub const Heap: Global = Global; unsafe impl GlobalAlloc for Global { #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut Void { + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { #[cfg(not(stage0))] let ptr = __rust_alloc(layout.size(), layout.align()); #[cfg(stage0)] let ptr = __rust_alloc(layout.size(), layout.align(), &mut 0); - ptr as *mut Void + ptr as *mut Opaque } #[inline] - unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) { __rust_dealloc(ptr as *mut u8, layout.size(), layout.align()) } #[inline] - unsafe fn realloc(&self, ptr: *mut Void, layout: Layout, new_size: usize) -> *mut Void { + unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque { #[cfg(not(stage0))] let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(), new_size); #[cfg(stage0)] let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(), new_size, layout.align(), &mut 0); - ptr as *mut Void + ptr as *mut Opaque } #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque { #[cfg(not(stage0))] let ptr = __rust_alloc_zeroed(layout.size(), layout.align()); #[cfg(stage0)] let ptr = __rust_alloc_zeroed(layout.size(), layout.align(), &mut 0); - ptr as *mut Void + ptr as *mut Opaque } #[inline] @@ -121,27 +121,27 @@ unsafe impl GlobalAlloc for Global { 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) } @@ -178,7 +178,7 @@ pub(crate) unsafe fn box_free(ptr: *mut T) { // 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 Void, layout); + Global.dealloc(ptr as *mut Opaque, layout); } } diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 88754ace3ce..225b055d8ee 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -518,7 +518,7 @@ impl Arc { if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); - Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())) + Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref())) } } @@ -637,7 +637,7 @@ impl ArcFromSlice for Arc<[T]> { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); - Global.dealloc(self.mem.as_void(), self.layout.clone()); + Global.dealloc(self.mem.as_opaque(), self.layout.clone()); } } } @@ -1156,7 +1156,7 @@ impl Drop for Weak { if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); unsafe { - Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())) + Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref())) } } } diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index 64aa40ac166..d6346662314 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -249,7 +249,7 @@ impl Root { self.as_mut().as_leaf_mut().parent = ptr::null(); unsafe { - Global.dealloc(NonNull::from(top).as_void(), Layout::new::>()); + Global.dealloc(NonNull::from(top).as_opaque(), Layout::new::>()); } } } @@ -435,7 +435,7 @@ impl NodeRef { > { let node = self.node; let ret = self.ascend().ok(); - Global.dealloc(node.as_void(), Layout::new::>()); + Global.dealloc(node.as_opaque(), Layout::new::>()); ret } } @@ -456,7 +456,7 @@ impl NodeRef { > { let node = self.node; let ret = self.ascend().ok(); - Global.dealloc(node.as_void(), Layout::new::>()); + Global.dealloc(node.as_opaque(), Layout::new::>()); ret } } @@ -1239,12 +1239,12 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } Global.dealloc( - right_node.node.as_void(), + right_node.node.as_opaque(), Layout::new::>(), ); } else { Global.dealloc( - right_node.node.as_void(), + right_node.node.as_opaque(), Layout::new::>(), ); } diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index cfb6504e743..faac38ca7ce 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -10,7 +10,7 @@ #![allow(deprecated)] -pub use alloc::{Layout, AllocErr, CannotReallocInPlace, Void}; +pub use alloc::{Layout, AllocErr, CannotReallocInPlace, Opaque}; use core::alloc::Alloc as CoreAlloc; use core::ptr::NonNull; @@ -54,7 +54,7 @@ unsafe impl Alloc for T where T: CoreAlloc { } unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - let ptr = NonNull::new_unchecked(ptr as *mut Void); + let ptr = NonNull::new_unchecked(ptr as *mut Opaque); CoreAlloc::dealloc(self, ptr, layout) } @@ -70,7 +70,7 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<*mut u8, AllocErr> { - let ptr = NonNull::new_unchecked(ptr as *mut Void); + let ptr = NonNull::new_unchecked(ptr as *mut Opaque); CoreAlloc::realloc(self, ptr, layout, new_layout.size()).map(|ptr| ptr.cast().as_ptr()) } @@ -87,7 +87,7 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result { - let ptr = NonNull::new_unchecked(ptr as *mut Void); + let ptr = NonNull::new_unchecked(ptr as *mut Opaque); CoreAlloc::realloc_excess(self, ptr, layout, new_layout.size()) .map(|e| Excess(e.0 .cast().as_ptr(), e.1)) } @@ -96,7 +96,7 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { - let ptr = NonNull::new_unchecked(ptr as *mut Void); + let ptr = NonNull::new_unchecked(ptr as *mut Opaque); CoreAlloc::grow_in_place(self, ptr, layout, new_layout.size()) } @@ -104,7 +104,7 @@ unsafe impl Alloc for T where T: CoreAlloc { ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { - let ptr = NonNull::new_unchecked(ptr as *mut Void); + let ptr = NonNull::new_unchecked(ptr as *mut Opaque); CoreAlloc::shrink_in_place(self, ptr, layout, new_layout.size()) } } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index d72301f5ad6..214cc7d7d0c 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -90,7 +90,7 @@ impl RawVec { // handles ZSTs and `cap = 0` alike let ptr = if alloc_size == 0 { - NonNull::::dangling().as_void() + NonNull::::dangling().as_opaque() } else { let align = mem::align_of::(); let result = if zeroed { @@ -310,7 +310,7 @@ impl RawVec { let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; alloc_guard(new_size).expect("capacity overflow"); - let ptr_res = self.a.realloc(NonNull::from(self.ptr).as_void(), + let ptr_res = self.a.realloc(NonNull::from(self.ptr).as_opaque(), cur, new_size); match ptr_res { @@ -369,7 +369,7 @@ impl RawVec { let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; alloc_guard(new_size).expect("capacity overflow"); - match self.a.grow_in_place(NonNull::from(self.ptr).as_void(), old_layout, new_size) { + match self.a.grow_in_place(NonNull::from(self.ptr).as_opaque(), old_layout, new_size) { Ok(_) => { // We can't directly divide `size`. self.cap = new_cap; @@ -426,7 +426,7 @@ impl RawVec { let res = match self.current_layout() { Some(layout) => { debug_assert!(new_layout.align() == layout.align()); - self.a.realloc(NonNull::from(self.ptr).as_void(), layout, new_layout.size()) + self.a.realloc(NonNull::from(self.ptr).as_opaque(), layout, new_layout.size()) } None => self.a.alloc(new_layout), }; @@ -535,7 +535,7 @@ impl RawVec { let res = match self.current_layout() { Some(layout) => { debug_assert!(new_layout.align() == layout.align()); - self.a.realloc(NonNull::from(self.ptr).as_void(), layout, new_layout.size()) + self.a.realloc(NonNull::from(self.ptr).as_opaque(), layout, new_layout.size()) } None => self.a.alloc(new_layout), }; @@ -601,7 +601,7 @@ impl RawVec { // FIXME: may crash and burn on over-reserve alloc_guard(new_layout.size()).expect("capacity overflow"); match self.a.grow_in_place( - NonNull::from(self.ptr).as_void(), old_layout, new_layout.size(), + NonNull::from(self.ptr).as_opaque(), old_layout, new_layout.size(), ) { Ok(_) => { self.cap = new_cap; @@ -662,7 +662,7 @@ impl RawVec { let new_size = elem_size * amount; let align = mem::align_of::(); let old_layout = Layout::from_size_align_unchecked(old_size, align); - match self.a.realloc(NonNull::from(self.ptr).as_void(), + match self.a.realloc(NonNull::from(self.ptr).as_opaque(), old_layout, new_size) { Ok(p) => self.ptr = p.cast().into(), @@ -698,7 +698,7 @@ impl RawVec { let elem_size = mem::size_of::(); if elem_size != 0 { if let Some(layout) = self.current_layout() { - self.a.dealloc(NonNull::from(self.ptr).as_void(), layout); + self.a.dealloc(NonNull::from(self.ptr).as_opaque(), layout); } } } @@ -734,7 +734,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> { #[cfg(test)] mod tests { use super::*; - use alloc::Void; + use alloc::Opaque; #[test] fn allocator_param() { @@ -754,7 +754,7 @@ mod tests { // before allocation attempts start failing. struct BoundedAlloc { fuel: usize } unsafe impl Alloc for BoundedAlloc { - unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { let size = layout.size(); if size > self.fuel { return Err(AllocErr); @@ -764,7 +764,7 @@ mod tests { err @ Err(_) => err, } } - unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { Global.dealloc(ptr, layout) } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1c835fe50de..de0422d82bb 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -259,7 +259,7 @@ use core::ops::CoerceUnsized; use core::ptr::{self, NonNull}; use core::convert::From; -use alloc::{Global, Alloc, Layout, Void, box_free}; +use alloc::{Global, Alloc, Layout, Opaque, box_free}; use string::String; use vec::Vec; @@ -737,7 +737,7 @@ impl RcFromSlice for Rc<[T]> { // In the event of a panic, elements that have been written // into the new RcBox will be dropped, then the memory freed. struct Guard { - mem: NonNull, + mem: NonNull, elems: *mut T, layout: Layout, n_elems: usize, @@ -760,7 +760,7 @@ impl RcFromSlice for Rc<[T]> { let v_ptr = v as *const [T]; let ptr = Self::allocate_for_ptr(v_ptr); - let mem = ptr as *mut _ as *mut Void; + let mem = ptr as *mut _ as *mut Opaque; let layout = Layout::for_value(&*ptr); // Pointer to first element @@ -844,7 +844,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc { self.dec_weak(); if self.weak() == 0 { - Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())); + Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref())); } } } @@ -1268,7 +1268,7 @@ impl Drop for Weak { // the weak count starts at 1, and will only go to zero if all // the strong pointers have disappeared. if self.weak() == 0 { - Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref())); + Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref())); } } } diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 7fea6061169..fd8109e2a4a 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -41,7 +41,7 @@ const MIN_ALIGN: usize = 8; #[allow(dead_code)] const MIN_ALIGN: usize = 16; -use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout, Void}; +use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout, Opaque}; use core::ptr::NonNull; #[unstable(feature = "allocator_api", issue = "32838")] @@ -50,25 +50,25 @@ pub struct System; #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl Alloc for System { #[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 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) } #[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> { + new_size: usize) -> Result, AllocErr> { NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) } @@ -82,25 +82,25 @@ unsafe impl Alloc for System { #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl<'a> Alloc for &'a System { #[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 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) } #[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> { + new_size: usize) -> Result, AllocErr> { NonNull::new(GlobalAlloc::realloc(*self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) } @@ -112,13 +112,13 @@ unsafe impl<'a> Alloc for &'a System { #[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))] mod realloc_fallback { - use core::alloc::{GlobalAlloc, Void, Layout}; + use core::alloc::{GlobalAlloc, Opaque, Layout}; use core::cmp; use core::ptr; impl super::System { - pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut Void, old_layout: Layout, - new_size: usize) -> *mut Void { + pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut Opaque, old_layout: Layout, + new_size: usize) -> *mut Opaque { // Docs for GlobalAlloc::realloc require this to be valid: let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); @@ -141,20 +141,21 @@ mod platform { use MIN_ALIGN; use System; - use core::alloc::{GlobalAlloc, Layout, Void}; + use core::alloc::{GlobalAlloc, Layout, Opaque}; #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl GlobalAlloc for System { #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut Void { + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::malloc(layout.size()) as *mut Void + libc::malloc(layout.size()) as *mut Opaque } else { #[cfg(target_os = "macos")] { if layout.align() > (1 << 31) { - // FIXME: use Void::null_mut https://github.com/rust-lang/rust/issues/49659 - return 0 as *mut Void + // FIXME: use Opaque::null_mut + // https://github.com/rust-lang/rust/issues/49659 + return 0 as *mut Opaque } } aligned_malloc(&layout) @@ -162,9 +163,9 @@ mod platform { } #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque { if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::calloc(layout.size(), 1) as *mut Void + libc::calloc(layout.size(), 1) as *mut Opaque } else { let ptr = self.alloc(layout.clone()); if !ptr.is_null() { @@ -175,24 +176,23 @@ mod platform { } #[inline] - unsafe fn dealloc(&self, ptr: *mut Void, _layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Opaque, _layout: Layout) { libc::free(ptr as *mut libc::c_void) } #[inline] - unsafe fn realloc(&self, ptr: *mut Void, old_layout: Layout, new_size: usize) -> *mut Void { - let align = old_layout.align(); - if align <= MIN_ALIGN && align <= new_size { - libc::realloc(ptr as *mut libc::c_void, new_size) as *mut Void + unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque { + if layout.align() <= MIN_ALIGN && layout.align() <= new_size { + libc::realloc(ptr as *mut libc::c_void, new_size) as *mut Opaque } else { - self.realloc_fallback(ptr, old_layout, new_size) + self.realloc_fallback(ptr, layout, new_size) } } } #[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))] #[inline] - unsafe fn aligned_malloc(layout: &Layout) -> *mut Void { + unsafe fn aligned_malloc(layout: &Layout) -> *mut Opaque { // On android we currently target API level 9 which unfortunately // doesn't have the `posix_memalign` API used below. Instead we use // `memalign`, but this unfortunately has the property on some systems @@ -210,19 +210,19 @@ mod platform { // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579 // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/ // /memory/aligned_memory.cc - libc::memalign(layout.align(), layout.size()) as *mut Void + libc::memalign(layout.align(), layout.size()) as *mut Opaque } #[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))] #[inline] - unsafe fn aligned_malloc(layout: &Layout) -> *mut Void { + unsafe fn aligned_malloc(layout: &Layout) -> *mut Opaque { let mut out = ptr::null_mut(); let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); if ret != 0 { - // FIXME: use Void::null_mut https://github.com/rust-lang/rust/issues/49659 - 0 as *mut Void + // FIXME: use Opaque::null_mut https://github.com/rust-lang/rust/issues/49659 + 0 as *mut Opaque } else { - out as *mut Void + out as *mut Opaque } } } @@ -232,7 +232,7 @@ mod platform { mod platform { use MIN_ALIGN; use System; - use core::alloc::{GlobalAlloc, Void, Layout}; + use core::alloc::{GlobalAlloc, Opaque, Layout}; type LPVOID = *mut u8; type HANDLE = LPVOID; @@ -264,7 +264,7 @@ mod platform { } #[inline] - unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut Void { + unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut Opaque { let ptr = if layout.align() <= MIN_ALIGN { HeapAlloc(GetProcessHeap(), flags, layout.size()) } else { @@ -276,23 +276,23 @@ mod platform { align_ptr(ptr, layout.align()) } }; - ptr as *mut Void + ptr as *mut Opaque } #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl GlobalAlloc for System { #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut Void { + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { allocate_with_flags(layout, 0) } #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque { allocate_with_flags(layout, HEAP_ZERO_MEMORY) } #[inline] - unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) { if layout.align() <= MIN_ALIGN { let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); debug_assert!(err != 0, "Failed to free heap memory: {}", @@ -306,12 +306,11 @@ mod platform { } #[inline] - unsafe fn realloc(&self, ptr: *mut Void, old_layout: Layout, new_size: usize) -> *mut Void { - let align = old_layout.align(); - if align <= MIN_ALIGN { - HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut Void + unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque { + if layout.align() <= MIN_ALIGN { + HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut Opaque } else { - self.realloc_fallback(ptr, old_layout, new_size) + self.realloc_fallback(ptr, layout, new_size) } } } @@ -338,7 +337,7 @@ mod platform { mod platform { extern crate dlmalloc; - use core::alloc::{GlobalAlloc, Layout, Void}; + use core::alloc::{GlobalAlloc, Layout, Opaque}; use System; // No need for synchronization here as wasm is currently single-threaded @@ -347,23 +346,23 @@ mod platform { #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl GlobalAlloc for System { #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut Void { - DLMALLOC.malloc(layout.size(), layout.align()) as *mut Void + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { + DLMALLOC.malloc(layout.size(), layout.align()) as *mut Opaque } #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { - DLMALLOC.calloc(layout.size(), layout.align()) as *mut Void + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque { + DLMALLOC.calloc(layout.size(), layout.align()) as *mut Opaque } #[inline] - unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) { DLMALLOC.free(ptr as *mut u8, layout.size(), layout.align()) } #[inline] - unsafe fn realloc(&self, ptr: *mut Void, layout: Layout, new_size: usize) -> *mut Void { - DLMALLOC.realloc(ptr as *mut u8, layout.size(), layout.align(), new_size) as *mut Void + unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque { + DLMALLOC.realloc(ptr as *mut u8, layout.size(), layout.align(), new_size) as *mut Opaque } } } diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 97a49703baf..fdba91bec80 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -24,12 +24,12 @@ use ptr::{self, NonNull}; extern { /// An opaque, unsized type. Used for pointers to allocated memory. /// - /// This type can only be used behind a pointer like `*mut Void` or `ptr::NonNull`. + /// This type can only be used behind a pointer like `*mut Opaque` or `ptr::NonNull`. /// Such pointers are similar to C’s `void*` type. - pub type Void; + pub type Opaque; } -impl Void { +impl Opaque { /// Similar to `std::ptr::null`, which requires `T: Sized`. pub fn null() -> *const Self { 0 as _ @@ -44,7 +44,7 @@ impl Void { /// Represents the combination of a starting address and /// a total capacity of the returned block. #[derive(Debug)] -pub struct Excess(pub NonNull, pub usize); +pub struct Excess(pub NonNull, pub usize); fn size_align() -> (usize, usize) { (mem::size_of::(), mem::align_of::()) @@ -387,11 +387,11 @@ impl From for CollectionAllocErr { // FIXME: docs pub unsafe trait GlobalAlloc { - unsafe fn alloc(&self, layout: Layout) -> *mut Void; + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque; - unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout); + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout); - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque { let size = layout.size(); let ptr = self.alloc(layout); if !ptr.is_null() { @@ -404,7 +404,7 @@ pub unsafe trait GlobalAlloc { /// /// `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`). - unsafe fn realloc(&self, ptr: *mut Void, old_layout: Layout, new_size: usize) -> *mut Void { + unsafe fn realloc(&self, ptr: *mut Opaque, old_layout: Layout, new_size: usize) -> *mut Opaque { let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); let new_ptr = self.alloc(new_layout); if !new_ptr.is_null() { @@ -554,7 +554,7 @@ pub unsafe trait 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. - unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr>; + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr>; /// Deallocate the memory referenced by `ptr`. /// @@ -571,7 +571,7 @@ pub unsafe trait Alloc { /// * In addition to fitting the block of memory `layout`, the /// alignment of the `layout` must match the alignment used /// to allocate that block of memory. - unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout); + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout); /// Allocator-specific method for signaling an out-of-memory /// condition. @@ -689,9 +689,9 @@ pub unsafe trait Alloc { /// reallocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. unsafe fn realloc(&mut self, - ptr: NonNull, + ptr: NonNull, layout: Layout, - new_size: usize) -> Result, AllocErr> { + new_size: usize) -> Result, AllocErr> { let old_size = layout.size(); if new_size >= old_size { @@ -732,7 +732,7 @@ pub unsafe trait 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. - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { let size = layout.size(); let p = self.alloc(layout); if let Ok(p) = p { @@ -781,7 +781,7 @@ pub unsafe trait Alloc { /// reallocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. unsafe fn realloc_excess(&mut self, - ptr: NonNull, + ptr: NonNull, layout: Layout, new_size: usize) -> Result { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); @@ -826,7 +826,7 @@ pub unsafe trait Alloc { /// `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, - ptr: NonNull, + ptr: NonNull, layout: Layout, new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. @@ -881,7 +881,7 @@ pub unsafe trait Alloc { /// `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, - ptr: NonNull, + ptr: NonNull, layout: Layout, new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. @@ -960,7 +960,7 @@ pub unsafe trait Alloc { { let k = Layout::new::(); if k.size() > 0 { - self.dealloc(ptr.as_void(), k); + self.dealloc(ptr.as_opaque(), k); } } @@ -1048,7 +1048,7 @@ pub unsafe trait Alloc { match (Layout::array::(n_old), Layout::array::(n_new)) { (Ok(ref k_old), Ok(ref k_new)) if k_old.size() > 0 && k_new.size() > 0 => { debug_assert!(k_old.align() == k_new.align()); - self.realloc(ptr.as_void(), k_old.clone(), k_new.size()).map(NonNull::cast) + self.realloc(ptr.as_opaque(), k_old.clone(), k_new.size()).map(NonNull::cast) } _ => { Err(AllocErr) @@ -1081,7 +1081,7 @@ pub unsafe trait Alloc { { match Layout::array::(n) { Ok(ref k) if k.size() > 0 => { - Ok(self.dealloc(ptr.as_void(), k.clone())) + Ok(self.dealloc(ptr.as_opaque(), k.clone())) } _ => { Err(AllocErr) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f4e668328ce..4a7d7c410eb 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2751,9 +2751,9 @@ impl NonNull { } } - /// Cast to a `Void` pointer + /// Cast to an `Opaque` pointer #[unstable(feature = "allocator_api", issue = "32838")] - pub fn as_void(self) -> NonNull<::alloc::Void> { + pub fn as_opaque(self) -> NonNull<::alloc::Opaque> { unsafe { NonNull::new_unchecked(self.as_ptr() as _) } diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 58d4c7f289c..305502e7f06 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -221,7 +221,7 @@ impl<'a> AllocFnFactory<'a> { let ident = ident(); args.push(self.cx.arg(self.span, ident, self.ptr_u8())); let arg = self.cx.expr_ident(self.span, ident); - self.cx.expr_cast(self.span, arg, self.ptr_void()) + self.cx.expr_cast(self.span, arg, self.ptr_opaque()) } AllocatorTy::Usize => { @@ -276,13 +276,13 @@ impl<'a> AllocFnFactory<'a> { self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable) } - fn ptr_void(&self) -> P { - let void = self.cx.path(self.span, vec![ + fn ptr_opaque(&self) -> P { + let opaque = self.cx.path(self.span, vec![ self.core, Ident::from_str("alloc"), - Ident::from_str("Void"), + Ident::from_str("Opaque"), ]); - let ty_void = self.cx.ty_path(void); - self.cx.ty_ptr(self.span, ty_void, Mutability::Mutable) + let ty_opaque = self.cx.ty_path(opaque); + self.cx.ty_ptr(self.span, ty_opaque, Mutability::Mutable) } } diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 4e728df010a..ff578ec42d2 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -21,7 +21,7 @@ #[doc(hidden)] #[allow(unused_attributes)] pub mod __default_lib_allocator { - use super::{System, Layout, GlobalAlloc, Void}; + use super::{System, Layout, GlobalAlloc, Opaque}; // for symbol names src/librustc/middle/allocator.rs // for signatures src/librustc_allocator/lib.rs @@ -46,7 +46,7 @@ pub mod __default_lib_allocator { pub unsafe extern fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize) { - System.dealloc(ptr as *mut Void, Layout::from_size_align_unchecked(size, align)) + System.dealloc(ptr as *mut Opaque, Layout::from_size_align_unchecked(size, align)) } #[no_mangle] @@ -56,7 +56,7 @@ pub mod __default_lib_allocator { align: usize, new_size: usize) -> *mut u8 { let old_layout = Layout::from_size_align_unchecked(old_size, align); - System.realloc(ptr as *mut Void, old_layout, new_size) as *mut u8 + System.realloc(ptr as *mut Opaque, old_layout, new_size) as *mut u8 } #[no_mangle] diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 38c99373788..93f059076d7 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -1183,7 +1183,7 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable { debug_assert!(!oflo, "should be impossible"); unsafe { - Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).as_void(), + Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).as_opaque(), Layout::from_size_align(size, align).unwrap()); // Remember how everything was allocated out of one buffer // during initialization? We only need one call to free here. diff --git a/src/test/run-make-fulldeps/std-core-cycle/bar.rs b/src/test/run-make-fulldeps/std-core-cycle/bar.rs index 20b87028fd1..62fd2ade1ca 100644 --- a/src/test/run-make-fulldeps/std-core-cycle/bar.rs +++ b/src/test/run-make-fulldeps/std-core-cycle/bar.rs @@ -16,11 +16,11 @@ use std::alloc::*; pub struct A; unsafe impl GlobalAlloc for A { - unsafe fn alloc(&self, _: Layout) -> *mut Void { + unsafe fn alloc(&self, _: Layout) -> *mut Opaque { loop {} } - unsafe fn dealloc(&self, _ptr: *mut Void, _: Layout) { + unsafe fn dealloc(&self, _ptr: *mut Opaque, _: Layout) { loop {} } } diff --git a/src/test/run-pass/allocator/auxiliary/custom.rs b/src/test/run-pass/allocator/auxiliary/custom.rs index 95096efc7ef..e6a2e22983b 100644 --- a/src/test/run-pass/allocator/auxiliary/custom.rs +++ b/src/test/run-pass/allocator/auxiliary/custom.rs @@ -13,18 +13,18 @@ #![feature(heap_api, allocator_api)] #![crate_type = "rlib"] -use std::heap::{GlobalAlloc, System, Layout, Void}; +use std::heap::{GlobalAlloc, System, Layout, Opaque}; use std::sync::atomic::{AtomicUsize, Ordering}; pub struct A(pub AtomicUsize); unsafe impl GlobalAlloc for A { - unsafe fn alloc(&self, layout: Layout) -> *mut Void { + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { self.0.fetch_add(1, Ordering::SeqCst); System.alloc(layout) } - unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) { self.0.fetch_add(1, Ordering::SeqCst); System.dealloc(ptr, layout) } diff --git a/src/test/run-pass/allocator/custom.rs b/src/test/run-pass/allocator/custom.rs index f7b2fd73c87..415d39a593e 100644 --- a/src/test/run-pass/allocator/custom.rs +++ b/src/test/run-pass/allocator/custom.rs @@ -15,7 +15,7 @@ extern crate helper; -use std::alloc::{self, Global, Alloc, System, Layout, Void}; +use std::alloc::{self, Global, Alloc, System, Layout, Opaque}; use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; static HITS: AtomicUsize = ATOMIC_USIZE_INIT; @@ -23,12 +23,12 @@ static HITS: AtomicUsize = ATOMIC_USIZE_INIT; struct A; unsafe impl alloc::GlobalAlloc for A { - unsafe fn alloc(&self, layout: Layout) -> *mut Void { + unsafe fn alloc(&self, layout: Layout) -> *mut Opaque { HITS.fetch_add(1, Ordering::SeqCst); System.alloc(layout) } - unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) { HITS.fetch_add(1, Ordering::SeqCst); System.dealloc(ptr, layout) } diff --git a/src/test/run-pass/realloc-16687.rs b/src/test/run-pass/realloc-16687.rs index 49ab0ee3310..38cc23c16a9 100644 --- a/src/test/run-pass/realloc-16687.rs +++ b/src/test/run-pass/realloc-16687.rs @@ -64,7 +64,7 @@ unsafe fn test_triangle() -> bool { println!("deallocate({:?}, {:?}", ptr, layout); } - Global.dealloc(NonNull::new_unchecked(ptr).as_void(), layout); + Global.dealloc(NonNull::new_unchecked(ptr).as_opaque(), layout); } unsafe fn reallocate(ptr: *mut u8, old: Layout, new: Layout) -> *mut u8 { @@ -72,7 +72,7 @@ unsafe fn test_triangle() -> bool { println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new); } - let ret = Global.realloc(NonNull::new_unchecked(ptr).as_void(), old.clone(), new.size()) + let ret = Global.realloc(NonNull::new_unchecked(ptr).as_opaque(), old.clone(), new.size()) .unwrap_or_else(|_| Global.oom()); if PRINT { -- cgit 1.4.1-3-g733a5