|
23 | 23 |
|
24 | 24 | extern crate libc;
|
25 | 25 |
|
26 |
| -use libc::{c_int, c_void, size_t}; |
| 26 | +pub use imp::*; |
27 | 27 |
|
28 |
| -// Linkage directives to pull in jemalloc and its dependencies. |
29 |
| -// |
30 |
| -// On some platforms we need to be sure to link in `pthread` which jemalloc |
31 |
| -// depends on, and specifically on android we need to also link to libgcc. |
32 |
| -// Currently jemalloc is compiled with gcc which will generate calls to |
33 |
| -// intrinsics that are libgcc specific (e.g. those intrinsics aren't present in |
34 |
| -// libcompiler-rt), so link that in to get that support. |
35 |
| -#[link(name = "jemalloc", kind = "static")] |
36 |
| -#[cfg_attr(target_os = "android", link(name = "gcc"))] |
37 |
| -#[cfg_attr(all(not(windows), |
38 |
| - not(target_os = "android"), |
39 |
| - not(target_env = "musl")), |
40 |
| - link(name = "pthread"))] |
41 |
| -#[cfg(not(cargobuild))] |
42 |
| -extern "C" {} |
43 |
| - |
44 |
| -// Note that the symbols here are prefixed by default on OSX and Windows (we |
45 |
| -// don't explicitly request it), and on Android and DragonFly we explicitly |
46 |
| -// request it as unprefixing cause segfaults (mismatches in allocators). |
47 |
| -extern "C" { |
48 |
| - #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
49 |
| - target_os = "dragonfly", target_os = "windows"), |
50 |
| - link_name = "je_mallocx")] |
51 |
| - fn mallocx(size: size_t, flags: c_int) -> *mut c_void; |
52 |
| - #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
53 |
| - target_os = "dragonfly", target_os = "windows"), |
54 |
| - link_name = "je_rallocx")] |
55 |
| - fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; |
56 |
| - #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
57 |
| - target_os = "dragonfly", target_os = "windows"), |
58 |
| - link_name = "je_xallocx")] |
59 |
| - fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; |
60 |
| - #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
61 |
| - target_os = "dragonfly", target_os = "windows"), |
62 |
| - link_name = "je_sdallocx")] |
63 |
| - fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int); |
64 |
| - #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
65 |
| - target_os = "dragonfly", target_os = "windows"), |
66 |
| - link_name = "je_nallocx")] |
67 |
| - fn nallocx(size: size_t, flags: c_int) -> size_t; |
68 |
| -} |
| 28 | +// See comments in build.rs for why we sometimes build a crate that does nothing |
| 29 | +#[cfg(not(dummy_jemalloc))] |
| 30 | +mod imp { |
| 31 | + use libc::{c_int, c_void, size_t}; |
69 | 32 |
|
70 |
| -// The minimum alignment guaranteed by the architecture. This value is used to |
71 |
| -// add fast paths for low alignment values. In practice, the alignment is a |
72 |
| -// constant at the call site and the branch will be optimized out. |
73 |
| -#[cfg(all(any(target_arch = "arm", |
74 |
| - target_arch = "mips", |
75 |
| - target_arch = "powerpc")))] |
76 |
| -const MIN_ALIGN: usize = 8; |
77 |
| -#[cfg(all(any(target_arch = "x86", |
78 |
| - target_arch = "x86_64", |
79 |
| - target_arch = "aarch64", |
80 |
| - target_arch = "powerpc64", |
81 |
| - target_arch = "mips64", |
82 |
| - target_arch = "s390x")))] |
83 |
| -const MIN_ALIGN: usize = 16; |
84 |
| - |
85 |
| -// MALLOCX_ALIGN(a) macro |
86 |
| -fn mallocx_align(a: usize) -> c_int { |
87 |
| - a.trailing_zeros() as c_int |
88 |
| -} |
| 33 | + // Linkage directives to pull in jemalloc and its dependencies. |
| 34 | + // |
| 35 | + // On some platforms we need to be sure to link in `pthread` which jemalloc |
| 36 | + // depends on, and specifically on android we need to also link to libgcc. |
| 37 | + // Currently jemalloc is compiled with gcc which will generate calls to |
| 38 | + // intrinsics that are libgcc specific (e.g. those intrinsics aren't present in |
| 39 | + // libcompiler-rt), so link that in to get that support. |
| 40 | + #[link(name = "jemalloc", kind = "static")] |
| 41 | + #[cfg_attr(target_os = "android", link(name = "gcc"))] |
| 42 | + #[cfg_attr(all(not(windows), |
| 43 | + not(target_os = "android"), |
| 44 | + not(target_env = "musl")), |
| 45 | + link(name = "pthread"))] |
| 46 | + #[cfg(not(cargobuild))] |
| 47 | + extern "C" {} |
| 48 | + |
| 49 | + // Note that the symbols here are prefixed by default on OSX and Windows (we |
| 50 | + // don't explicitly request it), and on Android and DragonFly we explicitly |
| 51 | + // request it as unprefixing cause segfaults (mismatches in allocators). |
| 52 | + extern "C" { |
| 53 | + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
| 54 | + target_os = "dragonfly", target_os = "windows"), |
| 55 | + link_name = "je_mallocx")] |
| 56 | + fn mallocx(size: size_t, flags: c_int) -> *mut c_void; |
| 57 | + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
| 58 | + target_os = "dragonfly", target_os = "windows"), |
| 59 | + link_name = "je_rallocx")] |
| 60 | + fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; |
| 61 | + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
| 62 | + target_os = "dragonfly", target_os = "windows"), |
| 63 | + link_name = "je_xallocx")] |
| 64 | + fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; |
| 65 | + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
| 66 | + target_os = "dragonfly", target_os = "windows"), |
| 67 | + link_name = "je_sdallocx")] |
| 68 | + fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int); |
| 69 | + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
| 70 | + target_os = "dragonfly", target_os = "windows"), |
| 71 | + link_name = "je_nallocx")] |
| 72 | + fn nallocx(size: size_t, flags: c_int) -> size_t; |
| 73 | + } |
| 74 | + |
| 75 | + // The minimum alignment guaranteed by the architecture. This value is used to |
| 76 | + // add fast paths for low alignment values. In practice, the alignment is a |
| 77 | + // constant at the call site and the branch will be optimized out. |
| 78 | + #[cfg(all(any(target_arch = "arm", |
| 79 | + target_arch = "mips", |
| 80 | + target_arch = "powerpc")))] |
| 81 | + const MIN_ALIGN: usize = 8; |
| 82 | + #[cfg(all(any(target_arch = "x86", |
| 83 | + target_arch = "x86_64", |
| 84 | + target_arch = "aarch64", |
| 85 | + target_arch = "powerpc64", |
| 86 | + target_arch = "mips64", |
| 87 | + target_arch = "s390x")))] |
| 88 | + const MIN_ALIGN: usize = 16; |
| 89 | + |
| 90 | + // MALLOCX_ALIGN(a) macro |
| 91 | + fn mallocx_align(a: usize) -> c_int { |
| 92 | + a.trailing_zeros() as c_int |
| 93 | + } |
| 94 | + |
| 95 | + fn align_to_flags(align: usize) -> c_int { |
| 96 | + if align <= MIN_ALIGN { |
| 97 | + 0 |
| 98 | + } else { |
| 99 | + mallocx_align(align) |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + #[no_mangle] |
| 104 | + pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 { |
| 105 | + let flags = align_to_flags(align); |
| 106 | + unsafe { mallocx(size as size_t, flags) as *mut u8 } |
| 107 | + } |
| 108 | + |
| 109 | + #[no_mangle] |
| 110 | + pub extern "C" fn __rust_reallocate(ptr: *mut u8, |
| 111 | + _old_size: usize, |
| 112 | + size: usize, |
| 113 | + align: usize) |
| 114 | + -> *mut u8 { |
| 115 | + let flags = align_to_flags(align); |
| 116 | + unsafe { rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 } |
| 117 | + } |
| 118 | + |
| 119 | + #[no_mangle] |
| 120 | + pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8, |
| 121 | + _old_size: usize, |
| 122 | + size: usize, |
| 123 | + align: usize) |
| 124 | + -> usize { |
| 125 | + let flags = align_to_flags(align); |
| 126 | + unsafe { xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize } |
| 127 | + } |
89 | 128 |
|
90 |
| -fn align_to_flags(align: usize) -> c_int { |
91 |
| - if align <= MIN_ALIGN { |
| 129 | + #[no_mangle] |
| 130 | + pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) { |
| 131 | + let flags = align_to_flags(align); |
| 132 | + unsafe { sdallocx(ptr as *mut c_void, old_size as size_t, flags) } |
| 133 | + } |
| 134 | + |
| 135 | + #[no_mangle] |
| 136 | + pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize { |
| 137 | + let flags = align_to_flags(align); |
| 138 | + unsafe { nallocx(size as size_t, flags) as usize } |
| 139 | + } |
| 140 | + |
| 141 | + // These symbols are used by jemalloc on android but the really old android |
| 142 | + // we're building on doesn't have them defined, so just make sure the symbols |
| 143 | + // are available. |
| 144 | + #[no_mangle] |
| 145 | + #[cfg(target_os = "android")] |
| 146 | + pub extern "C" fn pthread_atfork(_prefork: *mut u8, |
| 147 | + _postfork_parent: *mut u8, |
| 148 | + _postfork_child: *mut u8) |
| 149 | + -> i32 { |
92 | 150 | 0
|
93 |
| - } else { |
94 |
| - mallocx_align(align) |
95 | 151 | }
|
96 | 152 | }
|
97 | 153 |
|
98 |
| -#[no_mangle] |
99 |
| -pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 { |
100 |
| - let flags = align_to_flags(align); |
101 |
| - unsafe { mallocx(size as size_t, flags) as *mut u8 } |
102 |
| -} |
| 154 | +#[cfg(dummy_jemalloc)] |
| 155 | +mod imp { |
| 156 | + fn bogus() -> ! { |
| 157 | + panic!("jemalloc is not implemented for this platform"); |
| 158 | + } |
103 | 159 |
|
104 |
| -#[no_mangle] |
105 |
| -pub extern "C" fn __rust_reallocate(ptr: *mut u8, |
106 |
| - _old_size: usize, |
107 |
| - size: usize, |
108 |
| - align: usize) |
109 |
| - -> *mut u8 { |
110 |
| - let flags = align_to_flags(align); |
111 |
| - unsafe { rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 } |
112 |
| -} |
| 160 | + #[no_mangle] |
| 161 | + pub extern "C" fn __rust_allocate(_size: usize, _align: usize) -> *mut u8 { |
| 162 | + bogus() |
| 163 | + } |
113 | 164 |
|
114 |
| -#[no_mangle] |
115 |
| -pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8, |
116 |
| - _old_size: usize, |
117 |
| - size: usize, |
118 |
| - align: usize) |
119 |
| - -> usize { |
120 |
| - let flags = align_to_flags(align); |
121 |
| - unsafe { xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize } |
122 |
| -} |
| 165 | + #[no_mangle] |
| 166 | + pub extern "C" fn __rust_reallocate(_ptr: *mut u8, |
| 167 | + _old_size: usize, |
| 168 | + _size: usize, |
| 169 | + _align: usize) |
| 170 | + -> *mut u8 { |
| 171 | + bogus() |
| 172 | + } |
123 | 173 |
|
124 |
| -#[no_mangle] |
125 |
| -pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) { |
126 |
| - let flags = align_to_flags(align); |
127 |
| - unsafe { sdallocx(ptr as *mut c_void, old_size as size_t, flags) } |
128 |
| -} |
| 174 | + #[no_mangle] |
| 175 | + pub extern "C" fn __rust_reallocate_inplace(_ptr: *mut u8, |
| 176 | + _old_size: usize, |
| 177 | + _size: usize, |
| 178 | + _align: usize) |
| 179 | + -> usize { |
| 180 | + bogus() |
| 181 | + } |
129 | 182 |
|
130 |
| -#[no_mangle] |
131 |
| -pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize { |
132 |
| - let flags = align_to_flags(align); |
133 |
| - unsafe { nallocx(size as size_t, flags) as usize } |
134 |
| -} |
| 183 | + #[no_mangle] |
| 184 | + pub extern "C" fn __rust_deallocate(_ptr: *mut u8, _old_size: usize, _align: usize) { |
| 185 | + bogus() |
| 186 | + } |
135 | 187 |
|
136 |
| -// These symbols are used by jemalloc on android but the really old android |
137 |
| -// we're building on doesn't have them defined, so just make sure the symbols |
138 |
| -// are available. |
139 |
| -#[no_mangle] |
140 |
| -#[cfg(target_os = "android")] |
141 |
| -pub extern "C" fn pthread_atfork(_prefork: *mut u8, |
142 |
| - _postfork_parent: *mut u8, |
143 |
| - _postfork_child: *mut u8) |
144 |
| - -> i32 { |
145 |
| - 0 |
| 188 | + #[no_mangle] |
| 189 | + pub extern "C" fn __rust_usable_size(_size: usize, _align: usize) -> usize { |
| 190 | + bogus() |
| 191 | + } |
146 | 192 | }
|
0 commit comments