]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
e9174d1e SL |
11 | #![crate_name = "alloc_jemalloc"] |
12 | #![crate_type = "rlib"] | |
e9174d1e | 13 | #![no_std] |
9cc50fc6 | 14 | #![allocator] |
e9174d1e SL |
15 | #![unstable(feature = "alloc_jemalloc", |
16 | reason = "this library is unlikely to be stabilized in its current \ | |
17 | form or name", | |
18 | issue = "27783")] | |
7453a54e | 19 | #![cfg_attr(not(stage0), deny(warnings))] |
e9174d1e SL |
20 | #![feature(allocator)] |
21 | #![feature(libc)] | |
e9174d1e SL |
22 | #![feature(staged_api)] |
23 | ||
24 | extern crate libc; | |
25 | ||
26 | use libc::{c_int, c_void, size_t}; | |
27 | ||
b039eaaf SL |
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. | |
e9174d1e | 35 | #[link(name = "jemalloc", kind = "static")] |
b039eaaf SL |
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"))] | |
7453a54e SL |
41 | #[cfg(not(cargobuild))] |
42 | extern {} | |
43 | ||
44 | // Note that the symbols here are prefixed by default on OSX (we don't | |
54a0048b SL |
45 | // explicitly request it), and on Android and DragonFly we explicitly request |
46 | // it as unprefixing cause segfaults (mismatches in allocators). | |
7453a54e | 47 | extern { |
54a0048b SL |
48 | #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
49 | target_os = "dragonfly"), | |
7453a54e SL |
50 | link_name = "je_mallocx")] |
51 | fn mallocx(size: size_t, flags: c_int) -> *mut c_void; | |
54a0048b SL |
52 | #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
53 | target_os = "dragonfly"), | |
7453a54e SL |
54 | link_name = "je_rallocx")] |
55 | fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; | |
54a0048b SL |
56 | #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
57 | target_os = "dragonfly"), | |
7453a54e SL |
58 | link_name = "je_xallocx")] |
59 | fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; | |
54a0048b SL |
60 | #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
61 | target_os = "dragonfly"), | |
7453a54e SL |
62 | link_name = "je_sdallocx")] |
63 | fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int); | |
54a0048b SL |
64 | #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", |
65 | target_os = "dragonfly"), | |
7453a54e SL |
66 | link_name = "je_nallocx")] |
67 | fn nallocx(size: size_t, flags: c_int) -> size_t; | |
e9174d1e SL |
68 | } |
69 | ||
e9174d1e SL |
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", | |
e9174d1e SL |
75 | target_arch = "powerpc")))] |
76 | const MIN_ALIGN: usize = 8; | |
77 | #[cfg(all(any(target_arch = "x86", | |
78 | target_arch = "x86_64", | |
9cc50fc6 | 79 | target_arch = "aarch64", |
7453a54e | 80 | target_arch = "powerpc64")))] |
e9174d1e SL |
81 | const MIN_ALIGN: usize = 16; |
82 | ||
83 | // MALLOCX_ALIGN(a) macro | |
b039eaaf SL |
84 | fn mallocx_align(a: usize) -> c_int { |
85 | a.trailing_zeros() as c_int | |
86 | } | |
e9174d1e SL |
87 | |
88 | fn align_to_flags(align: usize) -> c_int { | |
b039eaaf SL |
89 | if align <= MIN_ALIGN { |
90 | 0 | |
91 | } else { | |
92 | mallocx_align(align) | |
93 | } | |
e9174d1e SL |
94 | } |
95 | ||
96 | #[no_mangle] | |
b039eaaf | 97 | pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 { |
e9174d1e | 98 | let flags = align_to_flags(align); |
7453a54e | 99 | unsafe { mallocx(size as size_t, flags) as *mut u8 } |
e9174d1e SL |
100 | } |
101 | ||
102 | #[no_mangle] | |
b039eaaf SL |
103 | pub extern "C" fn __rust_reallocate(ptr: *mut u8, |
104 | _old_size: usize, | |
105 | size: usize, | |
106 | align: usize) | |
107 | -> *mut u8 { | |
e9174d1e | 108 | let flags = align_to_flags(align); |
7453a54e | 109 | unsafe { rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 } |
e9174d1e SL |
110 | } |
111 | ||
112 | #[no_mangle] | |
b039eaaf SL |
113 | pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8, |
114 | _old_size: usize, | |
115 | size: usize, | |
116 | align: usize) | |
117 | -> usize { | |
e9174d1e | 118 | let flags = align_to_flags(align); |
7453a54e | 119 | unsafe { xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize } |
e9174d1e SL |
120 | } |
121 | ||
122 | #[no_mangle] | |
b039eaaf | 123 | pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) { |
e9174d1e | 124 | let flags = align_to_flags(align); |
7453a54e | 125 | unsafe { sdallocx(ptr as *mut c_void, old_size as size_t, flags) } |
e9174d1e SL |
126 | } |
127 | ||
128 | #[no_mangle] | |
b039eaaf | 129 | pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize { |
e9174d1e | 130 | let flags = align_to_flags(align); |
7453a54e | 131 | unsafe { nallocx(size as size_t, flags) as usize } |
e9174d1e | 132 | } |
9cc50fc6 SL |
133 | |
134 | // These symbols are used by jemalloc on android but the really old android | |
135 | // we're building on doesn't have them defined, so just make sure the symbols | |
136 | // are available. | |
137 | #[no_mangle] | |
138 | #[cfg(target_os = "android")] | |
139 | pub extern fn pthread_atfork(_prefork: *mut u8, | |
140 | _postfork_parent: *mut u8, | |
141 | _postfork_child: *mut u8) -> i32 { | |
142 | 0 | |
143 | } |