From 2bc4d3ec23cc88155173729e60df54c8aa4949a6 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 24 Oct 2014 17:34:57 -0400 Subject: [PATCH] get rid of libc_heap::{malloc_raw, realloc_raw} The C standard library functions should be used directly. The quirky NULL / zero-size allocation workaround is no longer necessary and was adding an extra branch to the allocator code path in a build without jemalloc. This is a small step towards liballoc being compatible with handling OOM errors instead of aborting (#18292). [breaking-change] --- src/liballoc/heap.rs | 27 +++++++++++++++++----- src/liballoc/lib.rs | 8 ++----- src/liballoc/libc_heap.rs | 48 --------------------------------------- src/librustrt/c_str.rs | 7 +++--- src/libstd/c_vec.rs | 4 ++-- src/libstd/rt/mod.rs | 2 +- 6 files changed, 30 insertions(+), 66 deletions(-) delete mode 100644 src/liballoc/libc_heap.rs diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 0e5aca18ec7..20569d336a8 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -213,8 +213,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 { @@ -226,7 +226,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, @@ -242,7 +246,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)); @@ -274,7 +282,6 @@ mod imp { mod imp { use libc::{c_void, size_t}; use libc; - use libc_heap; use core::ptr::RawPtr; use super::MIN_ALIGN; @@ -288,7 +295,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() { @@ -301,7 +312,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); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 2df9a585fec..c721649ca9d 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -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] @@ -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 diff --git a/src/liballoc/libc_heap.rs b/src/liballoc/libc_heap.rs deleted file mode 100644 index 4f6400630fd..00000000000 --- a/src/liballoc/libc_heap.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2012-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 or the MIT license -// , 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 core::ptr::{RawPtr, null_mut}; - -/// 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 { - null_mut() - } else { - let p = malloc(size as size_t); - if p.is_null() { - ::oom(); - } - 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); - null_mut() - } else { - let p = realloc(ptr as *mut c_void, size as size_t); - if p.is_null() { - ::oom(); - } - p as *mut u8 - } -} diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 0ef0601828d..6a33777a413 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -71,7 +71,6 @@ fn main() { */ -use alloc::libc_heap::malloc_raw; use collections::string::String; use collections::hash; use core::fmt; @@ -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 } } @@ -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; diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 95f8ab72016..7ec25acb173 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -165,11 +165,11 @@ mod tests { use super::CVec; use libc; use ptr; - use rt::libc_heap::malloc_raw; fn malloc(n: uint) -> CVec { 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); }) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 689bcdad131..a91c6c572e6 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -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};