Skip to content

global allocator improvements #18293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 49 additions & 40 deletions src/liballoc/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
/// 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.
/// create the allocation referenced by `ptr`. The `old_size` parameter may be
/// any value in range_inclusive(requested_size, usable_size).
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8 {
imp::reallocate(ptr, old_size, size, align)
Expand All @@ -38,8 +38,8 @@ pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint)
/// Extends or shrinks the allocation referenced by `ptr` to `size` bytes of
/// memory in-place.
///
/// Returns true if successful, otherwise false if the allocation was not
/// altered.
/// If the operation succeeds, it returns `usable_size(size, align)` and if it
/// fails (or is a no-op) it returns `usable_size(old_size, align)`.
///
/// 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
Expand All @@ -49,20 +49,20 @@ pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint)
/// create the allocation referenced by `ptr`. The `old_size` parameter may be
/// any value in range_inclusive(requested_size, usable_size).
#[inline]
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> bool {
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> uint {
imp::reallocate_inplace(ptr, old_size, size, align)
}

/// Deallocates 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.
/// 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]
pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
imp::deallocate(ptr, size, align)
pub unsafe fn deallocate(ptr: *mut u8, old_size: uint, align: uint) {
imp::deallocate(ptr, old_size, align)
}

/// Returns the usable size of an allocation created with the specified the
Expand Down Expand Up @@ -102,8 +102,8 @@ unsafe fn exchange_malloc(size: uint, align: uint) -> *mut u8 {
#[cfg(not(test))]
#[lang="exchange_free"]
#[inline]
unsafe fn exchange_free(ptr: *mut u8, size: uint, align: uint) {
deallocate(ptr, size, align);
unsafe fn exchange_free(ptr: *mut u8, old_size: uint, align: uint) {
deallocate(ptr, old_size, align);
}

// The minimum alignment guaranteed by the architecture. This value is used to
Expand All @@ -112,10 +112,10 @@ unsafe fn exchange_free(ptr: *mut u8, size: uint, align: uint) {
#[cfg(any(target_arch = "arm",
target_arch = "mips",
target_arch = "mipsel"))]
static MIN_ALIGN: uint = 8;
const MIN_ALIGN: uint = 8;
#[cfg(any(target_arch = "x86",
target_arch = "x86_64"))]
static MIN_ALIGN: uint = 16;
const MIN_ALIGN: uint = 16;

#[cfg(jemalloc)]
mod imp {
Expand Down Expand Up @@ -178,22 +178,16 @@ mod imp {
}

#[inline]
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint,
align: uint) -> bool {
pub unsafe fn reallocate_inplace(ptr: *mut u8, _old_size: uint, size: uint,
align: uint) -> uint {
let flags = align_to_flags(align);
let new_size = je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) as uint;
// checking for failure to shrink is tricky
if size < old_size {
usable_size(size, align) == new_size as uint
} else {
new_size >= size
}
je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) as uint
}

#[inline]
pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, old_size: uint, align: uint) {
let flags = align_to_flags(align);
je_sdallocx(ptr as *mut c_void, size as size_t, flags)
je_sdallocx(ptr as *mut c_void, old_size as size_t, flags)
}

