[][src]Crate alloc_counter

alloc_counter

Alloc counters

A redesign of the Quick and Dirty Allocation Profiling Tool.

Features

  • Although #[no_std] is intended, it isn't currently supported due to the lack of portable thread_local implementation. This may be "fixed" with a feature flag to use a global atomic under the contract that the program is single threaded.

  • Count allocations, reallocations and deallocations individually with count_alloc.

  • Allow, deny, and forbid use of the global allocator with allow_alloc, deny_alloc and forbid_alloc.

  • #[no_alloc] function attribute to deny and #[no_alloc(forbid)] to forbid use of the global allocator.

  • #[count_alloc] function attribute to print the counts to stderr. Alternatively use #[count_alloc(func = "my_function")] where my_function accepts a triple of usizes and returns () to redirect the output.

Limitations and known issues

  • Methods must either take a reference to self or Self must be a Copy type.

  • Ordinary and async functions must be treated differently. Use count_alloc for functions and count_alloc_future for futures.

Usage

An AllocCounter<A> wraps an allocator A to individually count the number of calls to alloc, realloc, and dealloc.

use alloc_counter::AllocCounter;

type MyAllocator = std::alloc::System;
const MyAllocator: MyAllocator = std::alloc::System;

#[global_allocator]
static A: AllocCounter<MyAllocator> = AllocCounter(MyAllocator);

Std-users may prefer to inherit their system's allocator.

use alloc_counter::AllocCounterSystem;

#[global_allocator]
static A: AllocCounterSystem = AllocCounterSystem;

To count the allocations of an expression, use count_alloc.

let (counts, v) = count_alloc(|| {
    // no alloc
    let mut v = Vec::new();
    // alloc
    v.push(0);
    // realloc
    v.push(1);
    // return the vector without deallocating
    v
});
assert_eq!(counts, (1, 1, 0));

To deny allocations for an expression use deny_alloc.

fn foo(b: Box<i32>) {
    // dropping causes a panic
    deny_alloc(|| drop(b))
}
foo(Box::new(0));

Similar to Rust's lints, you can still allow allocation inside a deny block.

fn foo(b: Box<i32>) {
    deny_alloc(|| allow_alloc(|| drop(b)))
}
foo(Box::new(0));

Forbidding allocations forces a panic even when allow_alloc is used.

fn foo(b: Box<i32>) {
    // panics because of outer `forbid`, even though drop happens in an allow block
    forbid_alloc(|| allow_alloc(|| drop(b)))
}
foo(Box::new(0));

For added sugar you may use the #[no_alloc] attribute on functions, including methods with self-binds. #[no_alloc] expands to calling deny_alloc and forcefully moves the parameters into the checked block. #[no_alloc(forbid)] calls forbid_alloc.

#[no_alloc(forbid)]
fn foo(b: Box<i32>) {
    allow_alloc(|| drop(b))
}
foo(Box::new(0));

License: MIT OR Apache-2.0

Structs

AllocCounter

An allocator that tracks allocations, reallocations, and deallocations in live code. It uses another backing allocator for actual heap management.

AsyncGuard

A future-wrapper which counts the allocations, reallocations, and deallocations that occur while the future is evaluating.

Enums

AllocMode

Configure how allocations are counted

Constants

AllocCounterSystem

An allocator that counts allocations, reallocations, and deallocations in live code. It uses the operating system as a backing implementation for actual heap management.

Functions

allow_alloc

Allow allocations for a closure, even if running in a deny closure. Allocations during a forbid closure will still cause a panic.

count_alloc

Count the allocations, reallocations, and deallocations that happen during execution of a closure.

count_alloc_future

Count the allocations, reallocations, and deallocations that happen duringexecution of a future.

deny_alloc

Panic on any allocations during the provided closure. If code within the closure calls allow_alloc, allocations are allowed within that scope.

forbid_alloc

Panic on any allocations during the provided closure, even if the closure contains code in an allow_alloc guard.

guard_fn

Apply the allocation mode against a function/closure. Panicking if any allocations, reallocations or deallocations occur. (Use guard_future for futures)

guard_future

Apply the allocation mode against a future. Panicking if any allocations, reallocations or deallocations occur. (Use guard_fn for functions)

Type Definitions

AllocCounterSystem

Type alias for an AllocCounter backed by the operating system's default allocator

Counters

A tuple of the counts; respectively allocations, reallocations, and deallocations.

Attribute Macros

count_alloc

Macro for counting allocations inside a functions.

no_alloc

Macro for marking functions as unable to allocate.