rusty_alloc 1.1.6

Allocator core of the rusty_alloc pure-Rust remake of mimalloc v2.4.5: segments, free-list-sharded pages, lock-free cross-thread frees, first-class heaps, arenas and a mi_*-compatible surface. Detects double frees. MIT.
Documentation

rusty_alloc

A pure-Rust remake of mimalloc — the v2.4.5 architecture (32 MiB segments, free-list-sharded pages, lock-free cross-thread frees), rebuilt from the design rather than transliterated from the C. No C anywhere in the product; the C mimalloc is a development-only differential oracle and is never a dependency.

Status: 1.0.0 — the API is frozen; changes follow semver from here.

Upgrade from 0.3.x or earlier — mandatory. 0.4.0 fixed three platform-independent use-after-frees on the abandon → adopt → reuse path. Treat 0.3.2 and earlier as unsound on every target.

Tested on x86-64/aarch64 Linux, aarch64/x86-64 macOS and x86-64 Windows; executed on wasm32-unknown-unknown (Node VM self-test, no emscripten).

What it is

  • ~150 of mimalloc's ~157 mi_* entry points, semantics-for-semantics, gated against the C implementation as a differential oracle.
  • A double free is detected and aborted, on both the owner and cross-thread paths. Upstream mimalloc accepts it silently in release builds; handing the same block to two owners is the failure this project exists to prevent.
  • Runs on WebAssembly via memory.grow, with no C toolchain.

Performance (instruction counts, not seconds)

Measured deterministically via callgrind instructions retired, x86-64 Linux, LD_PRELOAD. Side-by-side against the field (ratio = our instructions ÷ theirs; lower is better):

workload vs mimalloc vs jemalloc vs glibc
lua 0.97 0.84 0.82
perl 0.99 0.89 0.81
sqlite 1.00 0.98 0.99

We match mimalloc and come in 2–15% under jemalloc (jemalloc 5.3.0) across all three real programs, and ~17% under glibc.

The per-operation scan (small/med/big/large/huge, calloc, realloc, aligned, usable, batch and mixed working-set ops) measures below mimalloc on all 13 operations. Per-op ratios vs mimalloc: med 0.47, small 0.49, aligned 0.50, realloc 0.51, small_touch 0.51, big/large 0.53, calloc 0.63, mixed 0.67, usable 0.73, batch lifo/fifo 0.89, huge 0.01.

Five of those hold ONE BLOCK LIVE at a time, so the page empties on every free and what they measure is page retire-and-recarve rather than steady-state service. On workloads with a real working set — the honest number for a program — it is liveset 0.92 (65,536 live objects, random victim replaced each step), shbench 0.91 (bulk batches released in waves) and xthread 0.83 (every free performed by a non-owning thread). Wall-clock time is deliberately not claimed: the measurement box cannot resolve it above its own noise floor, and instructions are not seconds.

Batch is the narrowest margin, and it is the one with a story. It sat at 1.008 after a ThreadSanitizer fix made a page-flags byte atomic, which costs exactly one instruction because LLVM will not fold an atomic load into a test's memory operand. That trade was kept — upstream reads the same byte non-atomically and has the race — and the instruction was won back elsewhere on the same path rather than by undoing it.

free's fast path is 21 instructions against mimalloc's 25, down from 27. The used-- codegen floor docs/opps.md recorded is closed: it took five instructions from safe Rust because LLVM will not emit a memory-destination read-modify-write when the value must also drive a branch, and it is two now, written directly. Resolving a pointer to its page went from nine instructions to five on the back of a per-slice owner table in the segment header. The flags test is the single row where upstream is still cheaper, and it stays that way deliberately: closing it would keep the read atomic in hardware while hiding it from the sanitizer that found the race.

Correctness on real software: jq, sqlite3, python3, git, xz, zstd, lua and perl produce byte-identical output under rusty_alloc, mimalloc and glibc; the full mimalloc-bench corpus (19 configurations, including the 8–16-thread storms) runs clean; Miri is clean over the whole target.

Usage

This crate is the allocator core. For the ergonomic Rust surface (GlobalAlloc, first-class Heap, the Allocator trait), use rusty_alloc-api.

Long-lived services should set purge_delay >= 0 — the configuration with flat, measured RSS. The shipped default leaves purging opt-in.

Security

