v1.0.0 — Stable API #7
jamesgober
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
mod-alloc v1.0.0 — Stable API
Date: 2026-05-18
Compare:
v0.9.5...v1.0.0Headline
The public surface is frozen. Breaking changes after
1.0.0require a major version bump per Semantic Versioning.
Path to here: name-claim placeholder in
v0.1.0→ realGlobalAllocimpl inv0.9.0→ inline backtrace capture inv0.9.1→ symbolication inv0.9.2→ DHAT JSON output inv0.9.3→dhat-rsdrop-in surface inv0.9.4→ Tier 2perf optimisation (~32x speedup) in
v0.9.5→ stable APIfreeze in
v1.0.0.One real downstream consumer (
dev-bench v0.9.7) has been liveon crates.io for a day with zero friction. Both Tier 1 and
Tier 2 bench numbers clear REPS section 6 targets with
significant headroom. The DHAT-format JSON output round-trips
cleanly through the upstream
dh_view.htmlviewer. docs.rsbuild passes on all features. MSRV holds at
1.75.What changed in v1.0.0
#[non_exhaustive]on data structs likely to grow fieldsThe public structs and enums most likely to gain new fields in
future minor versions are now
#[non_exhaustive]. Readingfields by name is fully stable; constructing via struct-literal
syntax from outside the crate is no longer supported for these
types. Use the API surfaces that produce them, or
Default::default()-and-mutate.AllocStatsCallSiteStats(backtraces)SymbolicatedFrame(symbolicate)SymbolicatedCallSite(symbolicate)CallSiteStatsdhat_compat::Modedhat_compat::HeapStatsanddhat_compat::AdHocStatsareintentionally left exhaustive. They mirror
dhat-rs'spublic surface field-for-field; the entire point of
dhat_compatis thatuse mod_alloc::dhat_compat as dhat;makes existing dhat-rscode keep compiling. Adding
#[non_exhaustive]here wouldbreak that claim.
Defaultderived on data structsAllocStatsandCallSiteStatsnow deriveDefaultso callershave a non-literal construction path:
dhat_compat::AdHocStatsalready derivedDefault; that stays.Documentation polish
src/lib.rscrate-level rustdoc now carries the fullv0.9.0 → v1.0.0 path summary instead of a v0.9.x-focused
status line.
AllocStatsincludes a "Stability"block explaining the
#[non_exhaustive]choice and therecommended construction pattern.
CallSiteStats,SymbolicatedFrame,SymbolicatedCallSite, anddhat_compat::Mode.No new features
v1.0.0does not add new functionality. The Tier 2 perf pass(v0.9.5), DHAT JSON output (v0.9.3), and
dhat-rsdrop-insurface (v0.9.4) are all already shipped on crates.io.
v1.0.0is purely a stability commitment + the#[non_exhaustive]future-proofing changes above.Frozen public surface
Everything in this list is stable through the
1.xline.Always available
pub struct ModAllocwithpub const fn new(),pub fn snapshot(&self) -> AllocStats,pub fn reset(&self),impl Default,unsafe impl GlobalAllocpub struct AllocStats(#[non_exhaustive], derivesDefault) with public fields:alloc_count: u64total_bytes: u64peak_bytes: u64current_bytes: u64live_count: u64peak_live_count: u64pub struct Profilerwithpub fn start() -> Self,pub fn stop(self) -> AllocStatsbacktracesfeaturepub struct CallSiteStats(#[non_exhaustive], derivesDefault) with public fields:frames: [u64; 8]frame_count: u8count: u64total_bytes: u64pub fn ModAlloc::call_sites(&self) -> Vec<CallSiteStats>MOD_ALLOC_BUCKETS(process-startoverride, default 4096, clamped to
[64, 1_048_576])symbolicatefeaturepub struct SymbolicatedFrame(#[non_exhaustive]) withpublic fields:
address: u64function: Option<String>file: Option<PathBuf>line: Option<u32>inlined: boolpub struct SymbolicatedCallSite(#[non_exhaustive]) withpublic fields:
count: u64total_bytes: u64frames: Vec<SymbolicatedFrame>pub fn ModAlloc::symbolicated_report(&self) -> Vec<SymbolicatedCallSite>dhat-compatfeaturepub fn ModAlloc::dhat_json_string(&self) -> Stringpub fn ModAlloc::write_dhat_json<P: AsRef<Path>>(&self, p: P) -> io::Result<()>pub mod dhat_compatcontaining:pub struct Alloc(unit struct,pub const fn new(),impl Default,unsafe impl GlobalAlloc)pub struct Profilerwithpub fn new_heap(),pub fn new_ad_hoc(),pub fn builder(),impl Droppub struct ProfilerBuilderwithpub fn ad_hoc(),pub fn testing(),pub fn file_name<P>(),pub fn trim_backtraces(),pub fn build()pub enum Mode { Heap, AdHoc }(#[non_exhaustive])pub struct HeapStats(exhaustive, mirrors dhat-rs) withpub fn get()and six public fieldspub struct AdHocStats(exhaustive, mirrors dhat-rs)with
pub fn get()and two public fieldspub fn ad_hoc_event(weight: usize)JSON wire format
dhatFileVersion: 2mode: "rust-heap"(heap profile) or"ad-hoc"(ad-hocprofile)
dh_view.htmlshipped withValgrind
MSRV
1.75, pinned inCargo.tomlviarust-versionandverified by CI on every push.
Bench (held from v0.9.5)
counters, default)backtraces)REPS section 6 targets: Tier 1 <50 ns total, Tier 2 <200 ns of
additional overhead. Both clear with significant headroom.
Verification
Full matrix run on Windows host (x86_64):
cargo build(default features): ✓cargo build --no-default-features: ✓cargo build --features counters: ✓cargo build --features backtraces: ✓cargo build --features symbolicate: ✓cargo build --features dhat-compat: ✓cargo build --all-features: ✓cargo +1.75 build --all-features(MSRV): ✓cargo fmt --all -- --check: ✓cargo clippy --all-targets -- -D warnings: ✓cargo clippy --all-targets --all-features -- -D warnings: ✓cargo clippy --all-targets --no-default-features -- -D warnings: ✓cargo doc --no-deps: ✓cargo doc --all-features --no-deps: ✓cargo test --all-features: 96/96 passcargo run --release --features backtraces --example bench_overhead:62.3 ns per cycle (Tier 2 overhead 16.8 ns, target was <200 ns)
CI matrix: ubuntu-latest, macos-latest, windows-latest plus the
ASAN nightly Linux job.
Migration from
0.9.xFor most callers — no changes required. Every public method
and field name is unchanged. The
#[non_exhaustive]additionsonly affect code that constructed these types via struct-literal
syntax from outside the crate:
AllocStatsCallSiteStatsSymbolicatedFrameSymbolicatedCallSitedhat_compat::ModeFor each such call site, switch to
Default::default()+named-field assignment, or consume the value from the appropriate
API surface (
snapshot,call_sites,symbolicated_report,etc.).
dhat_compat::HeapStats/AdHocStatsare explicitlyexhaustive — drop-in code from
dhat-rskeeps compiling.Stability commitment
From
1.0.0forward:1.0.x).(
1.x.0). Adding fields to#[non_exhaustive]types isconsidered backwards-compatible; adding methods to public
types is considered backwards-compatible.
2.0.0. This includesremoving public items, renaming public fields, tightening
trait bounds on public APIs, raising MSRV beyond
1.75, andchanging the JSON wire format in non-additive ways.
The
MOD_ALLOC_BUCKETSenvironment variable and its[64, 1_048_576]clamp range are part of the stable surface;default behaviour (4096 buckets, ~384 KB) will not change in
the
1.xline.Acknowledgements
This crate exists because
dhat-rs'sbacktrace → addr2linedependency chain forces
MSRV 1.85+, which was incompatiblewith the broader
dev-*family target of1.75.mod-allocprovides equivalent core profiling at MSRV
1.75with zeroruntime dependencies on the alloc hot path and a drop-in
dhat_compatsurface that lets consumers migrate with aone-line import change.
The
dh_view.htmlviewer shipped with Valgrind is what makesthe JSON wire format useful; that work belongs to the upstream
DHAT authors and Valgrind contributors.
Release ceremony
Standard pattern:
git tag -a v1.0.0 -m "Release v1.0.0 - Stable API"git push origin maingit push origin v1.0.0cargo publish --dry-run --all-featurescargo publishhttps://crates.io/crates/mod-alloc/1.0.0is live.GitHub release title:
v1.0.0 — Stable API. Not tagged aspre-release this time — this is the real one.
Full Changelog: v0.9.5...v1.0.0
This discussion was created from the release v1.0.0 — Stable API.
All reactions