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.
8083pub 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
8992impl Arena {
93+ /// Allocate a new Arena with 32 bytes preallocated.
9094 pub fn new ( ) -> Arena {
9195 Arena :: new_with_size ( 32 u)
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
407413impl < 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