1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
[]
= "rusty_alloc"
= "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."
= "https://docs.rs/rusty_alloc"
= true
= true
= true
= true
= true
= true
= true
= "README.md"
# The crate has NO dependencies on any target it currently ships to — this
# entry is compiled ONLY for targets that lack a 64-bit atomic (32-bit RISC-V
# and Xtensa: the Janus ESP32-C3/C6/S3 parts), so the x86-64, aarch64, wasm32
# and Windows builds remain dependency-free.
#
# Why a shim here and NARROWING everywhere else (P3 of docs/plans/small-metal.md):
# the crate's other 64-bit atomics are BITMAPS, whose word width is a free
# choice, and those were narrowed to `u32` — no dependency, still lock-free.
# These two are different: `options::{get,set}` are `i64` in an API frozen at
# v2.0.0, and `DeferredFreeFun`'s heartbeat is a `u64` in the C ABI shared with
# mimalloc's `mi_deferred_free_fun`. Narrowing either breaks a contract, and
# hand-rolling a 64-bit atomic out of two 32-bit halves inside an allocator is
# exactly the kind of thing that produces a subtle bug.
[]
= { = "1", = false, = ["fallback"] }
[]
# `std` is DEFAULT and additive — unlike the geometry `--cfg` (P2), which is
# deliberately not a feature. A feature is right here precisely because it IS
# additive: if any consumer in a graph needs `std`, enabling it for all of them
# is harmless. Turning it OFF is what a firmware does, and it selects the
# single-heap profile: no `thread_local!`, no environment, no `process::abort`
# (see `lib.rs`). P3 of docs/plans/small-metal.md.
= ["std"]
= []
# Full invariant checking: list walks, canaries, double-free detection (our `dmi`).
= []
# Feature-gated rdtsc path profiler (§7.5 of the plan). OFF = byte-identical build.
= []
# EXPERIMENTAL (2026-08-20): the free-list link BOUND without the encoding.
#
# `secure` costs a flat ~15 instructions per allocation, and almost all of that
# is the per-page keyed encode/decode plus key generation — not the bound
# itself, which is two ALU ops on a value already in a register. This feature
# isolates the bound so its cost can be measured on its own.
#
# What it buys WITHOUT encoding: an attacker who overwrites a plain link can
# still choose the value, but the bound confines the target to the SAME 32 MiB
# segment — which removes GOT entries, vtables, stack addresses and saved
# return addresses from reach entirely. Strictly weaker than `secure` (which
# also denies steering at all without both per-page keys), strictly stronger
# than today's default, which follows any value it is handed.
#
# Not on by default and not yet recommended: see the plan file for the
# measurement and the false-positive testing before promoting it.
= []
# EXPERIMENTAL (2026-08-20): per-page block-liveness bitmap.
#
# The one defence that actually stops the residual in R-005. Encoding and
# bounds both try to prevent a link being FORGED; this detects the thing a
# forgery is for — `malloc` handing out a block that is already live. It does
# not care how the link was forged, so it covers key recovery, relative
# forgery and blind luck alike.
#
# The bitmap is out-of-band with respect to the free list itself and carries no
# key, so unlike the encoding it is not defeated by a read primitive.
#
# OFF by default and independently switchable from `secure`/`linkcheck` so it
# can be measured, and reverted, on its own. Composes with either.
= []
# Hardened build (our `smi`). M8. Deliberately NOT default — see the cost below.
#
# Always on with this feature: per-page encrypted free-list links, plus a
# same-segment + alignment bound on every decoded link (`page::link_is_plausible`).
#
# Available but INERT until asked for: guarded objects and their guard pages.
# The `guarded_max` OPTION defaults to 0, so `init::create_heap` skips both
# `guarded_set_*` calls and the heap keeps `guarded_rate: 0`. Enabling `secure`
# alone therefore does NOT give you guard pages — set the `guarded_max` option
# > 0, or call `guarded_set_sample_rate` / `mi_heap_guarded_set_sample_rate`.
#
# Measured cost (2026-08-20, callgrind Ir, same binary both arms): a FLAT ~15
# instructions per allocation — 8-25% per-op depending only on how cheap the op
# is (batch 60->75, big 171->185, `usable` and `huge` exactly +0.00 since
# neither walks a free list) and +0.6-1.8% whole-program on lua/perl/sqlite.
# Opt-in because that is enough to forfeit mimalloc parity, which is the
# headline result: perl 0.9991 -> 1.0160, sqlite 1.0003 -> 1.0061,
# calloc 0.949 -> 1.041, batch_lifo 1.008 -> 1.259.
= []
[]
= { = "0.60", = [
"Win32_Foundation",
"Win32_System_Memory",
"Win32_System_SystemInformation",
"Win32_System_Threading",
"Win32_System_Performance",
"Win32_System_ProcessStatus",
"Win32_Security_Cryptography",
] }
[]
= { = "0.2", = false }
[]
= "0.7"
# H-28: the documented invariants get PROPERTIES, not just examples. Kept
# dev-only and vet-exempted at safe-to-run — it can never reach a published
# artifact.
= { = "1", = false, = ["std"] }
[]
= true