Repository navigation
Expand file tree
/
Copy pathCargo.toml
More file actions
227 lines (218 loc) · 12.8 KB
/
Copy pathCargo.toml
File metadata and controls
227 lines (218 loc) · 12.8 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
[workspace]
resolver = "2"
members = [
"crates/rusty_alloc",
"crates/rusty_alloc_api",
"crates/rusty_alloc_ffi",
"crates/rusty_alloc_override",
"crates/rusty_alloc_bench",
"crates/rusty_alloc_wasm",
]
[workspace.package]
# 1.0.0: the API is frozen; changes follow semver from here. The allocator is
# complete and gated; the wall-clock half of the performance evidence still
# needs a quiet box, so only instruction-count claims are made (README says so).
#
# 1.0.0: API frozen. The 2026-08-20 optimization campaign (docs/opps.md)
# sharpened the per-op margins — calloc 0.95->0.82, realloc 0.79->0.76,
# big/large/mixed nudged down — on top of the 0.7.0 fast-path work, and the
# `use-protection-please` security audit reached 14/15 v1.0.0 gates with a
# time-bound owner waiver on H-27 (the 30-day fuzz soak, mechanism live,
# completes 2026-09-19). Every op of the per-op scan is at-or-below mimalloc
# except batch (a measured safe-Rust codegen floor, +0.8%); all three
# real-program arms and the full mimalloc-bench corpus run clean.
# 1.0.1 — patch. No API change. `free`'s fast path went 27 instructions to 21
# (mimalloc's is 25): the `used--` codegen floor `docs/opps.md` #6 recorded as
# unreachable from safe Rust is closed, the thread-id read is folded into its
# compare, and resolving a pointer to its page dropped from nine instructions
# to five on a per-slice owner table in the segment header. Allocator-only
# ratios against mimalloc on real programs moved lua 0.75->0.66, perl
# 0.95->0.83, sqlite 0.98->0.85; every op of the per-op scan is now BELOW
# mimalloc, batch included.
#
# 1.1.0 — MINOR, and minor rather than patch for exactly one reason: it adds a
# public item, `bins::is_aligned_to`. Nothing is removed or changed, so every
# 1.0.x user compiles unchanged. The new function is total — a non-power-of-two
# alignment returns `false`, the conservative answer at every call site — which
# is what makes it safe to expose. The other helpers this release introduced
# (`div_by_block_size`, `exact_div_by_block_size`) are deliberately
# `pub(crate)`: both carry preconditions and return a wrong value rather than
# diverging outside them, and that does not belong in a frozen public API.
#
# The release itself: **the allocator no longer divides.** Zero `div`/`idiv`,
# zero `divsd`/`divss`, zero 128-bit soft-division libcalls, and zero
# magic-multiply divisions by `size_of::<Page>()` — verified in the shipped
# object, not inferred from source. 60 `div` instructions removed in all.
# `docs/opps.md` #1 (`page_index`'s divide by 88, open since it was filed) is
# closed at ZERO header cost: `Page::area` already encodes the slice index and
# `SEGMENT_SLICE_SIZE` is 2^16, so the index is a shift — the spare-field the
# entry proposed was never needed. `free_general` went 148 instructions to 112
# and `usable_size_slow` 93 to 55 when the block-size division's four-arm match
# became a branchless reciprocal table.
#
# One latent defect fixed on the way: huge segments build their single page
# slot by hand and never wrote `Page::area`, so it held null. Nothing read it
# before; `page_index` and `unalign` both do now.
#
# Windows: the QPC tick-to-nanosecond conversion no longer calls `__udivti3`.
#
# Real-program numbers are UNCHANGED at the precision the README prints —
# lua 0.97, perl 0.99, sqlite 1.00 whole-program; 0.66/0.83/0.85 allocator-only
# — and all 13 per-op scans remain below mimalloc. This release is a
# code-size and cycle result that the instruction counter mostly cannot see;
# said plainly rather than dressed up.
#
# 1.1.1 — patch. No API change, and no behaviour change on any platform whose
# page size is a power of two, which is all of them. It restores the Kani
# proof `good_size_never_shrinks_a_request`, which 1.1.0 broke.
#
# `page_align_up`'s round-up mask was built from `ps - 1`, guarded by a
# `debug_assert` that the page size is a power of two. That assertion is true
# on every real platform but is NOT provable: `ps` is read from an atomic
# cache of an OS value, so Kani models it as arbitrary, where `ps - 1`
# underflows at zero and the mask is not a round-up at all. The mask is now
# built from the page size's trailing zeros — `1 << (tz & 63)` is a power of
# two for EVERY input, including 0 — which makes the property structural
# rather than asserted and the function total. On a real platform
# `1 << ps.trailing_zeros() == ps`, so the arithmetic is unchanged for one
# `tzcnt` and one `shl`; all 26 divide removals that motivated the mask stay,
# and every opscan op is byte-identical.
#
# How it shipped: the `proofs` job runs only on a weekly cron and manual
# dispatch, and that cron had NEVER fired — the harnesses had not run in CI
# once, for any release. `ci.yml` now also runs them on `v*` tags, so a
# release cannot ship an unverified proof again.
#
# 1.1.2 — patch. No API change. **Windows gets faster; nothing else moves.**
#
# The division campaign that produced 1.1.0 measured every one of its "zero
# divisions" claims on the Linux `.so`, and `prim/windows.rs` is not compiled
# into that object — so five rounds of scanning had never read it. Emitting
# assembly for the msvc target found TEN integer divisions there:
#
# * `prim::alloc` x4 — two `is_multiple_of(try_alignment)` on a RUNTIME
# divisor, the same shape D7/D12/D19 removed from eight other sites, on
# the OS reservation path every segment goes through. Now the same mask,
# whose conservative direction is the safe one here: a `false` falls
# through to the aligned-reservation retry rather than accepting a block.
# * `prim::clock_now` x2 — `is_multiple_of` IS a modulo, so 1.1.0's
# `if 1e9.is_multiple_of(freq) { 1e9 / freq }` divided twice to answer
# once. `q * freq == 1e9` answers it after one division and cannot
# overflow.
# * `random::reseed` x2 — `clock_now` inlined into it.
# * `stats::process_info` x2 — display conversions, already minimal.
#
# **10 -> 3, and `prim::alloc` 4 -> 0.** What remains is one once-per-process
# `1e9 / freq`, the same one inlined into `reseed`, and the ms conversion.
#
# macOS (x86-64 and aarch64) and wasm32 were audited the same way and are
# already at **zero** — the Unix backend never had that shape. Those scans are
# kept as `tools/div-scan-targets.sh` with a self-test that proves each ISA's
# pattern actually fires (`udiv`/`i64.div_u` are invisible to an x86 `div`
# grep, so a zero from the wrong pattern looks exactly like a clean result).
#
# Linux is byte-identical: cfrac allocator 3,445,578,308, `free` 21.000
# Ir/call, all 13 opscan ops unchanged, zero divisions of every class.
#
# 1.1.3 — patch, README only. **No code change whatsoever**: the compiled
# artifact is byte-identical to 1.1.2. Adds the shared "Remade With Rust
# ecosystem" section (the ORG BOILERPLATE block kept identical across the
# org's repos) above the licence.
#
# It needs a version bump because crates.io renders the README baked into the
# published `.crate` tarball — editing the file in the repository cannot
# change an already-published version's page.
#
# 1.1.4 — patch, README only again, and 1.1.3 is why this exists. That release
# added the ecosystem section to the WORKSPACE-ROOT README, which is the
# GitHub-facing one. Each published crate declares `readme = "README.md"`,
# resolved relative to its own directory, so crates.io renders
# `crates/rusty_alloc/README.md` and `crates/rusty_alloc_api/README.md` — two
# different files that never got the section. Fixed here, in both, and
# verified by extracting the packaged `.crate` before publishing rather than
# checking the live page afterwards.
version = "2.2.7"
edition = "2024"
# MSRV. Declared for the first time in 1.0.1 because this release genuinely
# needs it: `asm!` label blocks (`asm_goto`, stable 1.87) carry the free path's
# memory-destination decrement, and a let-chain needs 1.88. Without this an
# older toolchain fails with a syntax error instead of a version message.
rust-version = "1.88"
license = "MIT"
repository = "https://github.com/remade-with-rust/rusty_alloc"
# Portfolio convention (matches rusty_h264): homepage is Mata Network, the
# parent org, not the GitHub org.
homepage = "https://www.mata.network/"
authors = ["remade-with-rust"]
keywords = ["allocator", "malloc", "mimalloc", "memory", "no-std"]
categories = ["memory-management", "no-std", "development-tools"]
[workspace.lints.rust]
unsafe_op_in_unsafe_fn = "deny"
# `ra_small_profile` (P2, docs/plans/small-metal.md) selects the chip geometry.
# A --cfg rather than a cargo feature ON PURPOSE: features are additive and
# unify across the dependency graph, so two consumers wanting different
# geometries would silently get one of them. A cfg is set by the DELIVERABLE,
# the same way a Janus firmware picks its chip.
unexpected_cfgs = { level = "warn", check-cfg = ["cfg(loom)", "cfg(kani)", "cfg(ra_small_profile)", "cfg(ra_single_threaded)", "cfg(ra_max_extents, values(\"8\", \"16\", \"64\"))", "cfg(ra_aligned_region)", "cfg(ra_segment_size, values(\"256k\"))", "cfg(ra_generic_collect, values(\"64\", \"4096\", \"65536\"))", "cfg(ra_small_wsize, values(\"256\", \"512\"))"] }
# Lint policy (hardening gate H-15). `pedantic` and `nursery` are ENABLED at
# workspace level and the build is clean under them, because every group
# member we do not enforce is listed below WITH ITS REASON. That is the point
# of the exercise: ~95 additional lints are now enforced, and the ones we
# decline are a deliberate, readable list rather than an unexamined
# `#![allow(clippy::pedantic)]`.
#
# Measured 2026-08-19: switching both groups on raised 481 warnings across
# ~25 distinct lints. Every one was triaged into the table below.
[workspace.lints.clippy]
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
undocumented_unsafe_blocks = "deny"
# --- Declined: DOCUMENTATION STYLE ------------------------------------------
# This crate's docs deliberately read as prose explaining a mechanism (why a
# brick exists, what a measurement showed). These lints police house style in
# a way that fights that, and none of them can catch a defect.
doc_markdown = "allow" # 63x: backticks around identifiers in prose
too_long_first_doc_paragraph = "allow" # 26x: our first paragraphs state a mechanism
missing_errors_doc = "allow" # 26x: errors are documented in prose, not a section
missing_panics_doc = "allow" # 13x
missing_safety_doc = "allow" # covered far more strictly by undocumented_unsafe_blocks
# --- Declined: API SHAPE ----------------------------------------------------
must_use_candidate = "allow" # 58x: `#[must_use]` is applied where IGNORING the
# value is a BUG (the 0.4.0 UAF family), not everywhere
# a value is returned - blanket use dilutes that signal
module_name_repetitions = "allow" # 37x: `page::PageQueue` etc. mirror upstream mimalloc's
# names on purpose; this is a 1:1 remake
missing_const_for_fn = "allow" # 23x: const-ness is an API promise; adding it wholesale
# freezes internals we still reshape per measurement
# --- Declined: NUMERIC CASTS — audited, bounded by construction -------------
# 2026-08-19: all 24 cast sites in the SHIPPED library code were read
# individually (H-17). Every one narrows a value bounded by a compile-time
# constant (HEADER_SLICES, SLICES_PER_SEGMENT=512, MAX_ARENAS) or an already
# sign-clamped option (`get(..).max(0)`). NONE narrows an untrusted length,
# which is the failure this lint family exists to catch, and the geometry
# bounds are additionally enforced by const asserts in `segment.rs`.
cast_possible_truncation = "allow"
cast_sign_loss = "allow"
cast_possible_wrap = "allow"
cast_precision_loss = "allow"
cast_ptr_alignment = "allow" # allocator metadata IS the alignment authority
# --- Declined: STYLE PREFERENCES --------------------------------------------
option_if_let_else = "allow" # nursery; `if let/else` reads better in unsafe blocks
redundant_closure_for_method_calls = "allow"
single_match_else = "allow"
explicit_iter_loop = "allow"
use_self = "allow"
many_single_char_names = "allow" # `p`, `b`, `q` are the allocator's own vocabulary
too_many_lines = "allow" # the segment/page state machines are cohesive
semicolon_if_nothing_returned = "allow"
iter_with_drain = "allow"
borrow_as_ptr = "allow" # `&raw` is used where it matters; this fires on tests
inline_always = "allow" # `#[inline(always)]` here is measured, not decorative
[profile.release]
lto = "thin"
codegen-units = 1
panic = "abort"
debug = true # symbols for profiling; strip at distribution, not here
[profile.bench-dist] # distribution-shaped profile for A/B honesty checks
inherits = "release"
debug = false