Skip to main content

Module alloc

Module alloc 

Source
Expand description

An opt-in #[global_allocator] backed by the BEAM allocator.

EnifAlloc routes every Rust heap allocation in the NIF library through enif_alloc/enif_free. This matters for hot code upgrade: enif_free is the one free path that is valid across two independently compiled builds of the library (a stable C ABI), whereas Rust’s default allocator is build-private. Routing allocations through the VM allocator is therefore a building block for carrying state across the upgrade boundary safely (see docs/UPGRADE.md).

§Why direct-linked, not dlsym

The rest of otter resolves enif_* symbols at run time with dlsym (via the enif_ffi crate). A global allocator cannot: it may be called for the very first Rust allocation, before any initialization code runs, so it must not depend on a resolution step that itself allocates. Instead this module direct-links the two functions it needs as extern "C". The BEAM exports them, and the dynamic linker binds them when the NIF .so is dlopen’d (RTLD_NOW) — before nif_init, before any Rust code. There is no catch-22.

§Inert until you opt in

EnifAlloc is always available, but it is referenced — and therefore pulls in the direct-linked enif_alloc/enif_free symbols — only when you install it as the global allocator with enif_global_allocator!. Until then dead-code elimination drops it, so otter still links into ordinary, non-BEAM binaries (its own cargo test, doc builds, etc.).

Once you do install it, those two symbols are undefined in the object file and resolved only when the BEAM loads the .so — so a crate that invokes the macro links only as a NIF cdylib hosted by the BEAM, never as an ordinary executable.

Structs§

EnifAlloc
A GlobalAlloc backed by the BEAM allocator (enif_alloc/enif_free).