Struct dynamic_arena::DynamicArena
source · [−]pub struct DynamicArena<'a, S = NonSend> { /* private fields */ }
Expand description
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.
Implementations
sourceimpl DynamicArena<'static, NonSend>
impl DynamicArena<'static, NonSend>
sourceimpl<'a, S> DynamicArena<'a, S>
impl<'a, S> DynamicArena<'a, S>
sourcepub fn with_capacity(item_capacity: usize, byte_capacity: usize) -> Self
pub fn with_capacity(item_capacity: usize, byte_capacity: usize) -> Self
Create an arena with pre-allocated capacity for the specified number of items and bytes.
NOTE: The “item” capacity excludes Copy
references that
don’t need to be dropped.
sourcepub fn alloc_copy<T: Copy + Send>(&self, value: T) -> &mut T
pub fn alloc_copy<T: Copy + Send>(&self, value: T) -> &mut T
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.
sourcepub unsafe fn alloc_unchecked<T>(&self, value: T) -> &mut T
pub unsafe fn alloc_unchecked<T>(&self, value: T) -> &mut T
Allocate the specified value in this arena,
without calling its Drop
function.
Since this doesn’t call the ‘Drop’ impleentation, this function leaks the underlying memory.
Safety
Technically, this function is safe to use. However, it leaks memory unconditionally (without calling Drop).
sourcepub unsafe fn alloc_layout(&self, layout: Layout) -> NonNull<u8>
pub unsafe fn alloc_layout(&self, layout: Layout) -> NonNull<u8>
Allocate space for an object with the specified layout
The returned pointer points at uninitialized memory
Safety
Technically, only the use of the memory is unsafe.
It would theoretically be possible to mark this function safe, just like Bump::alloc_layout.
sourcepub unsafe fn dynamic_drop<T>(&self, value: *mut T)
pub unsafe fn dynamic_drop<T>(&self, value: *mut T)
Dynamically drop the specified value, invoking the drop function when the arena is dropped.
Safety
This assumes it’s safe to drop the value at the same time the arena is dropped. 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.
sourcepub fn as_bumpalo(&self) -> &Bump
pub fn as_bumpalo(&self) -> &Bump
Retrieve the underlying bump allocator for this arena
sourceimpl<'a> DynamicArena<'a, Sendable>
impl<'a> DynamicArena<'a, Sendable>
sourcepub fn new_send() -> Self
pub fn new_send() -> Self
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
.
sourcepub fn alloc<T: Send + 'a>(&self, value: T) -> &mut T
pub fn alloc<T: Send + 'a>(&self, value: T) -> &mut T
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
.
sourceimpl<'a> DynamicArena<'a, NonSend>
impl<'a> DynamicArena<'a, NonSend>
sourcepub fn new_bounded() -> Self
pub fn new_bounded() -> Self
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
.
Trait Implementations
sourceimpl<'a, S: SendAbility> Default for DynamicArena<'a, S>
impl<'a, S: SendAbility> Default for DynamicArena<'a, S>
sourceimpl<'a, S> Drop for DynamicArena<'a, S>
impl<'a, S> Drop for DynamicArena<'a, S>
impl<'a, S: SendAbility + Send> Send for DynamicArena<'a, S>
Auto Trait Implementations
impl<'a, S = NonSend> !RefUnwindSafe for DynamicArena<'a, S>
impl<'a, S = NonSend> !Sync for DynamicArena<'a, S>
impl<'a, S> Unpin for DynamicArena<'a, S> where
S: Unpin,
impl<'a, S = NonSend> !UnwindSafe for DynamicArena<'a, S>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more