Skip to content

Rollup of 9 pull requests #36627

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

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
82639d4
fix top level attr spans
mikhail-m1 Sep 16, 2016
af67f0b
Fix name of error test file
aclarry Sep 6, 2016
313fb8f
Replace 'e.g.' by 'i.e.'
GuillaumeGomez Sep 19, 2016
2ea3ab3
Add the ability to merge spans to codemap
Sep 19, 2016
8b02aa1
fixed the safety header/wording in option.rs
Sep 19, 2016
80a4477
Lazily allocate TypedArena's first chunk.
nnethercote Sep 19, 2016
c41a806
Workaround #34427 by using memset of 0 on ARM to set the discriminant.
pnkfelix Sep 15, 2016
429ba7b
Minor correction in `sort_by_key` doc comment
caipre Sep 20, 2016
23efc54
Update E0560 to include label
aclarry Sep 16, 2016
e4b1842
Check for overlapping and simplify unit test
Sep 20, 2016
854ae8f
Fix some typos and improve doc comments style
GuillaumeGomez Sep 21, 2016
e632a1a
Rollup merge of #36330 - aclarry:e0560-update, r=jonathandturner
Sep 21, 2016
fe88e1b
Rollup merge of #36496 - pnkfelix:workaround-issue-34427, r=eddyb
Sep 21, 2016
3f48843
Rollup merge of #36539 - mikhail-m1:36530, r=jonathandturner
Sep 21, 2016
d75b696
Rollup merge of #36578 - GuillaumeGomez:fix_typo, r=steveklabnik
Sep 21, 2016
3c2558a
Rollup merge of #36585 - jonathandturner:misc_error_touchups, r=nrc
Sep 21, 2016
5cd252c
Rollup merge of #36589 - jpadkins:option_docs_safety_wording_fix, r=b…
Sep 21, 2016
846ff6d
Rollup merge of #36592 - nnethercote:TypedArena, r=bluss
Sep 21, 2016
5a6abc9
Rollup merge of #36600 - caipre:sort-by-key-comment-fix, r=apasel422
Sep 21, 2016
708bfe0
Rollup merge of #36623 - GuillaumeGomez:doc_typos, r=steveklabnik
Sep 21, 2016
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
93 changes: 55 additions & 38 deletions src/libarena/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
//! of individual objects while the arena itself is still alive. The benefit
//! of an arena is very fast allocation; just a pointer bump.
//!
//! This crate has two arenas implemented: `TypedArena`, which is a simpler
//! arena but can only hold objects of a single type, and `Arena`, which is a
//! more complex, slower arena which can hold objects of any type.
//! This crate implements `TypedArena`, a simple arena that can only hold
//! objects of a single type.

#![crate_name = "arena"]
#![unstable(feature = "rustc_private", issue = "27812")]
Expand Down Expand Up @@ -51,16 +50,19 @@ use std::ptr;
use alloc::heap;
use alloc::raw_vec::RawVec;

