Skip to content

Commit d322385

Browse files
committed
Auto merge of #83152 - guswynn:jemallocator_part2, r=Mark-Simulacrum
Use tikv-jemallocator in rustc/rustdoc in addition to jemalloc-sys when enabled. In #81782 it was mentioned that one reason rustc may benefit from minimalloc is it doesn't use the `sdallocx` api from jemalloc. Currently, on unix, rust uses jemalloc by importing its symbols to use them with the default, System (libc) global allocator. This PR switches its global alloc to `tikv-jemallocator`, which correctly uses sized deallocation (https://docs.rs/tikv-jemallocator/0.4.1/src/tikv_jemallocator/lib.rs.html#121-126). `tikv-jemallocator`, as far as I can tell, is a more up-to-date set of bindings to jemalloc than `jemallocator` The perf results of this pr are in large part due to the version upgrade of jemalloc, but sized deallocation has a non-trivial improvement, particularly to rustdoc. This pr also includes changes to bootstrap to correctly pass the jemalloc feature through to the rustdoc build
2 parents d203fce + 3965773 commit d322385

File tree

7 files changed

+107
-17
lines changed

7 files changed

+107
-17
lines changed

Cargo.lock

+23-12
Original file line numberDiff line numberDiff line change
@@ -1732,17 +1732,6 @@ version = "0.4.6"
17321732
source = "registry+https://github.com/rust-lang/crates.io-index"
17331733
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
17341734

1735-
[[package]]
1736-
name = "jemalloc-sys"
1737-
version = "0.3.2"
1738-
source = "registry+https://github.com/rust-lang/crates.io-index"
1739-
checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
1740-
dependencies = [
1741-
"cc",
1742-
"fs_extra",
1743-
"libc",
1744-
]
1745-
17461735
[[package]]
17471736
name = "jobserver"
17481737
version = "0.1.21"
@@ -3586,9 +3575,10 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
35863575
name = "rustc-main"
35873576
version = "0.0.0"
35883577
dependencies = [
3589-
"jemalloc-sys",
35903578
"rustc_codegen_ssa",
35913579
"rustc_driver",
3580+
"tikv-jemalloc-sys",
3581+
"tikv-jemallocator",
35923582
]
35933583

