Struct maskerad_memory_allocators::StackAllocator [] [src]

pub struct StackAllocator { /* fields omitted */ }

A stack-based allocator.

It manages two memory storages to:

  • Allocate bytes in a stack-like fashion.

  • Store different types of objects in the same storage.

  • Drop the content of the storage when needed.

One storage 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.

Details

Instantiation

When instantiated, the StackAllocator pre-allocate the given number of bytes for each memory storage.

Allocation

When an object is allocated in memory, the allocator:

  • Check if the allocated object needs to be dropped, and choose which memory storage to use according to this information,

  • Asks a pointer to a memory address to the corresponding memory storage,

  • Place the object in this memory address,

  • Update the first unused memory address of the memory storage according to an offset,

  • And return an immutable/mutable reference to the object which has been placed in the memory storage.

This offset is calculated by the size of the object, its vtable (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 storage. A stack allocator can reset a memory storage to a marker, or reset a memory storage entirely.

When a memory storage 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 storage is reset completely, it will:

  • Drop everything, if it 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.
    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)
    })?;

    assert!(my_vec.is_empty());
    closed = true;
}

Methods

impl StackAllocator
[src]

[src]

Creates a StackAllocator with the given capacities, in bytes.

The first capacity is for the memory storage holding data implementing the Drop trait, the second is for the memory storage holding data implementing the Copy trait.

Example

use maskerad_memory_allocators::StackAllocator;

let allocator = StackAllocator::with_capacity(100, 50);
assert_eq!(allocator.capacity(), 100);
assert_eq!(allocator.capacity_copy(), 50);

[src]

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 memory storage storing data implementing the Drop trait. Otherwise, it will be placed in the other memory storage.

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
})?;

assert_eq!(my_i32, &mut 26);

[src]

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 memory storage storing data implementing the Drop trait. Otherwise, it will be placed in the other memory storage.

Warning

This function doesn't return an error if the allocated data doesn't fit in the StackAllocator's remaining capacity, It doesn't perform any check.

Use if you now that the data will fit into memory and you can't afford the checks.

Example

use maskerad_memory_allocators::StackAllocator;
let allocator = StackAllocator::with_capacity(100, 100);

// An i32 is 4 bytes, has a 4-byte alignment and doesn't have a destructor.
// It will, in the worst case take 8 bytes in the stack memory.
// The copy storage of the stack can store up to 100 bytes, so it's fine.

let my_i32 = allocator.alloc_mut_unchecked(|| {
    26 as i32
});

assert_eq!(my_i32, &mut 26);

[src]

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 memory storage storing data implementing the Drop trait. Otherwise, it will be placed in the other memory storage.

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
})?;

assert_eq!(my_i32, &26);

[src]

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 memory storage storing data implementing the Drop trait. Otherwise, it will be placed in the other memory storage.

Warning

This function doesn't return an error if the allocated data doesn't fit in the StackAllocator's remaining capacity, It doesn't perform any check.

Use if you now that the data will fit into memory and you can't afford the checks.

Example

use maskerad_memory_allocators::StackAllocator;
let allocator = StackAllocator::with_capacity(100, 100);

// An i32 is 4 bytes, has a 4-byte alignment and doesn't have a destructor.
// It will, in the worst case take 8 bytes in the stack memory.
// The copy storage of the stack can store up to 100 bytes, so it's fine.

let my_i32 = allocator.alloc_unchecked(|| {
    26 as i32
});

assert_eq!(my_i32, &26);

[src]

Returns the index of the first unused memory address of the memory storage 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);
}

[src]

Returns the index of the first unused memory address of the memory storage 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);
}

[src]

Reset the memory storage 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)
})?;
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);

[src]

Reset the memory storage 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
})?;
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);

[src]

Reset partially the memory storage storing data implementing the Drop trait, dropping all the content residing between the marker and the first unused memory address of the memory storage.

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)
})?;

//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)
})?;

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);

[src]

Reset partially the memory storage 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
})?;

//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
})?;

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);

[src]

Returns the maximum capacity the memory storage storing data implementing the Drop trait can hold.

Example

use maskerad_memory_allocators::StackAllocator;
// 100 bytes for data implementing Drop, 100 bytes for Data implementing Copy.
let allocator = StackAllocator::with_capacity(100, 50);
assert_eq!(allocator.capacity(), 100);

[src]

Returns the maximum capacity the memory storage storing data implementing the Copy trait can hold.

Example

use maskerad_memory_allocators::StackAllocator;
// 100 bytes for data implementing Drop, 100 bytes for Data implementing Copy.
let allocator = StackAllocator::with_capacity(100, 50);
assert_eq!(allocator.capacity_copy(), 50);

[src]

Returns a raw pointer to the start of the memory storage storing data implementing the Drop 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, 50);
let ptr = allocator.storage_as_ptr();

[src]

Returns a raw pointer to the start of the memory storage 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, 50);
let ptr = allocator.storage_copy_as_ptr();

Trait Implementations

impl Debug for StackAllocator
[src]

[src]

Formats the value using the given formatter.

impl Drop for StackAllocator
[src]

[src]

Executes the destructor for this type. Read more