feat(binding): allocation-tracking global allocator behind the tracking_allocator feature - #10703
Merged
Merged
Conversation
✅ Deploy Preview for rolldown-rs canceled.
|
tracking_allocator feature
IWANABETHATGUY
marked this pull request as draft
August 19, 2026 02:14
IWANABETHATGUY
force-pushed
the
feat/tracking-allocator
branch
from
August 19, 2026 02:17
b674ade to
feb2dca
Compare
…ature Adds crates/rolldown_tracking_allocator, a mimalloc wrapper that counts live/peak bytes and alloc/realloc calls for the Rust side only, so the numbers are free of V8 heap and GC noise. rolldown_binding installs it behind the new `tracking_allocator` feature and exposes getNativeMemoryStats()/resetNativeMemoryStats(); without the feature the functions return null and plain mimalloc stays. The counters batch per thread (flush every 64 KiB of drift or 1024 ops). Per-allocation global atomics serialize the worker threads on shared cache lines and cost +31%..+201% on the bundle@ benches; the batched version measures -0.1%..+2.3% vs plain mimalloc, compared with `cargo bench -p bench --features tracking_allocator -- 'bundle@'`. The smoke test holds ballast and allows batch-sized drift, because stats() clamps a negative balance to zero and a harness thread can leave a small negative drift before the test runs.
IWANABETHATGUY
force-pushed
the
feat/tracking-allocator
branch
from
August 19, 2026 02:29
88b66d5 to
e76585e
Compare
IWANABETHATGUY
marked this pull request as ready for review
August 19, 2026 02:37
Merging this PR will not alter performance
Comparing Footnotes
|
A thread that exited below the batching thresholds lost its pending deltas, while a cross-thread free of the same memory was still counted. Rolldown retires threads in normal operation (expiring spawn_blocking threads, the short-lived sourcemap thread), so repeated builds could drive the balance negative without bound and stats() then reported liveBytes: 0. An exit guard now flushes a thread's pending deltas at teardown; operations during guard registration or after its destruction update the globals directly.
hyfdev
approved these changes
Aug 19, 2026
h-a-n-a
approved these changes
Aug 19, 2026
shulaoda
approved these changes
Aug 19, 2026
IWANABETHATGUY
added a commit
that referenced
this pull request
Aug 19, 2026
This PR makes the node benchmark build with the `tracking_allocator` feature and record each suite's peak Rust-side memory above its starting floor, emitted as `<suite> (peak memory)` rows (unit `bytes`) in the JSON the benchmark action already tracks. The allocator tier is used instead of `process.memoryUsage()` because allocator peaks stay stable across fresh-process rounds (CV 0.03-3.1% per suite) while polled RSS deltas swing (CV 2.9-136%). On a stock binding the stats return null and the output is unchanged. requires #10703
shulaoda
reviewed
Aug 19, 2026
| pub mod binding_watcher_bundler; | ||
| pub mod classic_bundler; | ||
| mod generated; | ||
| pub mod native_memory; |
Member
There was a problem hiding this comment.
Could we also add a cfg default_global_allocator feature gate?
Member
Author
There was a problem hiding this comment.
gate the native_memory module itself out — is not reasonable, for two concrete reasons:
- napi codegen generates from the compiled crate, so a cfg-gated module changes the export surface per feature set. binding.cjs and binding.d.cts would differ between builds, and the generated-code check in CI would fail for whichever build did not produce the committed files.
- The stacked bench PR imports getNativeMemoryStats from rolldown/experimental unconditionally and branches on null. A vanishing export turns that graceful branch into an import error on every stock binding.
Merged
shulaoda
added a commit
that referenced
this pull request
Aug 19, 2026
## [1.2.5] - 2026-08-19 ### 🚀 Features - bench: record per-suite peak memory in the node benchmark (#10704) by @IWANABETHATGUY - binding: allocation-tracking global allocator behind the `tracking_allocator` feature (#10703) by @IWANABETHATGUY - add armv7 android (armv7-linux-androideabi) support (#10691) by @shulaoda - add `NAMESPACE_CONFLICT` warning for conflicting star re-exports (#7452) by @AliceLanniste ### 🐛 Bug Fixes - rolldown_plugin_vite_reporter: avoid ANSI erase-line escape in non-TTY output (#10692) by @shulaoda - rolldown_plugin_vite_resolve: preserve Yarn PnP virtual importer (#10591) by @Freakazo - exclude hash placeholders from case-insensitive filename deconfliction (#10590) by @Nic-Polumeyv - code-splitting: fold already-loaded side-effectful libraries into eager entries (#10645) by @JoviDeCroock - dev: flush re-emitted assets when their content changes (#10637) by @btea - renamer: rename nested `require`/`__filename`/`__dirname` bindings in CJS output (#10655) by @marcoroth - silence two wasm-only warnings (#10668) by @IWANABETHATGUY ### 🚜 Refactor - skip case folding for filenames with hash placeholders (#10689) by @hyfdev - code-splitting: remove redundant synthetic statement owner (#10503) by @hyfdev - renamer: move the cjs check into `rename_bindings_shadowing_cjs_ambient_names` (#10672) by @IWANABETHATGUY ### 📚 Documentation - agents: point the never-edit list at the binding files that exist (#10719) by @melbinjp ### 🧪 Testing - deconflict: pin renaming the external process binding away from the global (#10702) by @hyfdev - dev: expect a hot update across a circular import (#10700) by @hyfdev ### ⚙️ Miscellaneous Tasks - deps: upgrade oxc to 0.146.0 (#10707) by @Boshen - deps: update rust crates (#10684) by @renovate[bot] - deps: update npm packages (#10685) by @renovate[bot] - build the benchmark comparison window from the JSON lines (#10701) by @IWANABETHATGUY - wasi: retry the Node Test step to absorb the shared-dlmalloc flake (#10699) by @hyfdev - append benchmark results to storage as JSON lines (#10682) by @IWANABETHATGUY - deps: update github actions (#10683) by @renovate[bot] - deps: update dependency rolldown-plugin-dts to v0.28.2 (#10679) by @renovate[bot] - deps: update dependency rolldown-plugin-dts to v0.28.1 (#10674) by @renovate[bot] ### ❤️ New Contributors * @melbinjp made their first contribution in [#10719](#10719) * @Freakazo made their first contribution in [#10591](#10591) * @marcoroth made their first contribution in [#10655](#10655) Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds a
tracking_allocatorcargo feature to the binding so that a build can report live and peak Rust-side memory to JS, exposed asgetNativeMemoryStats/resetNativeMemoryStats. Enabling it shifts timing by at most ~2.3%; a stock build is unchanged.