diff --git a/mk/crates.mk b/mk/crates.mk index 4ac4abe9063..a0a0bc800c4 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -51,14 +51,15 @@ TARGET_CRATES := libc std green rustuv native flate arena glob term semver \ uuid serialize sync getopts collections num test time rand \ - workcache url log regex graphviz core rlibc + workcache url log regex graphviz core rlibc alloc HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros CRATES := $(TARGET_CRATES) $(HOST_CRATES) TOOLS := compiletest rustdoc rustc DEPS_core := DEPS_rlibc := -DEPS_std := core libc native:rustrt native:compiler-rt native:backtrace native:jemalloc +DEPS_alloc := core libc native:jemalloc +DEPS_std := core libc alloc native:rustrt native:backtrace DEPS_graphviz := std DEPS_green := std rand native:context_switch DEPS_rustuv := std native:uv native:uv_support @@ -76,7 +77,7 @@ DEPS_serialize := std collections log DEPS_term := std collections log DEPS_semver := std DEPS_uuid := std serialize rand -DEPS_sync := std +DEPS_sync := std alloc DEPS_getopts := std DEPS_collections := std rand DEPS_fourcc := syntax std @@ -101,6 +102,7 @@ TOOL_SOURCE_rustc := $(S)src/driver/driver.rs ONLY_RLIB_core := 1 ONLY_RLIB_rlibc := 1 +ONLY_RLIB_alloc := 1 ################################################################################ # You should not need to edit below this line diff --git a/src/libsync/arc.rs b/src/liballoc/arc.rs similarity index 96% rename from src/libsync/arc.rs rename to src/liballoc/arc.rs index 26d7e04fe1d..1ad79072e75 100644 --- a/src/libsync/arc.rs +++ b/src/liballoc/arc.rs @@ -13,11 +13,16 @@ * between tasks. */ -use std::mem; -use std::ptr; -use std::rt::heap::deallocate; -use std::sync::atomics; -use std::mem::{min_align_of, size_of}; +use core::atomics; +use core::clone::Clone; +use core::kinds::{Share, Send}; +use core::mem::{min_align_of, size_of, drop}; +use core::mem; +use core::ops::{Drop, Deref}; +use core::option::{Some, None, Option}; +use core::ptr; +use core::ptr::RawPtr; +use heap::deallocate; /// An atomically reference counted wrapper for shared state. /// @@ -28,6 +33,8 @@ use std::mem::{min_align_of, size_of}; /// task. /// /// ```rust +/// extern crate sync; +/// /// use sync::Arc; /// /// fn main() { @@ -251,10 +258,16 @@ impl Drop for Weak { #[cfg(test)] #[allow(experimental)] mod tests { - use super::{Arc, Weak}; + use std::clone::Clone; + use std::comm::channel; + use std::mem::drop; + use std::ops::{Drop, Deref, DerefMut}; + use std::option::{Option, Some, None}; use std::sync::atomics; use std::task; - use Mutex; + use std::vec::Vec; + use super::{Arc, Weak}; + use sync::Mutex; struct Canary(*mut atomics::AtomicUint); diff --git a/src/libstd/rt/heap.rs b/src/liballoc/heap.rs similarity index 95% rename from src/libstd/rt/heap.rs rename to src/liballoc/heap.rs index e616b9b8beb..69cd82a981a 100644 --- a/src/libstd/rt/heap.rs +++ b/src/liballoc/heap.rs @@ -11,10 +11,13 @@ // 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 core::intrinsics::{abort, cttz32}; +use core::option::{None, Option}; +use core::ptr::{RawPtr, mut_null, null}; use libc::{c_char, c_int, c_void, size_t}; -use ptr::{RawPtr, mut_null, null}; -use option::{None, Option}; + +#[cfg(not(test))] use core::raw; +#[cfg(not(test))] use util; #[link(name = "jemalloc", kind = "static")] extern { @@ -148,11 +151,12 @@ unsafe fn exchange_free(ptr: *mut u8) { #[cfg(not(test))] #[lang="closure_exchange_malloc"] #[inline] +#[allow(deprecated)] 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 total_size = util::get_box_size(size, align); let p = allocate(total_size, 8); - let alloc = p as *mut ::raw::Box<()>; + let alloc = p as *mut raw::Box<()>; (*alloc).drop_glue = drop_glue; alloc as *mut u8 diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs new file mode 100644 index 00000000000..1a6d7bfaed0 --- /dev/null +++ b/src/liballoc/lib.rs @@ -0,0 +1,101 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Rust's core allocation library +//! +//! This is the lowest level library through which allocation in Rust can be +//! performed where the allocation is assumed to succeed. This library will +//! trigger a task failure when allocation fails. +//! +//! This library, like libcore, is not intended for general usage, but rather as +//! a building block of other libraries. The types and interfaces in this +//! library are reexported through the [standard library](../std/index.html), +//! and should not be used through this library. +//! +//! Currently, there are four major definitions in this library. +//! +//! ## Owned pointers +//! +//! The [`Box`](owned/index.html) type is the core owned pointer type in rust. +//! There can only be one owner of a `Box`, and the owner can decide to mutate +//! the contents. +//! +//! This type can be sent among tasks efficiently as the size of a `Box` value +//! is just a pointer. Tree-like data structures are often built on owned +//! pointers because each node often has only one owner, the parent. +//! +//! ## Reference counted pointers +//! +//! The [`Rc`](rc/index.html) type is a non-threadsafe reference-counted pointer +//! type intended for sharing memory within a task. An `Rc` pointer wraps a +//! type, `T`, and only allows access to `&T`, a shared reference. +//! +//! This type is useful when inherited mutability is too constraining for an +//! application (such as using `Box`), and is often paired with the `Cell` or +//! `RefCell` types in order to allow mutation. +//! +//! ## Atomically reference counted pointers +//! +//! The [`Arc`](arc/index.html) type is the threadsafe equivalent of the `Rc` +//! type. It provides all the same functionality of `Rc`, except it requires +//! that the contained type `T` is shareable. Additionally, `Arc` is itself +//! sendable while `Rc` is not. +//! +//! This types allows for shared access to the contained data, and is often +//! paired with synchronization primitives such as mutexes to allow mutation of +//! shared resources. +//! +//! ## 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. + +#![crate_id = "alloc#0.11.0-pre"] +#![license = "MIT/ASL2"] +#![crate_type = "rlib"] +#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://static.rust-lang.org/doc/master")] + +#![no_std] +#![feature(phase)] + +#[phase(syntax, link)] +extern crate core; +extern crate libc; + +// Allow testing this library + +#[cfg(test)] extern crate sync; +#[cfg(test)] extern crate native; +#[cfg(test)] #[phase(syntax, link)] extern crate std; +#[cfg(test)] #[phase(syntax, link)] extern crate log; + +// Heaps provided for low-level allocation strategies + +pub mod heap; +pub mod libc_heap; +pub mod util; + +// Primitive types using the heaps above + +#[cfg(not(test))] +pub mod owned; +pub mod arc; +pub mod rc; + +#[cfg(not(test))] +mod std { + pub use core::fmt; + pub use core::option; +} diff --git a/src/libstd/rt/libc_heap.rs b/src/liballoc/libc_heap.rs similarity index 96% rename from src/libstd/rt/libc_heap.rs rename to src/liballoc/libc_heap.rs index ece51ab9989..5b189bc672e 100644 --- a/src/libstd/rt/libc_heap.rs +++ b/src/liballoc/libc_heap.rs @@ -12,8 +12,8 @@ //! The global (exchange) heap. use libc::{c_void, size_t, free, malloc, realloc}; -use ptr::{RawPtr, mut_null}; -use intrinsics::abort; +use core::ptr::{RawPtr, mut_null}; +use core::intrinsics::abort; /// A wrapper around libc::malloc, aborting on out-of-memory #[inline] diff --git a/src/libstd/owned.rs b/src/liballoc/owned.rs similarity index 91% rename from src/libstd/owned.rs rename to src/liballoc/owned.rs index bd6684b3905..30e0fe6c4dd 100644 --- a/src/libstd/owned.rs +++ b/src/liballoc/owned.rs @@ -8,17 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Operations on unique pointer types +//! A unique pointer type -use any::{Any, AnyRefExt}; -use clone::Clone; -use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering}; -use default::Default; -use fmt; -use intrinsics; -use mem; -use raw::TraitObject; -use result::{Ok, Err, Result}; +use core::any::{Any, AnyRefExt}; +use core::clone::Clone; +use core::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering}; +use core::default::Default; +use core::fmt; +use core::intrinsics; +use core::mem; +use core::raw::TraitObject; +use core::result::{Ok, Err, Result}; /// A value that represents the global exchange heap. This is the default /// place that the `box` keyword allocates into when no place is supplied. diff --git a/src/libstd/rc.rs b/src/liballoc/rc.rs similarity index 93% rename from src/libstd/rc.rs rename to src/liballoc/rc.rs index 87c2f826af5..5a877d9362e 100644 --- a/src/libstd/rc.rs +++ b/src/liballoc/rc.rs @@ -23,17 +23,18 @@ pointers, and then storing the parent pointers as `Weak` pointers. */ -use mem::transmute; -use cell::Cell; -use clone::Clone; -use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering}; -use kinds::marker; -use ops::{Deref, Drop}; -use option::{Option, Some, None}; -use ptr; -use ptr::RawPtr; -use mem::{min_align_of, size_of}; -use rt::heap::deallocate; +use core::mem::transmute; +use core::cell::Cell; +use core::clone::Clone; +use core::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering}; +use core::kinds::marker; +use core::ops::{Deref, Drop}; +use core::option::{Option, Some, None}; +use core::ptr; +use core::ptr::RawPtr; +use core::mem::{min_align_of, size_of}; + +use heap::deallocate; struct RcBox { value: T, @@ -230,9 +231,11 @@ impl RcBoxPtr for Weak { #[cfg(test)] mod tests { - use prelude::*; - use super::*; - use cell::RefCell; + use super::{Rc, Weak}; + use std::cell::RefCell; + use std::option::{Option, Some, None}; + use std::mem::drop; + use std::clone::Clone; #[test] fn test_clone() { @@ -280,7 +283,7 @@ mod tests { #[test] fn gc_inside() { // see issue #11532 - use gc::Gc; + use std::gc::Gc; let a = Rc::new(RefCell::new(Gc::new(1))); assert!(a.try_borrow_mut().is_some()); } diff --git a/src/liballoc/util.rs b/src/liballoc/util.rs new file mode 100644 index 00000000000..7e35af79eab --- /dev/null +++ b/src/liballoc/util.rs @@ -0,0 +1,30 @@ +// Copyright 2013 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. + +#![doc(hidden)] + +use core::mem; +use core::raw; + +#[inline] +#[deprecated] +pub fn get_box_size(body_size: uint, body_align: uint) -> uint { + let header_size = mem::size_of::>(); + let total_size = align_to(header_size, body_align) + body_size; + total_size +} + +// Rounds size to the next alignment. Alignment is required to be a power of +// two. +#[inline] +fn align_to(size: uint, align: uint) -> uint { + assert!(align != 0); + (size + align - 1) & !(align - 1) +} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 119cd9aa2ca..a45f8a83a24 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -124,21 +124,21 @@ // Make and rand accessible for benchmarking/testcases #[cfg(test)] extern crate rand; -extern crate libc; +extern crate alloc; extern crate core; +extern crate libc; // Make std testable by not duplicating lang items. See #2912 #[cfg(test)] extern crate realstd = "std"; -#[cfg(test)] pub use kinds = realstd::kinds; -#[cfg(test)] pub use ops = realstd::ops; -#[cfg(test)] pub use cmp = realstd::cmp; -#[cfg(test)] pub use ty = realstd::ty; -#[cfg(test)] pub use owned = realstd::owned; +#[cfg(test)] pub use realstd::kinds; +#[cfg(test)] pub use realstd::ops; +#[cfg(test)] pub use realstd::cmp; +#[cfg(test)] pub use realstd::ty; -#[cfg(not(test))] pub use cmp = core::cmp; -#[cfg(not(test))] pub use kinds = core::kinds; -#[cfg(not(test))] pub use ops = core::ops; -#[cfg(not(test))] pub use ty = core::ty; +#[cfg(not(test))] pub use core::cmp; +#[cfg(not(test))] pub use core::kinds; +#[cfg(not(test))] pub use core::ops; +#[cfg(not(test))] pub use core::ty; pub use core::any; pub use core::bool; @@ -155,6 +155,9 @@ pub use core::raw; pub use core::tuple; pub use core::result; +pub use alloc::owned; +pub use alloc::rc; + // Run tests with libgreen instead of libnative. // // FIXME: This egregiously hacks around starting the test runner in a different @@ -205,10 +208,7 @@ pub mod strbuf; pub mod ascii; -pub mod rc; pub mod gc; -#[cfg(not(test))] -pub mod owned; /* Common traits */ 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 { diff --git a/src/libsync/lib.rs b/src/libsync/lib.rs index e5d506301e3..3396425928e 100644 --- a/src/libsync/lib.rs +++ b/src/libsync/lib.rs @@ -27,17 +27,18 @@ #[cfg(test)] #[phase(syntax, link)] extern crate log; +extern crate alloc; + pub use comm::{DuplexStream, duplex}; pub use task_pool::TaskPool; pub use future::Future; -pub use arc::{Arc, Weak}; +pub use alloc::arc::{Arc, Weak}; pub use lock::{Mutex, MutexGuard, Condvar, Barrier, RWLock, RWLockReadGuard, RWLockWriteGuard}; // The mutex/rwlock in this module are not meant for reexport pub use raw::{Semaphore, SemaphoreGuard}; -mod arc; mod comm; mod future; mod lock; diff --git a/src/libsync/lock.rs b/src/libsync/lock.rs index 930b3009042..9f59f587770 100644 --- a/src/libsync/lock.rs +++ b/src/libsync/lock.rs @@ -447,7 +447,7 @@ mod tests { use std::task; use std::task::TaskBuilder; - use arc::Arc; + use Arc; use super::{Mutex, Barrier, RWLock}; #[test] diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs index 990aba3ebff..591318d24b2 100644 --- a/src/libsync/raw.rs +++ b/src/libsync/raw.rs @@ -622,7 +622,7 @@ impl<'a> Drop for RWLockReadGuard<'a> { #[cfg(test)] mod tests { - use arc::Arc; + use Arc; use super::{Semaphore, Mutex, RWLock, Condvar}; use std::mem; diff --git a/src/test/compile-fail/no_send-rc.rs b/src/test/compile-fail/no_send-rc.rs index 20f1cbc47bc..bf79d1393b8 100644 --- a/src/test/compile-fail/no_send-rc.rs +++ b/src/test/compile-fail/no_send-rc.rs @@ -15,6 +15,6 @@ fn bar(_: T) {} fn main() { let x = Rc::new(5); bar(x); - //~^ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc`, + //~^ ERROR instantiating a type parameter with an incompatible type `alloc::rc::Rc`, // which does not fulfill `Send` }