diff --git a/Cargo.lock b/Cargo.lock index 4677d34d2a630..3429a08d4fff5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5490,8 +5490,6 @@ version = "0.1.0" [[package]] name = "tikv-jemalloc-sys" version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" dependencies = [ "cc", "libc", diff --git a/Cargo.toml b/Cargo.toml index 67c7a9d67edc8..b1cee8a363d22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,5 +91,5 @@ codegen-units = 1 # If you want to use a crate with local modifications, you can set a path or git dependency here. # For git dependencies, also add your source to ALLOWED_SOURCES in src/tools/tidy/src/extdeps.rs. -#[patch.crates-io] - +[patch.crates-io] +tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys" } diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index ca1bb59e59d60..f4d03674cea2f 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -7,27 +7,22 @@ // distribution. The obvious way to do this is with the `#[global_allocator]` // mechanism. However, for complicated reasons (see // https://github.com/rust-lang/rust/pull/81782#issuecomment-784438001 for some -// details) that mechanism doesn't work here. Also, we must use a consistent -// allocator across the rustc <-> llvm boundary, and `#[global_allocator]` -// wouldn't provide that. +// details) that mechanism doesn't work here. Also, we'd like to use a +// consistent allocator across the rustc <-> llvm boundary, and +// `#[global_allocator]` wouldn't provide that. // -// Instead, we use a lower-level mechanism. rustc is linked with jemalloc in a -// way such that jemalloc's implementation of `malloc`, `free`, etc., override -// the libc allocator's implementation. This means that Rust's `System` -// allocator, which calls `libc::malloc()` et al., is actually calling into -// jemalloc. +// Instead, we use a lower-level mechanism, namely the +// `"unprefixed_malloc_on_supported_platforms"` Cargo feature of jemalloc-sys. +// +// This makes jemalloc-sys override the libc/system allocator's implementation +// of `malloc`, `free`, etc.. This means that Rust's `System` allocator, which +// calls `libc::malloc()` et al., is actually calling into jemalloc. // // A consequence of not using `GlobalAlloc` (and the `tikv-jemallocator` crate // provides an impl of that trait, which is called `Jemalloc`) is that we // cannot use the sized deallocation APIs (`sdallocx`) that jemalloc provides. // It's unclear how much performance is lost because of this. // -// As for the symbol overrides in `main` below: we're pulling in a static copy -// of jemalloc. We need to actually reference its symbols for it to get linked. -// The two crates we link to here, `std` and `rustc_driver`, are both dynamic -// libraries. So we must reference jemalloc symbols one way or another, because -// this file is the only object code in the rustc executable. -// // NOTE: if you are reading this comment because you want to set a custom `global_allocator` for // benchmarking, consider using the benchmarks in the `rustc-perf` collector suite instead: // https://github.com/rust-lang/rustc-perf/blob/master/collector/README.md#profiling @@ -36,43 +31,9 @@ // 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 _; fn main() { - // See the comment at the top of this file for an explanation of this. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - use tikv_jemalloc_sys as jemalloc_sys; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // 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; - } - } - rustc_driver::main() } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 9871066b9eb51..02689e35f75bc 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -61,11 +61,6 @@ extern crate rustc_target; extern crate rustc_trait_selection; extern crate test; -// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs -// about jemalloc. -#[cfg(feature = "jemalloc")] -extern crate tikv_jemalloc_sys as jemalloc_sys; - use std::env::{self, VarError}; use std::io::{self, IsTerminal}; use std::path::Path; @@ -77,6 +72,10 @@ use rustc_interface::interface; use rustc_middle::ty::TyCtxt; use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option}; use rustc_session::{EarlyDiagCtxt, getopts}; +/// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs +/// for why we need this `use` statement. +#[cfg(feature = "jemalloc")] +use tikv_jemalloc_sys as _; use tracing::info; use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION; @@ -124,37 +123,6 @@ mod visit_ast; mod visit_lib; pub fn main() { - // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs - // about jemalloc. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::install_ice_hook( diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 6bddcbfd94ce4..8d13323ae051c 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -13,10 +13,10 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs -// about jemalloc. +/// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs +/// for why we need this `use` statement. #[cfg(feature = "jemalloc")] -extern crate tikv_jemalloc_sys as jemalloc_sys; +use tikv_jemalloc_sys as _; use clippy_utils::sym; use declare_clippy_lint::LintListBuilder; @@ -192,36 +192,6 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne #[allow(clippy::too_many_lines)] #[allow(clippy::ignored_unit_patterns)] pub fn main() { - // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs - // about jemalloc. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::init_rustc_env_logger(&early_dcx); diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 9b0bee72aeff6..912d8943297cf 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -26,6 +26,11 @@ extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; +/// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs +/// for why we need this `use` statement. +#[cfg(any(target_os = "linux", target_os = "macos"))] +use tikv_jemalloc_sys as _; + mod log; use std::env; @@ -389,48 +394,7 @@ fn parse_range(val: &str) -> Result, &'static str> { Ok(from..to) } -#[cfg(any(target_os = "linux", target_os = "macos"))] -fn jemalloc_magic() { - // These magic runes are copied from - // . - // See there for further comments. - use std::os::raw::{c_int, c_void}; - - use tikv_jemalloc_sys as jemalloc_sys; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // 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; - } -} - fn main() { - #[cfg(any(target_os = "linux", target_os = "macos"))] - jemalloc_magic(); - let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); // Snapshot a copy of the environment before `rustc` starts messing with it.