diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/collections/hash/table.rs | 11 | ||||
| -rw-r--r-- | src/libstd/error.rs | 4 | ||||
| -rw-r--r-- | src/libstd/heap.rs | 165 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 14 | ||||
| -rw-r--r-- | src/libstd/sys/unix/mod.rs | 20 | ||||
| -rw-r--r-- | src/libstd/sys/windows/mod.rs | 18 |
6 files changed, 178 insertions, 54 deletions
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 50c721db849..06f4f7643ec 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use alloc::heap::{allocate, deallocate}; +use alloc::heap::{Heap, Alloc, Layout}; use cmp; use hash::{BuildHasher, Hash, Hasher}; @@ -781,10 +781,8 @@ impl<K, V> RawTable<K, V> { .expect("capacity overflow"), "capacity overflow"); - let buffer = allocate(size, alignment); - if buffer.is_null() { - ::alloc::oom() - } + let buffer = Heap.alloc(Layout::from_size_align(size, alignment).unwrap()) + .unwrap_or_else(|e| Heap.oom(e)); let hashes = buffer.offset(hash_offset as isize) as *mut HashUint; @@ -1193,7 +1191,8 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> { debug_assert!(!oflo, "should be impossible"); unsafe { - deallocate(self.hashes.ptr() as *mut u8, size, align); + Heap.dealloc(self.hashes.ptr() as *mut u8, + 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/error.rs b/src/libstd/error.rs index 4b340f70fbc..d77f817659c 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -224,7 +224,7 @@ impl Error for ! { #[unstable(feature = "allocator_api", reason = "the precise API and guarantees it provides may be tweaked.", - issue = "27700")] + issue = "32838")] impl Error for allocator::AllocErr { fn description(&self) -> &str { allocator::AllocErr::description(self) @@ -233,7 +233,7 @@ impl Error for allocator::AllocErr { #[unstable(feature = "allocator_api", reason = "the precise API and guarantees it provides may be tweaked.", - issue = "27700")] + issue = "32838")] impl Error for allocator::CannotReallocInPlace { fn description(&self) -> &str { allocator::CannotReallocInPlace::description(self) diff --git a/src/libstd/heap.rs b/src/libstd/heap.rs new file mode 100644 index 00000000000..83bd3b04b4d --- /dev/null +++ b/src/libstd/heap.rs @@ -0,0 +1,165 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! dox + +#![unstable(issue = "32838", feature = "allocator_api")] + +pub use alloc::heap::{Heap, Alloc, Layout, Excess, CannotReallocInPlace, AllocErr}; +#[cfg(not(stage0))] +pub use alloc_system::System; + +#[cfg(all(not(stage0), not(test)))] +#[doc(hidden)] +pub mod __default_lib_allocator { + use super::{System, Layout, Alloc, AllocErr}; + use ptr; + + // for symbol names src/librustc/middle/allocator.rs + // for signatures src/librustc_allocator/lib.rs + + // linkage directives are provided as part of the current compiler allocator + // ABI + + #[no_mangle] + pub unsafe extern fn __rdl_alloc(size: usize, + align: usize, + 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 + } + } + } + + #[no_mangle] + pub unsafe extern fn __rdl_oom(err: *const u8) -> ! { + System.oom((*(err as *const AllocErr)).clone()) + } + + #[no_mangle] + pub unsafe extern fn __rdl_dealloc(ptr: *mut u8, + size: usize, + align: usize) { + System.dealloc(ptr, Layout::from_size_align_unchecked(size, align)) + } + + #[no_mangle] + pub unsafe extern fn __rdl_usable_size(layout: *const u8, + min: *mut usize, + max: *mut usize) { + let pair = System.usable_size(&*(layout as *const Layout)); + *min = pair.0; + *max = pair.1; + } + + #[no_mangle] + pub unsafe extern fn __rdl_realloc(ptr: *mut u8, + old_size: usize, + old_align: usize, + new_size: usize, + new_align: usize, + 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 + } + } + } + + #[no_mangle] + pub unsafe extern fn __rdl_alloc_zeroed(size: usize, + align: usize, + 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 + } + } + } + + #[no_mangle] + pub unsafe extern fn __rdl_alloc_excess(size: usize, + align: usize, + excess: *mut usize, + 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 + } + } + } + + #[no_mangle] + pub unsafe extern fn __rdl_realloc_excess(ptr: *mut u8, + old_size: usize, + old_align: usize, + new_size: usize, + new_align: usize, + excess: *mut usize, + 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) { + Ok(p) => { + *excess = p.1; + p.0 + } + Err(e) => { + ptr::write(err as *mut AllocErr, e); + 0 as *mut u8 + } + } + } + + #[no_mangle] + pub unsafe extern fn __rdl_grow_in_place(ptr: *mut u8, + old_size: usize, + old_align: usize, + new_size: usize, + new_align: usize) -> 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.grow_in_place(ptr, old_layout, new_layout) { + Ok(()) => 1, + Err(_) => 0, + } + } + + #[no_mangle] + pub unsafe extern fn __rdl_shrink_in_place(ptr: *mut u8, + old_size: usize, + old_align: usize, + new_size: usize, + new_align: usize) -> 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.shrink_in_place(ptr, old_layout, new_layout) { + Ok(()) => 1, + Err(_) => 0, + } + } +} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bafe23e80a0..c4bdf7c5b82 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -230,11 +230,6 @@ // Tell the compiler to link to either panic_abort or panic_unwind #![needs_panic_runtime] -// Always use alloc_system during stage0 since we don't know if the alloc_* -// crate the stage0 compiler will pick by default is available (most -// obviously, if the user has disabled jemalloc in `./configure`). -#![cfg_attr(any(stage0, feature = "force_alloc_system"), feature(alloc_system))] - // Turn warnings into errors, but only after stage0, where it can be useful for // code to emit warnings during language transitions #![deny(warnings)] @@ -246,6 +241,8 @@ // compiler details that will never be stable #![feature(alloc)] #![feature(allocator_api)] +#![feature(alloc_system)] +#![feature(allocator_internals)] #![feature(allow_internal_unstable)] #![feature(asm)] #![feature(associated_consts)] @@ -322,6 +319,8 @@ #![cfg_attr(test, feature(update_panic_count))] #![cfg_attr(test, feature(float_bits_conv))] +#![cfg_attr(not(stage0), default_lib_allocator)] + // Explicitly import the prelude. The compiler uses this same unstable attribute // to import the prelude implicitly when building crates that depend on std. #[prelude_import] @@ -342,15 +341,13 @@ extern crate core as __core; #[macro_use] #[macro_reexport(vec, format)] extern crate alloc; +extern crate alloc_system; extern crate std_unicode; extern crate libc; // We always need an unwinder currently for backtraces extern crate unwind; -#[cfg(any(stage0, feature = "force_alloc_system"))] -extern crate alloc_system; - // compiler-rt intrinsics extern crate compiler_builtins; @@ -465,6 +462,7 @@ pub mod path; pub mod process; pub mod sync; pub mod time; +pub mod heap; // Platform-abstraction modules #[macro_use] diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 854d380d128..46e5acdf3d2 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -59,8 +59,6 @@ pub mod stdio; #[cfg(not(test))] pub fn init() { - use alloc::oom; - // By default, some platforms will send a *signal* when an EPIPE error // would otherwise be delivered. This runtime doesn't install a SIGPIPE // handler, causing it to kill the program, which isn't exactly what we @@ -72,24 +70,6 @@ pub fn init() { reset_sigpipe(); } - oom::set_oom_handler(oom_handler); - - // A nicer handler for out-of-memory situations than the default one. This - // one prints a message to stderr before aborting. 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. - fn oom_handler() -> ! { - use intrinsics; - let msg = "fatal runtime error: out of memory\n"; - unsafe { - libc::write(libc::STDERR_FILENO, - msg.as_ptr() as *const libc::c_void, - msg.len()); - intrinsics::abort(); - } - } - #[cfg(not(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia")))] unsafe fn reset_sigpipe() { assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR); diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 840e7fdfc9b..ee58efc5144 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -47,24 +47,6 @@ pub mod stdio; #[cfg(not(test))] pub fn init() { - ::alloc::oom::set_oom_handler(oom_handler); - - // See comment in sys/unix/mod.rs - fn oom_handler() -> ! { - use intrinsics; - use ptr; - let msg = "fatal runtime error: out of memory\n"; - unsafe { - // WriteFile silently fails if it is passed an invalid handle, so - // there is no need to check the result of GetStdHandle. - c::WriteFile(c::GetStdHandle(c::STD_ERROR_HANDLE), - msg.as_ptr() as c::LPVOID, - msg.len() as c::DWORD, - ptr::null_mut(), - ptr::null_mut()); - intrinsics::abort(); - } - } } pub fn decode_error_kind(errno: i32) -> ErrorKind { |
