Skip to content

Commit 91fa8e5

Browse files
committed
arena: add docs for Arena
1 parent 30250d3 commit 91fa8e5

File tree

1 file changed

+34
-28
lines changed

1 file changed

+34
-28
lines changed

src/libarena/lib.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
//! once, once the arena itself is destroyed. They do not support deallocation
1515
//! of individual objects while the arena itself is still alive. The benefit
1616
//! of an arena is very fast allocation; just a pointer bump.
17+
//!
18+
//! This crate has two arenas implemented: TypedArena, which is a simpler
19+
//! arena but can only hold objects of a single type, and Arena, which is a
20+
//! more complex, slower Arena which can hold objects of any type.
1721
1822
#![crate_id = "arena#0.11.0-pre"]
1923
#![crate_type = "rlib"]
@@ -56,41 +60,42 @@ impl Chunk {
5660
}
5761
}
5862

59-
// Arenas are used to quickly allocate objects that share a
60-
// lifetime. The arena uses ~[u8] vectors as a backing store to
61-
// allocate objects from. For each allocated object, the arena stores
62-
// a pointer to the type descriptor followed by the
63-
// object. (Potentially with alignment padding after each of them.)
64-
// When the arena is destroyed, it iterates through all of its chunks,
65-
// and uses the tydesc information to trace through the objects,
66-
// calling the destructors on them.
67-
// One subtle point that needs to be addressed is how to handle
68-
// failures while running the user provided initializer function. It
69-
// is important to not run the destructor on uninitialized objects, but
70-
// how to detect them is somewhat subtle. Since alloc() can be invoked
71-
// recursively, it is not sufficient to simply exclude the most recent
72-
// object. To solve this without requiring extra space, we use the low
73-
// order bit of the tydesc pointer to encode whether the object it
74-
// describes has been fully initialized.
75-
76-
// As an optimization, objects with destructors are stored in
77-
// different chunks than objects without destructors. This reduces
78-
// overhead when initializing plain-old-data and means we don't need
79-
// to waste time running the destructors of POD.
63+
/// A slower reflection-based arena that can allocate objects of any type.
64+
///
65+
/// This arena uses Vec<u8> as a backing store to allocate objects from. For
66+
/// each allocated object, the arena stores a pointer to the type descriptor
67+
/// followed by the object. (Potentially with alignment padding after each
68+
/// element.) When the arena is destroyed, it iterates through all of its
69+
/// chunks, and uses the tydesc information to trace through the objects,
70+
/// calling the destructors on them. One subtle point that needs to be
71+
/// addressed is how to handle failures while running the user provided
72+
/// initializer function. It is important to not run the destructor on
73+
/// uninitialized objects, but how to detect them is somewhat subtle. Since
74+
/// alloc() can be invoked recursively, it is not sufficient to simply exclude
75+
/// the most recent object. To solve this without requiring extra space, we
76+
/// use the low order bit of the tydesc pointer to encode whether the object
77+
/// it describes has been fully initialized.
78+
///
79+
/// As an optimization, objects with destructors are stored in
80+
/// different chunks than objects without destructors. This reduces
81+
/// overhead when initializing plain-old-data and means we don't need
82+
/// to waste time running the destructors of POD.
8083
pub struct Arena {
8184
// The head is separated out from the list as a unbenchmarked
82-
// microoptimization, to avoid needing to case on the list to
83-
// access the head.
85+
// microoptimization, to avoid needing to case on the list to access the
86+
// head.
8487
head: Chunk,
8588
copy_head: Chunk,
8689
chunks: RefCell<Vec<Chunk>>,
8790
}
8891

8992
impl Arena {
93+
/// Allocate a new Arena with 32 bytes preallocated.
9094
pub fn new() -> Arena {
9195
Arena::new_with_size(32u)
9296
}
9397

98+
/// Allocate a new Arena with `initial_size` bytes preallocated.
9499
pub fn new_with_size(initial_size: uint) -> Arena {
95100
Arena {
96101
head: chunk(initial_size, false),
@@ -265,7 +270,8 @@ impl Arena {
265270
}
266271
}
267272

268-
// The external interface
273+
/// Allocate a new item in the arena, using `op` to initialize the value
274+
/// and returning a reference to it.
269275
#[inline]
270276
pub fn alloc<'a, T>(&'a self, op: || -> T) -> &'a T {
271277
unsafe {
@@ -313,7 +319,7 @@ fn test_arena_destructors_fail() {
313319
});
314320
}
315321

316-
/// An arena that can hold objects of only one type.
322+
/// A faster arena that can hold objects of only one type.
317323
///
318324
/// Safety note: Modifying objects in the arena that have already had their
319325
/// `drop` destructors run can cause leaks, because the destructor will not
@@ -405,13 +411,13 @@ impl<T> TypedArenaChunk<T> {
405411
}
406412

407413
impl<T> TypedArena<T> {
408-
/// Creates a new arena with preallocated space for 8 objects.
414+
/// Creates a new TypedArena with preallocated space for 8 objects.
409415
#[inline]
410416
pub fn new() -> TypedArena<T> {
411417
TypedArena::with_capacity(8)
412418
}
413419

414-
/// Creates a new arena with preallocated space for the given number of
420+
/// Creates a new TypedArena with preallocated space for the given number of
415421
/// objects.
416422
#[inline]
417423
pub fn with_capacity(capacity: uint) -> TypedArena<T> {
@@ -423,7 +429,7 @@ impl<T> TypedArena<T> {
423429
}
424430
}
425431

426-
/// Allocates an object into this arena.
432+
/// Allocates an object in the TypedArena, returning a reference to it.
427433
#[inline]
428434
pub fn alloc<'a>(&'a self, object: T) -> &'a T {
429435
unsafe {

0 commit comments

Comments
 (0)