diff options
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/heap.rs | 197 | ||||
| -rw-r--r-- | src/libstd/rt/libc_heap.rs | 51 | ||||
| -rw-r--r-- | src/libstd/rt/local_heap.rs | 3 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 8 | ||||
| -rw-r--r-- | src/libstd/rt/util.rs | 17 |
5 files changed, 4 insertions, 272 deletions
diff --git a/src/libstd/rt/heap.rs b/src/libstd/rt/heap.rs deleted file mode 100644 index e616b9b8beb..00000000000 --- a/src/libstd/rt/heap.rs +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2014 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. - -// FIXME: #13994: port to the sized deallocation API when available -// FIXME: #13996: need a way to mark the `allocate` and `reallocate` return values as `noalias` - -use intrinsics::{abort, cttz32}; -use libc::{c_char, c_int, c_void, size_t}; -use ptr::{RawPtr, mut_null, null}; -use option::{None, Option}; - -#[link(name = "jemalloc", kind = "static")] -extern { - fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void; - fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; - fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; - fn je_dallocx(ptr: *mut c_void, flags: c_int); - fn je_nallocx(size: size_t, flags: c_int) -> size_t; - fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void, *c_char)>, - cbopaque: *mut c_void, - opts: *c_char); -} - -// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough -#[cfg(not(windows), not(target_os = "android"))] -#[link(name = "pthread")] -extern {} - -// MALLOCX_ALIGN(a) macro -#[inline(always)] -fn mallocx_align(a: uint) -> c_int { unsafe { cttz32(a as u32) as c_int } } - -/// Return a pointer to `size` bytes of memory. -/// -/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The -/// alignment must be no larger than the largest supported page size on the platform. -#[inline] -pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 { - let ptr = je_mallocx(size as size_t, mallocx_align(align)) as *mut u8; - if ptr.is_null() { - abort() - } - ptr -} - -/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory. -/// -/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The -/// alignment must be no larger than the largest supported page size on the platform. -/// -/// The `old_size` and `align` parameters are the parameters that were used to create the -/// allocation referenced by `ptr`. The `old_size` parameter may also be the value returned by -/// `usable_size` for the requested size. -#[inline] -#[allow(unused_variable)] // for the parameter names in the documentation -pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> *mut u8 { - let ptr = je_rallocx(ptr as *mut c_void, size as size_t, mallocx_align(align)) as *mut u8; - if ptr.is_null() { - abort() - } - ptr -} - -/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory in-place. -/// -/// Return true if successful, otherwise false if the allocation was not altered. -/// -/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The -/// alignment must be no larger than the largest supported page size on the platform. -/// -/// The `old_size` and `align` parameters are the parameters that were used to -/// create the allocation referenced by `ptr`. The `old_size` parameter may be -/// any value in range_inclusive(requested_size, usable_size). -#[inline] -#[allow(unused_variable)] // for the parameter names in the documentation -pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> bool { - je_xallocx(ptr as *mut c_void, size as size_t, 0, mallocx_align(align)) == size as size_t -} - -/// Deallocate the memory referenced by `ptr`. -/// -/// The `ptr` parameter must not be null. -/// -/// The `size` and `align` parameters are the parameters that were used to create the -/// allocation referenced by `ptr`. The `size` parameter may also be the value returned by -/// `usable_size` for the requested size. -#[inline] -#[allow(unused_variable)] // for the parameter names in the documentation -pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) { - je_dallocx(ptr as *mut c_void, mallocx_align(align)) -} - -/// Return the usable size of an allocation created with the specified the `size` and `align`. -#[inline] -pub fn usable_size(size: uint, align: uint) -> uint { - unsafe { je_nallocx(size as size_t, mallocx_align(align)) as uint } -} - -/// Print implementation-defined allocator statistics. -/// -/// These statistics may be inconsistent if other threads use the allocator during the call. -#[unstable] -pub fn stats_print() { - unsafe { - je_malloc_stats_print(None, mut_null(), null()) - } -} - -/// The allocator for unique pointers. -#[cfg(not(test))] -#[lang="exchange_malloc"] -#[inline(always)] -pub unsafe fn exchange_malloc_(size: uint, align: uint) -> *mut u8 { - exchange_malloc(size, align) -} - -/// The allocator for unique pointers. -#[inline] -pub unsafe fn exchange_malloc(size: uint, align: uint) -> *mut u8 { - // The compiler never calls `exchange_free` on ~ZeroSizeType, so zero-size - // allocations can point to this `static`. It would be incorrect to use a null - // pointer, due to enums assuming types like unique pointers are never null. - static EMPTY: () = (); - - if size == 0 { - &EMPTY as *() as *mut u8 - } else { - allocate(size, align) - } -} - -#[cfg(not(test))] -#[lang="exchange_free"] -#[inline] -// FIXME: #13994 (rustc should pass align and size here) -unsafe fn exchange_free(ptr: *mut u8) { - deallocate(ptr, 0, 8); -} - -// FIXME: #7496 -#[cfg(not(test))] -#[lang="closure_exchange_malloc"] -#[inline] -unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut u8 { - let total_size = ::rt::util::get_box_size(size, align); - let p = allocate(total_size, 8); - - let alloc = p as *mut ::raw::Box<()>; - (*alloc).drop_glue = drop_glue; - - alloc as *mut u8 -} - -// hack for libcore -#[no_mangle] -#[doc(hidden)] -#[deprecated] -#[cfg(not(test))] -pub unsafe extern "C" fn rust_malloc(size: uint, align: uint) -> *mut u8 { - exchange_malloc(size, align) -} - -// hack for libcore -#[no_mangle] -#[doc(hidden)] -#[deprecated] -#[cfg(not(test))] -pub unsafe extern "C" fn rust_free(ptr: *mut u8, size: uint, align: uint) { - deallocate(ptr, size, align) -} - -#[cfg(test)] -mod bench { - extern crate test; - use self::test::Bencher; - - #[bench] - fn alloc_owned_small(b: &mut Bencher) { - b.iter(|| { - box 10 - }) - } - - #[bench] - fn alloc_owned_big(b: &mut Bencher) { - b.iter(|| { - box [10, ..1000] - }) - } -} diff --git a/src/libstd/rt/libc_heap.rs b/src/libstd/rt/libc_heap.rs deleted file mode 100644 index ece51ab9989..00000000000 --- a/src/libstd/rt/libc_heap.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2012 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. - - -//! The global (exchange) heap. - -use libc::{c_void, size_t, free, malloc, realloc}; -use ptr::{RawPtr, mut_null}; -use intrinsics::abort; - -/// A wrapper around libc::malloc, aborting on out-of-memory -#[inline] -pub unsafe fn malloc_raw(size: uint) -> *mut u8 { - // `malloc(0)` may allocate, but it may also return a null pointer - // http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html - if size == 0 { - mut_null() - } else { - let p = malloc(size as size_t); - if p.is_null() { - // we need a non-allocating way to print an error here - abort(); - } - p as *mut u8 - } -} - -/// A wrapper around libc::realloc, aborting on out-of-memory -#[inline] -pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 { - // `realloc(ptr, 0)` may allocate, but it may also return a null pointer - // http://pubs.opengroup.org/onlinepubs/9699919799/functions/realloc.html - if size == 0 { - free(ptr as *mut c_void); - mut_null() - } else { - let p = realloc(ptr as *mut c_void, size as size_t); - if p.is_null() { - // we need a non-allocating way to print an error here - abort(); - } - p as *mut u8 - } -} diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index 5feec7fd9d2..240d137adc6 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -10,6 +10,7 @@ //! The local, garbage collected heap +use alloc::util; use iter::Iterator; use libc::{c_void, free}; use mem; @@ -58,7 +59,7 @@ impl LocalHeap { #[inline] pub fn alloc(&mut self, drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut Box { - let total_size = ::rt::util::get_box_size(size, align); + let total_size = util::get_box_size(size, align); let alloc = self.memory_region.malloc(total_size); { // Make sure that we can't use `mybox` outside of this scope diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index a04cbabedd6..daf18346fee 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -74,6 +74,8 @@ pub use self::unwind::{begin_unwind, begin_unwind_fmt}; pub use self::util::{Stdio, Stdout, Stderr}; +pub use alloc::{heap, libc_heap}; + // FIXME: these probably shouldn't be public... #[doc(hidden)] pub mod shouldnt_be_public { @@ -86,12 +88,6 @@ pub mod shouldnt_be_public { // Internal macros used by the runtime. mod macros; -/// Wrappers around malloc / realloc aborting on out-of-memory. -pub mod libc_heap; - -/// The low-level memory allocation API. -pub mod heap; - /// Implementations of language-critical runtime features like @. pub mod task; diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index 5f9ea14a647..c9e82bd16e5 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -26,23 +26,6 @@ use slice::ImmutableVector; // FIXME: Once the runtime matures remove the `true` below to turn off rtassert, etc. pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert); -#[deprecated] -#[doc(hidden)] -#[inline] -pub fn get_box_size(body_size: uint, body_align: uint) -> uint { - let header_size = ::mem::size_of::<::raw::Box<()>>(); - let total_size = align_to(header_size, body_align) + body_size; - total_size -} - -// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power -// of two. -#[inline] -fn align_to(size: uint, align: uint) -> uint { - assert!(align != 0); - (size + align - 1) & !(align - 1) -} - /// Get the number of cores available pub fn num_cpus() -> uint { unsafe { |
