From 9d312aa670c3df535e38ab0b1479637f65f75fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 23 Apr 2026 07:40:11 +0200 Subject: [PATCH 1/6] Use global Rust jemalloc --- Cargo.lock | 13 ++++++++++++- compiler/rustc/Cargo.toml | 2 +- compiler/rustc_driver_impl/Cargo.toml | 6 ++++++ compiler/rustc_driver_impl/src/lib.rs | 4 ++++ src/tools/tidy/src/deps.rs | 1 + 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ac10d7d4fb53..9a8ff6bb250a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -756,7 +756,7 @@ checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", - "unicode-width 0.1.14", + "unicode-width 0.2.2", ] [[package]] @@ -3837,6 +3837,7 @@ dependencies = [ "rustc_target", "serde_json", "shlex", + "tikv-jemallocator", "tracing", "windows 0.61.3", ] @@ -5551,6 +5552,16 @@ dependencies = [ "libc", ] +[[package]] +name = "tikv-jemallocator" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0359b4327f954e0567e69fb191cf1436617748813819c94b8cd4a431422d053a" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + [[package]] name = "tinystr" version = "0.8.2" diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 8cef9e0644bb0..6b65c5d1abdfd 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -35,7 +35,7 @@ features = ['override_allocator_on_supported_platforms'] [features] # tidy-alphabetical-start check_only = ['rustc_driver_impl/check_only'] -jemalloc = ['dep:tikv-jemalloc-sys'] +jemalloc = ['dep:tikv-jemalloc-sys', 'rustc_driver_impl/jemalloc'] llvm = ['rustc_driver_impl/llvm'] llvm_enzyme = ['rustc_driver_impl/llvm_enzyme'] llvm_offload = ['rustc_driver_impl/llvm_offload'] diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 10e1b1987194a..89b3c9440351a 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -55,9 +55,15 @@ features = [ ctrlc = "3.4.4" # tidy-alphabetical-end +[dependencies.tikv-jemallocator] +version = "0.6.1" +optional = true +features = ['override_allocator_on_supported_platforms'] + [features] # tidy-alphabetical-start check_only = ['rustc_interface/check_only'] +jemalloc = ['dep:tikv-jemallocator'] llvm = ['rustc_interface/llvm'] llvm_enzyme = ['rustc_interface/llvm_enzyme'] llvm_offload = ['rustc_interface/llvm_offload'] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index c15c3c229398c..a7c9b4897d317 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -63,6 +63,10 @@ use rustc_target::json::ToJson; use rustc_target::spec::{Target, TargetTuple}; use tracing::trace; +#[cfg(feature = "jemalloc")] +#[global_allocator] +static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + #[allow(unused_macros)] macro do_not_use_print($($t:tt)*) { std::compile_error!( diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 1d12456d2bb23..60a3de06f7272 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -442,6 +442,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "thorin-dwp", "thread_local", "tikv-jemalloc-sys", + "tikv-jemallocator", "tinystr", "tinyvec", "tinyvec_macros", From fe8fc27b2953dd1e216a11c85e6431170a5aa51b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 27 Apr 2026 10:19:41 +0200 Subject: [PATCH 2/6] w --- compiler/rustc/Cargo.toml | 1 - compiler/rustc/src/main.rs | 65 +++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 6b65c5d1abdfd..1886ff7c27e7a 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -30,7 +30,6 @@ wasi = "=0.14.2" [dependencies.tikv-jemalloc-sys] version = "0.6.1" optional = true -features = ['override_allocator_on_supported_platforms'] [features] # tidy-alphabetical-start diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index 30d64b05cfde9..1fc12abb8b7d1 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -3,6 +3,7 @@ // Several crates are depended upon but unused so that they are present in the sysroot #![expect(unused_crate_dependencies)] +use std::os::raw::{c_char, c_int, c_void}; use std::process::ExitCode; // A note about jemalloc: rustc uses jemalloc when built for CI and @@ -37,8 +38,70 @@ use std::process::ExitCode; // to compare their performance, see // https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef // for an example of how to do so. + #[cfg(feature = "jemalloc")] -use tikv_jemalloc_sys as _; +mod c_alloc { + #[used] + static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = calloc; + #[used] + static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = posix_memalign; + #[used] + static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = aligned_alloc; + #[used] + static _F4: unsafe extern "C" fn(usize) -> *mut c_void = malloc; + #[used] + static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = realloc; + #[used] + static _F6: unsafe extern "C" fn(*mut c_void) = free; + //#[used] + //static _F7: unsafe extern "C" fn(*const c_char) -> *mut c_char = strdup; + + // On OSX, jemalloc doesn't directly override malloc/free, but instead + // registers itself with the allocator's zone APIs in a ctor. However, + // the linker doesn't seem to consider ctors as "used" when statically + // linking, so we need to explicitly depend on the function. + #[cfg(target_os = "macos")] + { + unsafe extern "C" { + fn _rjem_je_zone_register(); + } + + #[used] + static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; + } + + #[unsafe(no_mangle)] + unsafe extern "C" fn calloc(items: usize, size: usize) -> *mut c_void { + unsafe { jemalloc_sys::calloc(items, size) } + } + + #[unsafe(no_mangle)] + unsafe extern "C" fn posix_memalign(ptr: *mut *mut c_void, size: usize, align: usize) -> c_int { + unsafe { jemalloc_sys::posix_memalign(ptr, size, align) } + } + + #[unsafe(no_mangle)] + unsafe extern "C" fn aligned_alloc(size: usize, align: usize) -> *mut c_void { + jemalloc_sys::aligned_alloc(size, align) + } + + #[unsafe(no_mangle)] + unsafe extern "C" fn malloc(size: usize) -> *mut c_void { + jemalloc_sys::malloc(size) + } + + #[unsafe(no_mangle)] + unsafe extern "C" fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void { + unsafe { jemalloc_sys::realloc(ptr, size) } + } + + #[unsafe(no_mangle)] + unsafe extern "C" fn free(ptr: *mut c_void) { + unsafe { + jemalloc_sys::free(ptr); + } + } +} fn main() -> ExitCode { rustc_driver::main() From df19d996aa615a42cd776833ba566f6201421c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 27 Apr 2026 10:35:49 +0200 Subject: [PATCH 3/6] w --- compiler/rustc/src/main.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index 1fc12abb8b7d1..e892ad9e144a0 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -3,7 +3,6 @@ // Several crates are depended upon but unused so that they are present in the sysroot #![expect(unused_crate_dependencies)] -use std::os::raw::{c_char, c_int, c_void}; use std::process::ExitCode; // A note about jemalloc: rustc uses jemalloc when built for CI and @@ -41,6 +40,7 @@ use std::process::ExitCode; #[cfg(feature = "jemalloc")] mod c_alloc { + use std::os::raw::{c_int, c_void}; #[used] static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = calloc; #[used] @@ -53,52 +53,49 @@ mod c_alloc { static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = realloc; #[used] static _F6: unsafe extern "C" fn(*mut c_void) = free; - //#[used] - //static _F7: unsafe extern "C" fn(*const c_char) -> *mut c_char = strdup; // On OSX, jemalloc doesn't directly override malloc/free, but instead // registers itself with the allocator's zone APIs in a ctor. However, // the linker doesn't seem to consider ctors as "used" when statically // linking, so we need to explicitly depend on the function. #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; + unsafe extern "C" { + fn _rjem_je_zone_register(); } + #[used] + #[cfg(target_os = "macos")] + static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; + #[unsafe(no_mangle)] unsafe extern "C" fn calloc(items: usize, size: usize) -> *mut c_void { - unsafe { jemalloc_sys::calloc(items, size) } + unsafe { tikv_jemalloc_sys::calloc(items, size) } } #[unsafe(no_mangle)] unsafe extern "C" fn posix_memalign(ptr: *mut *mut c_void, size: usize, align: usize) -> c_int { - unsafe { jemalloc_sys::posix_memalign(ptr, size, align) } + unsafe { tikv_jemalloc_sys::posix_memalign(ptr, size, align) } } #[unsafe(no_mangle)] unsafe extern "C" fn aligned_alloc(size: usize, align: usize) -> *mut c_void { - jemalloc_sys::aligned_alloc(size, align) + unsafe { tikv_jemalloc_sys::aligned_alloc(size, align) } } #[unsafe(no_mangle)] unsafe extern "C" fn malloc(size: usize) -> *mut c_void { - jemalloc_sys::malloc(size) + unsafe { tikv_jemalloc_sys::malloc(size) } } #[unsafe(no_mangle)] unsafe extern "C" fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void { - unsafe { jemalloc_sys::realloc(ptr, size) } + unsafe { tikv_jemalloc_sys::realloc(ptr, size) } } #[unsafe(no_mangle)] unsafe extern "C" fn free(ptr: *mut c_void) { unsafe { - jemalloc_sys::free(ptr); + tikv_jemalloc_sys::free(ptr); } } } From 6cde8d2d16ac39724ba602fabb672ff18a7dcab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 27 Apr 2026 11:17:19 +0200 Subject: [PATCH 4/6] w --- compiler/rustc_driver_impl/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 89b3c9440351a..ea29658a297df 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -58,7 +58,6 @@ ctrlc = "3.4.4" [dependencies.tikv-jemallocator] version = "0.6.1" optional = true -features = ['override_allocator_on_supported_platforms'] [features] # tidy-alphabetical-start From b966e9fca85fe5729263b81e7f044f7ded1b7177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 27 Apr 2026 13:55:27 +0200 Subject: [PATCH 5/6] w --- Cargo.lock | 1 + compiler/rustc/src/main.rs | 12 +++++------ compiler/rustc_driver_impl/Cargo.toml | 6 +++++- compiler/rustc_driver_impl/src/lib.rs | 30 +++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a8ff6bb250a5..494535542f3a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3837,6 +3837,7 @@ dependencies = [ "rustc_target", "serde_json", "shlex", + "tikv-jemalloc-sys", "tikv-jemallocator", "tracing", "windows 0.61.3", diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index e892ad9e144a0..ab1918a428901 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -69,33 +69,33 @@ mod c_alloc { #[unsafe(no_mangle)] unsafe extern "C" fn calloc(items: usize, size: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::calloc(items, size) } + unsafe { rustc_driver::jemalloc::calloc(items, size) } } #[unsafe(no_mangle)] unsafe extern "C" fn posix_memalign(ptr: *mut *mut c_void, size: usize, align: usize) -> c_int { - unsafe { tikv_jemalloc_sys::posix_memalign(ptr, size, align) } + unsafe { rustc_driver::jemalloc::posix_memalign(ptr, size, align) } } #[unsafe(no_mangle)] unsafe extern "C" fn aligned_alloc(size: usize, align: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::aligned_alloc(size, align) } + unsafe { rustc_driver::jemalloc::aligned_alloc(size, align) } } #[unsafe(no_mangle)] unsafe extern "C" fn malloc(size: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::malloc(size) } + unsafe { rustc_driver::jemalloc::malloc(size) } } #[unsafe(no_mangle)] unsafe extern "C" fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::realloc(ptr, size) } + unsafe { rustc_driver::jemalloc::realloc(ptr, size) } } #[unsafe(no_mangle)] unsafe extern "C" fn free(ptr: *mut c_void) { unsafe { - tikv_jemalloc_sys::free(ptr); + rustc_driver::jemalloc::free(ptr); } } } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index ea29658a297df..fe9243ce62b5b 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -59,10 +59,14 @@ ctrlc = "3.4.4" version = "0.6.1" optional = true +[dependencies.tikv-jemalloc-sys] +version = "0.6.1" +optional = true + [features] # tidy-alphabetical-start check_only = ['rustc_interface/check_only'] -jemalloc = ['dep:tikv-jemallocator'] +jemalloc = ['dep:tikv-jemallocator', 'dep:tikv-jemalloc-sys'] llvm = ['rustc_interface/llvm'] llvm_enzyme = ['rustc_interface/llvm_enzyme'] llvm_offload = ['rustc_interface/llvm_offload'] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index a7c9b4897d317..78a0648387aa8 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -64,9 +64,39 @@ use rustc_target::spec::{Target, TargetTuple}; use tracing::trace; #[cfg(feature = "jemalloc")] +mod jemalloc { + use std::os::raw::{c_int, c_void}; + #[global_allocator] static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; +unsafe extern "C" fn calloc(items: usize, size: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::calloc(items, size) } +} + +unsafe extern "C" fn posix_memalign(ptr: *mut *mut c_void, size: usize, align: usize) -> c_int { + unsafe { tikv_jemalloc_sys::posix_memalign(ptr, size, align) } +} + +unsafe extern "C" fn aligned_alloc(size: usize, align: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::aligned_alloc(size, align) } +} + +unsafe extern "C" fn malloc(size: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::malloc(size) } +} + +unsafe extern "C" fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::realloc(ptr, size) } +} + +unsafe extern "C" fn free(ptr: *mut c_void) { + unsafe { + tikv_jemalloc_sys::free(ptr); + } +} +} + #[allow(unused_macros)] macro do_not_use_print($($t:tt)*) { std::compile_error!( From 33d8da8b9e63e8bb6755a6cec7247a8e615e5278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 27 Apr 2026 14:19:36 +0200 Subject: [PATCH 6/6] w --- compiler/rustc_driver_impl/src/lib.rs | 48 +++++++++++++++------------ 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 78a0648387aa8..dda7397e3496b 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -64,38 +64,42 @@ use rustc_target::spec::{Target, TargetTuple}; use tracing::trace; #[cfg(feature = "jemalloc")] -mod jemalloc { +pub mod jemalloc { use std::os::raw::{c_int, c_void}; -#[global_allocator] -static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + #[global_allocator] + static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; -unsafe extern "C" fn calloc(items: usize, size: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::calloc(items, size) } -} + pub unsafe extern "C" fn calloc(items: usize, size: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::calloc(items, size) } + } -unsafe extern "C" fn posix_memalign(ptr: *mut *mut c_void, size: usize, align: usize) -> c_int { - unsafe { tikv_jemalloc_sys::posix_memalign(ptr, size, align) } -} + pub unsafe extern "C" fn posix_memalign( + ptr: *mut *mut c_void, + size: usize, + align: usize, + ) -> c_int { + unsafe { tikv_jemalloc_sys::posix_memalign(ptr, size, align) } + } -unsafe extern "C" fn aligned_alloc(size: usize, align: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::aligned_alloc(size, align) } -} + pub unsafe extern "C" fn aligned_alloc(size: usize, align: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::aligned_alloc(size, align) } + } -unsafe extern "C" fn malloc(size: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::malloc(size) } -} + pub unsafe extern "C" fn malloc(size: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::malloc(size) } + } -unsafe extern "C" fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void { - unsafe { tikv_jemalloc_sys::realloc(ptr, size) } -} + pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void { + unsafe { tikv_jemalloc_sys::realloc(ptr, size) } + } -unsafe extern "C" fn free(ptr: *mut c_void) { - unsafe { - tikv_jemalloc_sys::free(ptr); + pub unsafe extern "C" fn free(ptr: *mut c_void) { + unsafe { + tikv_jemalloc_sys::free(ptr); + } } } -} #[allow(unused_macros)] macro do_not_use_print($($t:tt)*) {