[][src]Struct dynamic_arena::DynamicArena

pub struct DynamicArena<'a, S = NonSend> { /* fields omitted */ }

An arena allocator where any type of object can be allocated.

Unlike typed arenas, any Sized object can be allocated here and they don't all have to have the same statically known type in advance. Usually you don't have to worry about the arena's lifetime, since it should be static by default (see).

Performance

Although this is slightly slower than a typed_arena::Arena, it can be much more memory and time efficient than having a ton of seperate typed arenas. The only point where dynamic dispatch actually gets involved is when the arena is dropped, since we have to dynamically dispatch the drop functions instead of statically dispatching them.

Safety

In order to prevent use after free in a DynamicArena, all pointers in the allocated items need to be valid for the lifetime 'a to ensure all references outlive the arena itself. Unfortunately, this statically prevents all self referential structs with alloc, since they can't be known ahead of time to be safe and outlive the arena itself, and we can't perform dropchk on a dynamically typed arena (only statically typed ones).

The alternatives to this are alloc_unchecked, which bypasses the lifetime and safety, and alloc_copy, which bypasses the lifetime by ensuring T: Copy. This is safe, since a copyable item can never have a custom drop, and the drop function could never possibly trigger use after free.

This means you can use self-referential structs with a DynamicArena as long as they implement Copy. One way to make your types implement copy and support self-refrential structs, is by replacing owned objects with their borrowed counterparts and then allocating them in the arena. For example

struct OwnedSelfReferential<'a> {
   next: Option<&'a OwnedSelfReferential<'a>>,
   text: String,
   array: Vec<u32>
}

can't be used with either alloc (since it's self referential), nor alloc_copy (since String and Vec need to be dropped). However by replacing String with &'a str and &'a [u32], we can make the structure Copy and enable use with alloc_copy.

Then, when someone needs to arena-allocate the struct they can use the same arena to allocate the String and Vec<u32> first, before they proceed to allocate the copyable struct.

Methods

impl DynamicArena<'static, NonSend>
[src]

pub fn new() -> Self
[src]

Create a new dynamic arena whose allocated items must outlive the 'static lifetime, and whose items aren't required to be Send.

Usually this is what you want, since it's only a bound for the allocated items.

impl<'a, S> DynamicArena<'a, S>
[src]

pub fn with_capacity(item_capacity: usize, byte_capacity: usize) -> Self
[src]

pub fn alloc_copy<T: Copy + Send>(&self, value: T) -> &mut T
[src]

Allocate the specified value in this arena, returning a reference which will be valid for the lifetime of the entire arena.

The bound on the item requires that T: Copy to ensure there's no drop function that needs to be invoked.

pub unsafe fn alloc_unchecked<T>(&self, value: T) -> &mut T
[src]

Allocate the specified value in this arena, without ensuring that its drop function would be safe to invoke.

Additionally this function leaks the underlying memory, and never runs the destructor, so its ownership needs to be tracked seperately.

pub unsafe fn dynamic_drop<T>(&self, value: *mut T)
[src]

Dynamically drop the specified value, invoking the drop function when the arena is dropped.

This is unsafe because the drop function isn't necessarily safe to invoke, and the memory isn't nessicarrily . Not only are you assuming that ptr::drop_in_place would be safe, you're also assuming that the drop function won't reference any dangling pointers, and that dropchk would be successful.

Normally these invariants are statically checked by the alloc method, which ensures that the memory is owned and all pointers would be valid for the lifetime of the entire arena.

impl<'a> DynamicArena<'a, Sendable>
[src]

pub fn new_send() -> Self
[src]

Create a new empty arena, bounded by the inferred lifetime for this type 'a

Since this arena has been marked Sendable, all items in the arena need to implement Send.

pub fn alloc<T: Send + 'a>(&self, value: T) -> &mut T
[src]

Allocate the specified value in this arena, returning a reference which will be valid for the lifetime of the entire arena.

The bound on this item requires that T: 'a to ensure the drop function is safe to invoke. Additionally, since the arena is Sendable, the bound on the item also requires that T: Send.

impl<'a> DynamicArena<'a, NonSend>
[src]

pub fn new_bounded() -> Self
[src]

Create a new empty arena, bounded by the inferred lifetime for this type 'a

Since this arena has been marked NonSend, the items in the arena don't necessarily need to implement Send.

pub fn alloc<T: 'a>(&self, value: T) -> &mut T
[src]

Allocate the specified value in this arena, returning a reference which will be valid for the lifetime of the entire arena.

The bound on this item requires that T: 'a to ensure the drop function is safe to invoke.

Trait Implementations

impl<'a, S> Drop for DynamicArena<'a, S>
[src]

impl<'a> Send for DynamicArena<'a, Sendable>
[src]

impl<'a, S: SendAbility> Default for DynamicArena<'a, S>
[src]

Auto Trait Implementations

impl<'a, S = NonSend> !Send for DynamicArena<'a, S>

impl<'a, S = NonSend> !Sync for DynamicArena<'a, S>

Blanket Implementations

impl<T> From for T
[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom for T where
    T: From<U>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Any for T where
    T: 'static + ?Sized
[src]