/// A faster arena that can hold objects of only one type.
/// An arena that can hold objects of only one type.
pub struct TypedArena<T> {
/// The capacity of the first chunk (once it is allocated).
first_chunk_capacity: usize,

/// A pointer to the next object to be allocated.
ptr: Cell<*mut T>,

/// A pointer to the end of the allocated area. When this pointer is
/// reached, a new chunk is allocated.
end: Cell<*mut T>,

/// A vector arena segments.
/// A vector of arena chunks.
chunks: RefCell<Vec<TypedArenaChunk<T>>>,

/// Marker indicating that dropping the arena causes its owned
Expand All @@ -69,7 +71,7 @@ pub struct TypedArena<T> {
}

struct TypedArenaChunk<T> {
/// Pointer to the next arena segment.
/// The raw storage for the arena chunk.
storage: RawVec<T>,
}

Expand Down Expand Up @@ -117,26 +119,26 @@ impl<T> TypedArenaChunk<T> {
const PAGE: usize = 4096;

impl<T> TypedArena<T> {
/// Creates a new `TypedArena` with preallocated space for many objects.
/// Creates a new `TypedArena`.
#[inline]
pub fn new() -> TypedArena<T> {
// Reserve at least one page.
let elem_size = cmp::max(1, mem::size_of::<T>());
TypedArena::with_capacity(PAGE / elem_size)
}

/// Creates a new `TypedArena` with preallocated space for the given number of
/// objects.
/// Creates a new `TypedArena`. Each chunk used within the arena will have
/// space for at least the given number of objects.
#[inline]
pub fn with_capacity(capacity: usize) -> TypedArena<T> {
unsafe {
let chunk = TypedArenaChunk::<T>::new(cmp::max(1, capacity));
TypedArena {
ptr: Cell::new(chunk.start()),
end: Cell::new(chunk.end()),
chunks: RefCell::new(vec![chunk]),
_own: PhantomData,
}
TypedArena {
first_chunk_capacity: cmp::max(1, capacity),
// We set both `ptr` and `end` to 0 so that the first call to
// alloc() will trigger a grow().
ptr: Cell::new(0 as *mut T),
end: Cell::new(0 as *mut T),
chunks: RefCell::new(vec![]),
_own: PhantomData,
}
}

Expand Down Expand Up @@ -171,29 +173,37 @@ impl<T> TypedArena<T> {
fn grow(&self) {
unsafe {
let mut chunks = self.chunks.borrow_mut();
let prev_capacity = chunks.last().unwrap().storage.cap();
let new_capacity = prev_capacity.checked_mul(2).unwrap();
if chunks.last_mut().unwrap().storage.double_in_place() {
self.end.set(chunks.last().unwrap().end());
let (chunk, new_capacity);
if let Some(last_chunk) = chunks.last_mut() {
if last_chunk.storage.double_in_place() {
self.end.set(last_chunk.end());
return;
} else {
let prev_capacity = last_chunk.storage.cap();
new_capacity = prev_capacity.checked_mul(2).unwrap();
}
} else {
let chunk = TypedArenaChunk::<T>::new(new_capacity);
self.ptr.set(chunk.start());
self.end.set(chunk.end());
chunks.push(chunk);
new_capacity = self.first_chunk_capacity;
}
chunk = TypedArenaChunk::<T>::new(new_capacity);
self.ptr.set(chunk.start());
self.end.set(chunk.end());
chunks.push(chunk);
}
}
/// Clears the arena. Deallocates all but the longest chunk which may be reused.
pub fn clear(&mut self) {
unsafe {
// Clear the last chunk, which is partially filled.
let mut chunks_borrow = self.chunks.borrow_mut();
let last_idx = chunks_borrow.len() - 1;
self.clear_last_chunk(&mut chunks_borrow[last_idx]);
// If `T` is ZST, code below has no effect.
for mut chunk in chunks_borrow.drain(..last_idx) {
let cap = chunk.storage.cap();
chunk.destroy(cap);
if let Some(mut last_chunk) = chunks_borrow.pop() {
self.clear_last_chunk(&mut last_chunk);
// If `T` is ZST, code below has no effect.
for mut chunk in chunks_borrow.drain(..) {
let cap = chunk.storage.cap();
chunk.destroy(cap);
}
chunks_borrow.push(last_chunk);
}
}
}
Expand Down Expand Up @@ -230,13 +240,14 @@ impl<T> Drop for TypedArena<T> {
unsafe {
// Determine how much was filled.
let mut chunks_borrow = self.chunks.borrow_mut();
let mut last_chunk = chunks_borrow.pop().unwrap();
// Drop the contents of the last chunk.
self.clear_last_chunk(&mut last_chunk);
// The last chunk will be dropped. Destroy all other chunks.
for chunk in chunks_borrow.iter_mut() {
let cap = chunk.storage.cap();
chunk.destroy(cap);
if let Some(mut last_chunk) = chunks_borrow.pop() {
// Drop the contents of the last chunk.
self.clear_last_chunk(&mut last_chunk);
// The last chunk will be dropped. Destroy all other chunks.
for chunk in chunks_borrow.iter_mut() {
let cap = chunk.storage.cap();
chunk.destroy(cap);
}
}
// RawVec handles deallocation of `last_chunk` and `self.chunks`.
}
Expand All @@ -260,6 +271,12 @@ mod tests {
z: i32,
}

#[test]
pub fn test_unused() {
let arena: TypedArena<Point> = TypedArena::new();
assert!(arena.chunks.borrow().is_empty());
}

#[test]
fn test_arena_alloc_nested() {
struct Inner {
Expand Down
50 changes: 26 additions & 24 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl<T> [T] {
core_slice::SliceExt::len(self)
}

/// Returns true if the slice has a length of 0
/// Returns true if the slice has a length of 0.
///
/// # Example
///
Expand Down Expand Up @@ -402,7 +402,7 @@ impl<T> [T] {
core_slice::SliceExt::get_unchecked_mut(self, index)
}

/// Returns an raw pointer to the slice's buffer
/// Returns an raw pointer to the slice's buffer.
///
/// The caller must ensure that the slice outlives the pointer this
/// function returns, or else it will end up pointing to garbage.
Expand Down Expand Up @@ -468,7 +468,7 @@ impl<T> [T] {
///
/// # Examples
///
/// ```rust
/// ```
/// let mut v = ["a", "b", "c", "d"];
/// v.swap(1, 3);
/// assert!(v == ["a", "d", "c", "b"]);
Expand All @@ -483,7 +483,7 @@ impl<T> [T] {
///
/// # Example
///
/// ```rust
/// ```
/// let mut v = [1, 2, 3];
/// v.reverse();
/// assert!(v == [3, 2, 1]);
Expand Down Expand Up @@ -567,9 +567,9 @@ impl<T> [T] {
}

/// Returns an iterator over `size` elements of the slice at a
/// time. The chunks are slices and do not overlap. If `size` does not divide the
/// length of the slice, then the last chunk will not have length
/// `size`.
/// time. The chunks are slices and do not overlap. If `size` does
/// not divide the length of the slice, then the last chunk will
/// not have length `size`.
///
/// # Panics
///
Expand Down Expand Up @@ -656,7 +656,7 @@ impl<T> [T] {
///
/// # Examples
///
/// ```rust
/// ```
/// let mut v = [1, 2, 3, 4, 5, 6];
///
/// // scoped to restrict the lifetime of the borrows
Expand Down Expand Up @@ -754,7 +754,7 @@ impl<T> [T] {
}

/// Returns an iterator over subslices separated by elements that match
/// `pred`, limited to returning at most `n` items. The matched element is
/// `pred`, limited to returning at most `n` items. The matched element is
/// not contained in the subslices.
///
/// The last element returned, if any, will contain the remainder of the
Expand All @@ -781,7 +781,7 @@ impl<T> [T] {
}

/// Returns an iterator over subslices separated by elements that match
/// `pred`, limited to returning at most `n` items. The matched element is
/// `pred`, limited to returning at most `n` items. The matched element is
/// not contained in the subslices.
///
/// The last element returned, if any, will contain the remainder of the
Expand Down Expand Up @@ -835,7 +835,7 @@ impl<T> [T] {

/// Returns an iterator over subslices separated by elements that match
/// `pred` limited to returning at most `n` items. This starts at the end of
/// the slice and works backwards. The matched element is not contained in
/// the slice and works backwards. The matched element is not contained in
/// the subslices.
///
/// The last element returned, if any, will contain the remainder of the
Expand Down Expand Up @@ -922,9 +922,9 @@ impl<T> [T] {
///
/// Looks up a series of four elements. The first is found, with a
/// uniquely determined position; the second and third are not
/// found; the fourth could match any position in `[1,4]`.
/// found; the fourth could match any position in `[1, 4]`.
///
/// ```rust
/// ```
/// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
///
/// assert_eq!(s.binary_search(&13), Ok(9));
Expand Down Expand Up @@ -956,9 +956,9 @@ impl<T> [T] {
///
/// Looks up a series of four elements. The first is found, with a
/// uniquely determined position; the second and third are not
/// found; the fourth could match any position in `[1,4]`.
/// found; the fourth could match any position in `[1, 4]`.
///
/// ```rust
/// ```
/// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
///
/// let seek = 13;
Expand All @@ -982,21 +982,23 @@ impl<T> [T] {
/// Binary search a sorted slice with a key extraction function.
///
/// Assumes that the slice is sorted by the key, for instance with
/// `sort_by_key` using the same key extraction function.
/// [`sort_by_key`] using the same key extraction function.
///
/// If a matching value is found then returns `Ok`, containing the
/// index for the matched element; if no match is found then `Err`
/// is returned, containing the index where a matching element could
/// be inserted while maintaining sorted order.
///
/// [`sort_by_key`]: primitive.slice.html#method.sort_by_key
///
/// # Examples
///
/// Looks up a series of four elements in a slice of pairs sorted by
/// their second elements. The first is found, with a uniquely
/// determined position; the second and third are not found; the
/// fourth could match any position in `[1,4]`.
/// fourth could match any position in `[1, 4]`.
///
/// ```rust
/// ```
/// let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
/// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
/// (1, 21), (2, 34), (4, 55)];
Expand All @@ -1023,7 +1025,7 @@ impl<T> [T] {
///
/// # Examples
///
/// ```rust
/// ```
/// let mut v = [-5, 4, 1, -3, 2];
///
/// v.sort();
Expand All @@ -1037,15 +1039,15 @@ impl<T> [T] {
self.sort_by(|a, b| a.cmp(b))
}

/// Sorts the slice, in place, using `key` to extract a key by which to
/// Sorts the slice, in place, using `f` to extract a key by which to
/// order the sort by.
///
/// This sort is stable and `O(n log n)` worst-case but allocates
/// approximately `2 * n`, where `n` is the length of `self`.
///
/// # Examples
///
/// ```rust
/// ```
/// let mut v = [-5i32, 4, 1, -3, 2];
///
/// v.sort_by_key(|k| k.abs());
Expand All @@ -1067,7 +1069,7 @@ impl<T> [T] {
///
/// # Examples
///
/// ```rust
/// ```
/// let mut v = [5, 4, 1, 3, 2];
/// v.sort_by(|a, b| a.cmp(b));
/// assert!(v == [1, 2, 3, 4, 5]);
Expand All @@ -1094,7 +1096,7 @@ impl<T> [T] {
///
/// # Example
///
/// ```rust
/// ```
/// let mut dst = [0, 0, 0];
/// let src = [1, 2, 3];
///
Expand All @@ -1116,7 +1118,7 @@ impl<T> [T] {
///
/// # Example
///
/// ```rust
/// ```
/// let mut dst = [0, 0, 0];
/// let src = [1, 2, 3];
///
Expand Down
4 changes: 2 additions & 2 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ impl str {
///
/// Basic usage:
///
/// ```rust
/// ```
/// let bananas = "bananas";
///
/// assert!(bananas.ends_with("anas"));
Expand Down Expand Up @@ -900,7 +900,7 @@ impl str {
///
/// It does _not_ give you:
///
/// ```rust,ignore
/// ```,ignore
/// assert_eq!(d, &["a", "b", "c"]);
/// ```
///
Expand Down
Loading