|  | 
| 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 | +// `"override_allocator_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