Struct maskerad_memory_allocators::StackAllocator
[−]
[src]
pub struct StackAllocator { /* fields omitted */ }
A stack-based allocator for data implementing the Drop trait.
It manages two MemoryChunk
s to:
Allocate bytes in a stack-like fashion.
Store different types of objects in the same storage.
Drop the content of the MemoryChunk when needed.
One MemoryChunk
is used for data implementing the Drop
trait, the other is used for data implementing
the Copy
trait. A structure implementing the Copy
trait cannot implement the Drop
trait. In order to
drop data implementing the Drop
trait, we need to store its vtable next to it in memory.
Instantiation
When instantiated, the memory chunk pre-allocate the given number of bytes for each MemoryChunk
.
Allocation
When an object is allocated in memory, the allocator:
Check if the allocated object needs to be dropped, and choose which
MemoryChunk
to use according to this information,Asks a pointer to a memory address to the corresponding memory chunk,
Place the object in this memory address,
Update the first unused memory address of the memory chunk according to an offset,
And return an immutable/mutable reference to the object which has been placed in the memory chunk.
This offset is calculated by the size of the object, the size of a TypeDescription
structure (if the object implement the Drop
trait),
its memory-alignment and an offset to align the object in memory.
Roll-back
This structure allows you to get a marker, the index to the first unused memory address of a memory chunk. A stack allocator can reset a memory chunk to a marker, or reset a memory chunk entirely.
When a memory chunk is reset to a marker, it will:
Drop all the content lying between the marker and the first unused memory address, if it holds data implementing the
Drop
trait,Set the first unused memory address to the marker.
When a memory chunk is reset completely, it will:
Drop everything, if ti holds data implementing the
Drop
trait,Set the first unused memory address to the bottom of its stack.
Example
use maskerad_memory_allocators::StackAllocator; //100 bytes for data implementing Drop, 100 bytes for data implementing Copy. let single_frame_allocator = StackAllocator::with_capacity(100, 100); let mut closed = false; while !closed { // The allocator is cleared every frame. // Everything is dropped, and allocation occurs from the bottom of the stack. single_frame_allocator.reset(); //... //allocate from the single frame allocator. //Be sure to use the data during this frame only! let my_vec: &Vec<u8> = single_frame_allocator.alloc(|| { Vec::with_capacity(10) }).unwrap(); assert!(my_vec.is_empty()); closed = true; }
Methods
impl StackAllocator
[src]
fn with_capacity(capacity: usize, capacity_copy: usize) -> Self
[src]
Creates a StackAllocator with the given capacities, in bytes.
The first capacity is for the MemoryChunk
holding data implementing the Drop
trait,
the second is for the MemoryChunk
holding data implementing the Copy
trait.
Example
#![feature(alloc)] use maskerad_memory_allocators::StackAllocator; let allocator = StackAllocator::with_capacity(100, 50); assert_eq!(allocator.storage().capacity(), 100); assert_eq!(allocator.storage_copy().capacity(), 50);
fn storage(&self) -> Ref<MemoryChunk>
[src]
Returns a borrowed reference to the memory chunk used for data implementing the Drop
trait.
fn storage_copy(&self) -> Ref<MemoryChunk>
[src]
Returns a borrowed reference to the memory chunk used for data implementing the Copy
trait.
fn alloc_mut<T, F>(&self, op: F) -> AllocationResult<&mut T> where
F: FnOnce() -> T,
[src]
F: FnOnce() -> T,
Allocates data in the allocator's memory, returning a mutable reference to the allocated data.
If the allocated data implements Drop
, it will be placed in the MemoryChunk
storing data implementing the Drop
trait.
Otherwise, it will be placed in the other MemoryChunk
.
Error
This function will return an error if the allocation exceeds the maximum storage capacity of the allocator.
Example
use maskerad_memory_allocators::StackAllocator; let allocator = StackAllocator::with_capacity(100, 100); let my_i32 = allocator.alloc_mut(|| { 26 as i32 }).unwrap(); assert_eq!(my_i32, &mut 26);
fn alloc<T, F>(&self, op: F) -> AllocationResult<&T> where
F: FnOnce() -> T,
[src]
F: FnOnce() -> T,
Allocates data in the allocator's memory, returning an immutable reference to the allocated data.
If the allocated data implements Drop
, it will be placed in the MemoryChunk
storing data implementing the Drop
trait.
Otherwise, it will be placed in the other MemoryChunk
.
Error
This function will return an error if the allocation exceeds the maximum storage capacity of the allocator.
Example
use maskerad_memory_allocators::StackAllocator; let allocator = StackAllocator::with_capacity(100, 100); let my_i32 = allocator.alloc(|| { 26 as i32 }).unwrap(); assert_eq!(my_i32, &26);
fn marker(&self) -> usize
[src]
Returns the index of the first unused memory address of the MemoryChunk
storing data implementing
the Drop
trait.
Example
use maskerad_memory_allocators::StackAllocator; let allocator = StackAllocator::with_capacity(100, 100); //100 bytes //Get the raw pointer to the bottom of the allocator's memory chunk. let start_allocator = allocator.storage().as_ptr(); //Get the index of the first unused memory address. let index_current_top = allocator.marker(); //Calling offset() on a raw pointer is an unsafe operation. unsafe { //Get the raw pointer, with the index. let current_top = start_allocator.offset(index_current_top as isize); //Nothing has been allocated in the allocator, //the top of the stack is the bottom of the allocator's memory chunk. assert_eq!(current_top, start_allocator); }
fn marker_copy(&self) -> usize
[src]
Returns the index of the first unused memory address of the MemoryChunk
storing data implementing
the Copy
trait.
Example
use maskerad_memory_allocators::StackAllocator; let allocator = StackAllocator::with_capacity(100, 100); //100 bytes //Get the raw pointer to the bottom of the allocator's memory chunk. let start_allocator = allocator.storage_copy().as_ptr(); //Get the index of the first unused memory address. let index_current_top = allocator.marker_copy(); //Calling offset() on a raw pointer is an unsafe operation. unsafe { //Get the raw pointer, with the index. let current_top = start_allocator.offset(index_current_top as isize); //Nothing has been allocated in the allocator, //the top of the stack is the bottom of the allocator's memory chunk. assert_eq!(current_top, start_allocator); }
fn reset(&self)
[src]
Reset the MemoryChunk
storing data implementing the Drop
trait, dropping all the content residing inside it.
Example
use maskerad_memory_allocators::StackAllocator; let allocator = StackAllocator::with_capacity(100, 100); // 100 bytes. //When nothing has been allocated, the first unused memory address is at index 0. assert_eq!(allocator.marker(), 0); let my_vec: &Vec<u8> = allocator.alloc(|| { Vec::with_capacity(10) }).unwrap(); assert_ne!(allocator.marker(), 0); allocator.reset(); //The MemoryChunk storing data implementing the `Drop` trait has been totally reset, and all its content has been dropped. assert_eq!(allocator.marker(), 0);
fn reset_copy(&self)
[src]
Reset the MemoryChunk
storing data implementing the Drop
trait, dropping all the content residing inside it.
Example
use maskerad_memory_allocators::StackAllocator; let allocator = StackAllocator::with_capacity(100, 100); // 100 bytes. //When nothing has been allocated, the first unused memory address is at index 0. assert_eq!(allocator.marker_copy(), 0); let my_i32 = allocator.alloc(|| { 8 as i32 }).unwrap(); assert_ne!(allocator.marker_copy(), 0); allocator.reset_copy(); //The MemoryChunk storing data implementing the `Copy` has been totally reset. assert_eq!(allocator.marker_copy(), 0);
fn reset_to_marker(&self, marker: usize)
[src]
Reset partially the MemoryChunk
storing data implementing the Drop
trait, dropping all the content residing between the marker and
the first unused memory address of the MemoryChunk
.
Example
use maskerad_memory_allocators::StackAllocator; // 100 bytes for data implementing Drop, 100 bytes for Data implementing Copy. let allocator = StackAllocator::with_capacity(100, 100); //When nothing has been allocated, the first unused memory address is at index 0. assert_eq!(allocator.marker(), 0); let my_vec: &Vec<u8> = allocator.alloc(|| { Vec::with_capacity(10) }).unwrap(); //After the allocation, get the index of the first unused memory address in the allocator. let index_current_top = allocator.marker(); assert_ne!(index_current_top, 0); let my_vec_2: &Vec<u8> = allocator.alloc(|| { Vec::with_capacity(10) }).unwrap(); assert_ne!(allocator.marker(), index_current_top); allocator.reset_to_marker(index_current_top); //The memorychunk storing data implementing the Drop trait has been partially reset, and all the content lying between the marker and //the first unused memory address has been dropped. assert_eq!(allocator.marker(), index_current_top);
fn reset_to_marker_copy(&self, marker: usize)
[src]
Reset partially the MemoryChunk
storing data implementing the Copy
trait.
Example
use maskerad_memory_allocators::StackAllocator; // 100 bytes for data implementing Drop, 100 bytes for Data implementing Copy. let allocator = StackAllocator::with_capacity(100, 100); //When nothing has been allocated, the first unused memory address is at index 0. assert_eq!(allocator.marker_copy(), 0); let my_i32 = allocator.alloc(|| { 8 as i32 }).unwrap(); //After the allocation, get the index of the first unused memory address in the allocator. let index_current_top = allocator.marker_copy(); assert_ne!(index_current_top, 0); let my_i32_2 = allocator.alloc(|| { 9 as i32 }).unwrap(); assert_ne!(allocator.marker_copy(), index_current_top); allocator.reset_to_marker_copy(index_current_top); //The memorychunk storing data implementing the Copy trait has been partially reset. assert_eq!(allocator.marker_copy(), index_current_top);
fn capacity(&self) -> usize
[src]
Returns the maximum capacity the MemoryChunk
storing data implementing the Drop
trait can hold.
fn capacity_copy(&self) -> usize
[src]
Returns the maximum capacity the MemoryChunk
storing data implementing the Copy
trait can hold.
fn storage_as_ptr(&self) -> *const u8
[src]
Returns a raw pointer to the start of the memory storage used by the MemoryChunk
storing data implementing the Drop
trait.
fn storage_copy_as_ptr(&self) -> *const u8
[src]
Returns a raw pointer to the start of the memory storage used by the MemoryChunk
storing data implementing the Copy
trait.