35943584
[[package]]
@@ -5318,6 +5308,27 @@ dependencies = [
53185308
name = "tier-check"
53195309
version = "0.1.0"
53205310

5311+
[[package]]
5312+
name = "tikv-jemalloc-sys"
5313+
version = "0.4.1+5.2.1-patched"
5314+
source = "registry+https://github.com/rust-lang/crates.io-index"
5315+
checksum = "8a26331b05179d4cb505c8d6814a7e18d298972f0a551b0e3cefccff927f86d3"
5316+
dependencies = [
5317+
"cc",
5318+
"fs_extra",
5319+
"libc",
5320+
]
5321+
5322+
[[package]]
5323+
name = "tikv-jemallocator"
5324+
version = "0.4.1"
5325+
source = "registry+https://github.com/rust-lang/crates.io-index"
5326+
checksum = "3c14a5a604eb8715bc5785018a37d00739b180bcf609916ddf4393d33d49ccdf"
5327+
dependencies = [
5328+
"libc",
5329+
"tikv-jemalloc-sys",
5330+
]
5331+
53215332
[[package]]
53225333
name = "time"
53235334
version = "0.1.43"

compiler/rustc/Cargo.toml

+7-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ rustc_driver = { path = "../rustc_driver" }
1111
# crate is intended to be used by codegen backends, which may not be in-tree.
1212
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
1313

14-
[dependencies.jemalloc-sys]
15-
version = '0.3.0'
14+
[dependencies.tikv-jemalloc-sys]
15+
version = '0.4.0'
1616
optional = true
1717
features = ['unprefixed_malloc_on_supported_platforms']
1818

19+
[dependencies.tikv-jemallocator]
20+
version = '0.4.0'
21+
optional = true
22+
1923
[features]
20-
jemalloc = ['jemalloc-sys']
24+
jemalloc = ['tikv-jemalloc-sys', 'tikv-jemallocator']
2125
llvm = ['rustc_driver/llvm']
2226
max_level_info = ['rustc_driver/max_level_info']

compiler/rustc/src/main.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
// Configure jemalloc as the `global_allocator` when configured. This is
2+
// so that we use the sized deallocation apis jemalloc provides
3+
// (namely `sdallocx`).
4+
//
5+
// The symbol overrides documented below are also performed so that we can
6+
// ensure that we use a consistent allocator across the rustc <-> llvm boundary
7+
#[cfg(feature = "jemalloc")]
8+
#[global_allocator]
9+
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
10+
11+
#[cfg(feature = "tikv-jemalloc-sys")]
12+
use tikv_jemalloc_sys as jemalloc_sys;
13+
114
fn main() {
215
// Pull in jemalloc when enabled.
316
//
@@ -7,7 +20,7 @@ fn main() {
720
// dynamic libraries. That means to pull in jemalloc we actually need to
821
// reference allocation symbols one way or another (as this file is the only
922
// object code in the rustc executable).
10-
#[cfg(feature = "jemalloc-sys")]
23+
#[cfg(feature = "tikv-jemalloc-sys")]
1124
{
1225
use std::os::raw::{c_int, c_void};
1326

src/bootstrap/tool.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,11 @@ impl Step for Rustdoc {
532532
// they'll be linked to those libraries). As such, don't explicitly `ensure` any additional
533533
// libraries here. The intuition here is that If we've built a compiler, we should be able
534534
// to build rustdoc.
535+
//
536+
let mut features = Vec::new();
537+
if builder.config.jemalloc {
538+
features.push("jemalloc".to_string());
539+
}
535540

536541
let cargo = prepare_tool_cargo(
537542
builder,
@@ -541,7 +546,7 @@ impl Step for Rustdoc {
541546
"build",
542547
"src/tools/rustdoc",
543548
SourceType::InTree,
544-
&[],
549+
features.as_slice(),
545550
);
546551

547552
builder.info(&format!(

src/librustdoc/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,8 @@ features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
3030
[dev-dependencies]
3131
expect-test = "1.0"
3232

33+
[features]
34+
jemalloc = []
35+
3336
[package.metadata.rust-analyzer]
3437
rustc_private = true

src/librustdoc/lib.rs

+51
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern crate tracing;
3030
// So if `rustc` was specified in Cargo.toml, this would spuriously rebuild crates.
3131
//
3232
// Dependencies listed in Cargo.toml do not need `extern crate`.
33+
3334
extern crate rustc_ast;
3435
extern crate rustc_ast_lowering;
3536
extern crate rustc_ast_pretty;
@@ -60,6 +61,15 @@ extern crate rustc_trait_selection;
6061
extern crate rustc_typeck;
6162
extern crate test as testing;
6263

64+
#[cfg(feature = "jemalloc")]
65+
extern crate tikv_jemalloc_sys;
66+
#[cfg(feature = "jemalloc")]
67+
use tikv_jemalloc_sys as jemalloc_sys;
68+
#[cfg(feature = "jemalloc")]
69+
extern crate tikv_jemallocator;
70+
#[cfg(feature = "jemalloc")]
71+
use tikv_jemallocator as jemallocator;
72+
6373
use std::default::Default;
6474
use std::env;
6575
use std::process;
@@ -113,7 +123,48 @@ mod theme;
113123
mod visit_ast;
114124
mod visit_lib;
115125

126+
// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs
127+
// about jemallocator
128+
#[cfg(feature = "jemalloc")]
129+
#[global_allocator]
130+
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
131+
116132
pub fn main() {
133+
// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs
134+
// about jemalloc-sys
135+
#[cfg(feature = "jemalloc")]
136+
{
137+
use std::os::raw::{c_int, c_void};
138+
139+
#[used]
140+
static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc;
141+
#[used]
142+
static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int =
143+
jemalloc_sys::posix_memalign;
144+
#[used]
145+
static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc;
146+
#[used]
147+
static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc;
148+
#[used]
149+
static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc;
150+
#[used]
151+
static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free;
152+
153+
// On OSX, jemalloc doesn't directly override malloc/free, but instead
154+
// registers itself with the allocator's zone APIs in a ctor. However,
155+
// the linker doesn't seem to consider ctors as "used" when statically
156+
// linking, so we need to explicitly depend on the function.
157+
#[cfg(target_os = "macos")]
158+
{
159+
extern "C" {
160+
fn _rjem_je_zone_register();
161+
}
162+
163+
#[used]
164+
static _F7: unsafe extern "C" fn() = _rjem_je_zone_register;
165+
}
166+
}
167+
117168
rustc_driver::set_sigpipe_handler();
118169
rustc_driver::install_ice_hook();
119170

src/tools/rustdoc/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ path = "main.rs"
1313

1414
[dependencies]
1515
rustdoc = { path = "../../librustdoc" }
16+
17+
[features]
18+
jemalloc = ['rustdoc/jemalloc']

0 commit comments

Comments
 (0)