|
7 | 7 | // distribution. The obvious way to do this is with the `#[global_allocator]` |
8 | 8 | // mechanism. However, for complicated reasons (see |
9 | 9 | // https://github.com/rust-lang/rust/pull/81782#issuecomment-784438001 for some |
10 | | -// details) that mechanism doesn't work here. Also, we must use a consistent |
11 | | -// allocator across the rustc <-> llvm boundary, and `#[global_allocator]` |
12 | | -// wouldn't provide that. |
| 10 | +// details) that mechanism doesn't work here. Also, we'd like to use a |
| 11 | +// consistent allocator across the rustc <-> llvm boundary, and |
| 12 | +// `#[global_allocator]` wouldn't provide that. |
13 | 13 | // |
14 | | -// Instead, we use a lower-level mechanism. rustc is linked with jemalloc in a |
15 | | -// way such that jemalloc's implementation of `malloc`, `free`, etc., override |
16 | | -// the libc allocator's implementation. This means that Rust's `System` |
17 | | -// allocator, which calls `libc::malloc()` et al., is actually calling into |
18 | | -// jemalloc. |
| 14 | +// Instead, we use a lower-level mechanism, namely the |
| 15 | +// `"unprefixed_malloc_on_supported_platforms"` Cargo feature of jemalloc-sys. |
| 16 | +// |
| 17 | +// This makes jemalloc-sys override the libc/system allocator's implementation |
| 18 | +// of `malloc`, `free`, etc.. This means that Rust's `System` allocator, which |
| 19 | +// calls `libc::malloc()` et al., is actually calling into jemalloc. |
19 | 20 | // |
20 | 21 | // A consequence of not using `GlobalAlloc` (and the `tikv-jemallocator` crate |
21 | 22 | // provides an impl of that trait, which is called `Jemalloc`) is that we |
22 | 23 | // cannot use the sized deallocation APIs (`sdallocx`) that jemalloc provides. |
23 | 24 | // It's unclear how much performance is lost because of this. |
24 | 25 | // |
25 | | -// As for the symbol overrides in `main` below: we're pulling in a static copy |
26 | | -// of jemalloc. We need to actually reference its symbols for it to get linked. |
27 | | -// The two crates we link to here, `std` and `rustc_driver`, are both dynamic |
28 | | -// libraries. So we must reference jemalloc symbols one way or another, because |
29 | | -// this file is the only object code in the rustc executable. |
30 | | -// |
31 | 26 | // NOTE: if you are reading this comment because you want to set a custom `global_allocator` for |
32 | 27 | // benchmarking, consider using the benchmarks in the `rustc-perf` collector suite instead: |
33 | 28 | // https://github.com/rust-lang/rustc-perf/blob/master/collector/README.md#profiling |
|
36 | 31 | // to compare their performance, see |
37 | 32 | // https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef |
38 | 33 | // for an example of how to do so. |
| 34 | +#[cfg(feature = "jemalloc")] |
| 35 | +use tikv_jemalloc_sys as _; |
39 | 36 |
|
40 | 37 | fn main() { |
41 | | - // See the comment at the top of this file for an explanation of this. |
42 | | - #[cfg(feature = "jemalloc")] |
43 | | - { |
44 | | - use std::os::raw::{c_int, c_void}; |
45 | | - |
46 | | - use tikv_jemalloc_sys as jemalloc_sys; |
47 | | - |
48 | | - #[used] |
49 | | - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; |
50 | | - #[used] |
51 | | - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = |
52 | | - jemalloc_sys::posix_memalign; |
53 | | - #[used] |
54 | | - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; |
55 | | - #[used] |
56 | | - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; |
57 | | - #[used] |
58 | | - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; |
59 | | - #[used] |
60 | | - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; |
61 | | - |
62 | | - // On OSX, jemalloc doesn't directly override malloc/free, but instead |
63 | | - // registers itself with the allocator's zone APIs in a ctor. However, |
64 | | - // the linker doesn't seem to consider ctors as "used" when statically |
65 | | - // linking, so we need to explicitly depend on the function. |
66 | | - #[cfg(target_os = "macos")] |
67 | | - { |
68 | | - unsafe extern "C" { |
69 | | - fn _rjem_je_zone_register(); |
70 | | - } |
71 | | - |
72 | | - #[used] |
73 | | - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; |
74 | | - } |
75 | | - } |
76 | | - |
77 | 38 | rustc_driver::main() |
78 | 39 | } |
0 commit comments