mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
### What? Adds `TurboMalloc::thread_park()` — a new method on `TurboMalloc` that calls `libmimalloc_sys::mi_collect(false)` to process mimalloc's lazy free lists when a Tokio worker thread parks. Registers it as an `on_thread_park` callback in every Tokio runtime that already registers `on_thread_stop`: - `turbopack-cli/src/main.rs` - `turbopack-cli/benches/small_apps.rs` - `next-napi-bindings/src/lib.rs` - `next-build-test/src/main.rs` - `turbo-tasks-backend/fuzz/src/graph.rs` ### Why? mimalloc uses deferred freeing: memory freed by one thread is not reclaimed immediately but is queued until that thread performs N more allocations. Tokio worker threads that are parked (waiting for work) don't allocate, so deferred frees accumulate indefinitely — memory is never returned to the OS until the thread wakes up and does real work. Calling `mi_collect(false)` on park processes the lazy free lists, allowing mimalloc to reclaim that memory, while avoiding the syscalls and globally synchronized operations that `mi_collect(true)` would trigger. ### How? - `thread_park()` only calls `mi_collect(false)` — it intentionally does **not** call `flush()`. `flush()` transfers the thread-local allocation counter to the global atomic and resets it to zero, which would violate the trace server's assumption that per-thread counters are monotonically increasing. Counter sync remains exclusively in `thread_stop()`. - `thread_park()` is feature-gated behind `cfg(all(feature = "custom_allocator", not(target_family = "wasm")))` and is a no-op otherwise. - `libmimalloc-sys` is added as a direct optional dependency under `[target.'cfg(not(target_family = "wasm"))'.dependencies]` (it was already a transitive dep via `mimalloc`) to access `mi_collect` directly, since `mimalloc`'s `use ffi::*` is not a public re-export. - In each `on_thread_park` callback, `TurboMalloc::thread_park()` is called **after** the existing SWC atom store GC, so atoms freed by that GC pass are also eligible for reclamation in the same collection. <!-- NEXT_JS_LLM_PR --> --------- Co-authored-by: Tobias Koppers <[email protected]> Co-authored-by: Claude <[email protected]>
35 lines
853 B
TOML
35 lines
853 B
TOML
[package]
|
|
name = "turbo-tasks-malloc"
|
|
version = "0.1.0"
|
|
description = "A wrapper around mimalloc or the system allocator that tracks allocations"
|
|
license = "MIT"
|
|
edition = "2024"
|
|
autobenches = false
|
|
|
|
[lib]
|
|
bench = false
|
|
|
|
[dependencies]
|
|
|
|
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
|
libmimalloc-sys = { version = "0.1.44", features = [
|
|
"extended",
|
|
], optional = true }
|
|
|
|
[target.'cfg(not(any(target_os = "linux", target_family = "wasm")))'.dependencies]
|
|
mimalloc = { version = "0.1.48", features = [
|
|
"v3",
|
|
"extended",
|
|
], optional = true }
|
|
|
|
[target.'cfg(all(target_os = "linux", not(target_family = "wasm")))'.dependencies]
|
|
mimalloc = { version = "0.1.48", features = [
|
|
"v3",
|
|
"extended",
|
|
"local_dynamic_tls",
|
|
], optional = true }
|
|
|
|
[features]
|
|
custom_allocator = ["dep:mimalloc", "dep:libmimalloc-sys"]
|
|
default = ["custom_allocator"]
|