Audited against the use-protection-please 41-gate hardening standard — 14 of 15 v1.0.0 gates met (the one open gate, H-27, is the 30-day continuous-fuzz soak: the nightly mechanism is live and clean, the soak completes 2026-09-19, and it ships under a time-bound owner waiver). The gate-by-gate table is at the bottom of this README; the residual-risk register (R-001..R-005, owner-accepted) and the two time-bound waivers are in the full checklist.

What the default build gives you:

  • A double free aborts instead of putting a block on a free list twice — on both the owner and the cross-thread path.
  • Foreign-pointer detection on free (debug / debug_checks builds), and a memory-safe core: unsafe isolated with a stated invariant on every block, undocumented_unsafe_blocks denied workspace-wide, Miri-clean.
  • Mitigations tested for EFFICACY, not just functiontests/corruption.rs poisons a real free list and requires the process to die of SIGABRT (detected) rather than SIGSEGV (followed the poisoned pointer); a mitigation nobody has watched fire is a claim, not a defence.

Opt-in hardening for hostile-input services:

  • secure — per-page encrypted free-list links plus a same-segment + alignment bound on every decoded link, so a link overwrite cannot steer the allocator to an out-of-heap target. Measured cost: a flat ~15 instructions per allocation (+0.6–1.8% whole-program).
  • blockmap — a per-page block-liveness map that catches a forged link landing on an already-live block, the one thing that closes R-005 (encoding does not survive an attacker with a read primitive). Off by default on cost (~3× secure); switchable independently.

Reports go through SECURITY.md (private GitHub advisories). See the threat model and the unsafe inventory.

Features

feature what
debug_checks full invariant validation: list walks, span tiling, page canaries
secure encrypted free-list links + same-segment link bound; guard pages / guarded-object sampling available (opt-in via options). Flat ~15 instr/alloc (+0.6–1.8% whole-program)
blockmap per-page block-liveness map — catches a forged link handed out as a live block (closes R-005). Off by default on cost (~3× secure)
profile feature-gated path profiler

Statistics counters follow upstream's MI_STAT rule: present in debug builds, compiled out of release.

The Remade With Rust ecosystem

Remade With Rust is an initiative by Mata Network to rebuild essential C and C++ tools in Rust — for the memory safety, the predictable performance, and the freedom of a permissive license. Each project is a reimplementation, not a fork: same wire protocols and file formats, new code you can actually depend on.

We build the core to production grade and open-source it so the community can extend it. No copyleft. No surprises. Just the tools we rely on, made faster and safer.

Project What it is
🎬 remade_ffmpeg_rs Our FFmpeg alternative. Drop-in ffmpeg and ffprobe binaries — demux → decode → filter → encode → mux, rebuilt as composable Rust crates with zero GPL/LGPL. Apache-2.0. rusty_h264 is its H.264 codec.
🧠 FFAI Our sister project: media for AI. "The AI media toolkit, remade with rust." Embedded ASR + TTS (Mercury), OCR (Carmenta) and vision-language captioning (Argus) behind an ffmpeg-style, swap-by-name architecture — no Python, no CUDA. MIT OR Apache-2.0.
🌐 Mata Network The home page. "Stop sacrificing your privacy for convenience." Sovereign, self-hostable privacy infrastructure — wallet & identity, password manager, contact manager, and a browser extension that stops information leaking as you browse. Remade With Rust is its open-source arm.

→ All projects: github.com/Remade-With-Rust

License

MIT. See LICENSE at the repository root.


Hardening status

Tier critical-path · Audited 2026-08-20 (survey) · v1.0.0 gates 14/15 · Full checklist

██████████████████░░ 94%  ·  34 Completed · 1 Scheduled · 1 Incomplete · 19 N/A

Phase ✅ Completed 🗓 Scheduled ⬜ Incomplete · N/A
0 — Threat modeling 2 0 0 0
1 — Toolchain 4 0 0 0
2 — Supply chain 8 0 0 0
3 — Code level 6 0 0 1
4 — Static analysis 1 0 0 0
5 — Dynamic analysis 3 0 0 0
6 — Fuzzing and properties 3 1 0 0
7 — Formal verification 1 0 0 0
8 — Build and binary 0 0 0 2
9 — Runtime privilege 0 0 0 1
10 — Cryptography 2 0 0 1
11 — CI/CD, release, and operations 4 0 1 0
12 — Compliance controls 0 0 0 14
Total 34 1 1 19

Next up — H-27 Continuous fuzzing with no open crashes (2026-09-19 (30 days from the nightly job's first run))

Architect — Tim — Mata Network