Skip to content

feat(binding): allocation-tracking global allocator behind the tracking_allocator feature - #10703

Merged
IWANABETHATGUY merged 3 commits into
mainfrom
feat/tracking-allocator
Aug 19, 2026
Merged

IWANABETHATGUY merged 3 commits into
mainfrom
feat/tracking-allocator

Conversation

@IWANABETHATGUY

@IWANABETHATGUY IWANABETHATGUY commented Aug 18, 2026 •

Copy link
Copy Markdown
Member

This PR adds a tracking_allocator cargo feature to the binding so that a build can report live and peak Rust-side memory to JS, exposed as getNativeMemoryStats / resetNativeMemoryStats. Enabling it shifts timing by at most ~2.3%; a stock build is unchanged.

@IWANABETHATGUY
IWANABETHATGUY marked this pull request as ready for review August 18, 2026 15:54
@netlify

netlify Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit e2dc671
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/6a8522136843f300082ac1d5

@IWANABETHATGUY IWANABETHATGUY changed the title feat/tracking allocator feat(binding): allocation-tracking global allocator behind the tracking_allocator feature Aug 19, 2026
@IWANABETHATGUY
IWANABETHATGUY marked this pull request as draft August 19, 2026 02:14
@IWANABETHATGUY
IWANABETHATGUY force-pushed the feat/tracking-allocator branch from b674ade to feb2dca Compare August 19, 2026 02:17
IWANABETHATGUY and others added 2 commits August 19, 2026 10:29
…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
IWANABETHATGUY force-pushed the feat/tracking-allocator branch from 88b66d5 to e76585e Compare August 19, 2026 02:29
@IWANABETHATGUY
IWANABETHATGUY marked this pull request as ready for review August 19, 2026 02:37
@codspeed

codspeed Bot commented Aug 19, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 7 untouched benchmarks
⏩ 10 skipped benchmarks1


Comparing feat/tracking-allocator (e2dc671) with main (4cde06d)

Open in CodSpeed

Footnotes

  1. 10 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

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.
@IWANABETHATGUY
IWANABETHATGUY merged commit 2d0cac8 into main Aug 19, 2026
36 checks passed
@IWANABETHATGUY
IWANABETHATGUY deleted the feat/tracking-allocator branch August 19, 2026 03:42
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
pub mod binding_watcher_bundler;
pub mod classic_bundler;
mod generated;
pub mod native_memory;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also add a cfg default_global_allocator feature gate?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gate the native_memory module itself out — is not reasonable, for two concrete reasons:

  1. 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.
  2. 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.

@rolldown-guard rolldown-guard Bot mentioned this pull request Aug 19, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Sponsor
SponsoredKunjungi sekarang
Promo