#[inline]
Expand All @@ -213,8 +207,8 @@ mod imp {
mod imp {
use core::cmp;
use core::ptr;
use core::ptr::RawPtr;
use libc;
use libc_heap;
use super::MIN_ALIGN;

extern {
Expand All @@ -226,7 +220,11 @@ mod imp {
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
if align <= MIN_ALIGN {
libc_heap::malloc_raw(size)
let ptr = libc::malloc(size as libc::size_t);
if ptr.is_null() {
::oom();
}
ptr as *mut u8
} else {
let mut out = 0 as *mut libc::c_void;
let ret = posix_memalign(&mut out,
Expand All @@ -242,7 +240,11 @@ mod imp {
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8 {
if align <= MIN_ALIGN {
libc_heap::realloc_raw(ptr, size)
let ptr = libc::realloc(ptr as *mut libc::c_void, size as libc::size_t);
if ptr.is_null() {
::oom();
}
ptr as *mut u8
} else {
let new_ptr = allocate(size, align);
ptr::copy_memory(new_ptr, ptr as *const u8, cmp::min(size, old_size));
Expand All @@ -252,13 +254,13 @@ mod imp {
}

#[inline]
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: uint, size: uint,
_align: uint) -> bool {
size == old_size
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: uint, _size: uint,
_align: uint) -> uint {
old_size
}

#[inline]
pub unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, _old_size: uint, _align: uint) {
libc::free(ptr as *mut libc::c_void)
}

Expand All @@ -274,7 +276,6 @@ mod imp {
mod imp {
use libc::{c_void, size_t};
use libc;
use libc_heap;
use core::ptr::RawPtr;
use super::MIN_ALIGN;

Expand All @@ -288,7 +289,11 @@ mod imp {
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
if align <= MIN_ALIGN {
libc_heap::malloc_raw(size)
let ptr = libc::malloc(size as size_t);
if ptr.is_null() {
::oom();
}
ptr as *mut u8
} else {
let ptr = _aligned_malloc(size as size_t, align as size_t);
if ptr.is_null() {
Expand All @@ -301,7 +306,11 @@ mod imp {
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, _old_size: uint, size: uint, align: uint) -> *mut u8 {
if align <= MIN_ALIGN {
libc_heap::realloc_raw(ptr, size)
let ptr = libc::realloc(ptr as *mut c_void, size as size_t);
if ptr.is_null() {
::oom();
}
ptr as *mut u8
} else {
let ptr = _aligned_realloc(ptr as *mut c_void, size as size_t,
align as size_t);
Expand All @@ -313,13 +322,13 @@ mod imp {
}

#[inline]
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: uint, size: uint,
_align: uint) -> bool {
size == old_size
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: uint, _size: uint,
_align: uint) -> uint {
old_size
}

#[inline]
pub unsafe fn deallocate(ptr: *mut u8, _size: uint, align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, _old_size: uint, align: uint) {
if align <= MIN_ALIGN {
libc::free(ptr as *mut libc::c_void)
} else {
Expand Down Expand Up @@ -348,7 +357,7 @@ mod test {
let ptr = heap::allocate(size, 8);
let ret = heap::reallocate_inplace(ptr, size, size, 8);
heap::deallocate(ptr, size, 8);
assert!(ret);
assert_eq!(ret, heap::usable_size(size, 8));
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,8 @@
//!
//! ## Heap interfaces
//!
//! The [`heap`](heap/index.html) and [`libc_heap`](libc_heap/index.html)
//! modules are the unsafe interfaces to the underlying allocation systems. The
//! `heap` module is considered the default heap, and is not necessarily backed
//! by libc malloc/free. The `libc_heap` module is defined to be wired up to
//! the system malloc/free.
//! The [`heap`](heap/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.

#![crate_name = "alloc"]
#![experimental]
Expand Down Expand Up @@ -90,7 +87,6 @@ pub use boxed as owned;
// Heaps provided for low-level allocation strategies

pub mod heap;
pub mod libc_heap;

// Primitive types using the heaps above

Expand Down
48 changes: 0 additions & 48 deletions src/liballoc/libc_heap.rs

This file was deleted.

7 changes: 4 additions & 3 deletions src/librustrt/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ fn main() {

*/

use alloc::libc_heap::malloc_raw;
use collections::string::String;
use collections::hash;
use core::fmt;
Expand Down Expand Up @@ -101,7 +100,8 @@ impl Clone for CString {
/// with C's allocator API, rather than the usual shallow clone.
fn clone(&self) -> CString {
let len = self.len() + 1;
let buf = unsafe { malloc_raw(len) } as *mut libc::c_char;
let buf = unsafe { libc::malloc(len as libc::size_t) } as *mut libc::c_char;
if buf.is_null() { fail!("out of memory") }
unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
CString { buf: buf as *const libc::c_char, owns_buffer_: true }
}
Expand Down Expand Up @@ -393,7 +393,8 @@ impl<'a> ToCStr for &'a [u8] {

unsafe fn to_c_str_unchecked(&self) -> CString {
let self_len = self.len();
let buf = malloc_raw(self_len + 1);
let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
if buf.is_null() { fail!("out of memory") }

ptr::copy_memory(buf, self.as_ptr(), self_len);
*buf.offset(self_len as int) = 0;
Expand Down
6 changes: 3 additions & 3 deletions src/librustrt/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ mod imp {

#[cfg(windows)]
mod imp {
use alloc::libc_heap::malloc_raw;
use alloc::heap;
use core::atomic;
use core::ptr;
use libc::{HANDLE, BOOL, LPSECURITY_ATTRIBUTES, c_void, DWORD, LPCSTR};
Expand Down Expand Up @@ -607,7 +607,7 @@ mod imp {
}

pub unsafe fn init_lock() -> uint {
let block = malloc_raw(CRIT_SECTION_SIZE as uint) as *mut c_void;
let block = heap::allocate(CRIT_SECTION_SIZE, 8) as *mut c_void;
InitializeCriticalSectionAndSpinCount(block, SPIN_COUNT);
return block as uint;
}
Expand All @@ -619,7 +619,7 @@ mod imp {

pub unsafe fn free_lock(h: uint) {
DeleteCriticalSection(h as LPCRITICAL_SECTION);
libc::free(h as *mut c_void);
heap::deallocate(h as *mut u8, CRIT_SECTION_SIZE, 8);
}

pub unsafe fn free_cond(h: uint) {
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/c_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ mod tests {
use super::CVec;
use libc;
use ptr;
use rt::libc_heap::malloc_raw;

fn malloc(n: uint) -> CVec<u8> {
unsafe {
let mem = malloc_raw(n);
let mem = libc::malloc(n as libc::size_t);
if mem.is_null() { fail!("out of memory") }

CVec::new_with_dtor(mem as *mut u8, n,
proc() { libc::free(mem as *mut libc::c_void); })
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};

// Reexport functionality from librustrt and other crates underneath the
// standard library which work together to create the entire runtime.
pub use alloc::{heap, libc_heap};
pub use alloc::heap;
pub use rustrt::{task, local, mutex, exclusive, stack, args, rtio, thread};
pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt};
pub use rustrt::{bookkeeping, at_exit, unwind, DEFAULT_ERROR_CODE, Runtime};
Expand Down