1 use crate::alloc
::{GlobalAlloc, Layout, System}
;
3 use crate::sys
::common
::alloc
::{realloc_fallback, MIN_ALIGN}
;
5 #[stable(feature = "alloc_system_type", since = "1.28.0")]
6 unsafe impl GlobalAlloc
for System
{
8 unsafe fn alloc(&self, layout
: Layout
) -> *mut u8 {
9 // jemalloc provides alignment less than MIN_ALIGN for small allocations.
10 // So only rely on MIN_ALIGN if size >= align.
11 // Also see <https://github.com/rust-lang/rust/issues/45955> and
12 // <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
13 if layout
.align() <= MIN_ALIGN
&& layout
.align() <= layout
.size() {
14 libc
::malloc(layout
.size()) as *mut u8
16 #[cfg(target_os = "macos")]
18 if layout
.align() > (1 << 31) {
19 return ptr
::null_mut();
22 aligned_malloc(&layout
)
27 unsafe fn alloc_zeroed(&self, layout
: Layout
) -> *mut u8 {
28 // See the comment above in `alloc` for why this check looks the way it does.
29 if layout
.align() <= MIN_ALIGN
&& layout
.align() <= layout
.size() {
30 libc
::calloc(layout
.size(), 1) as *mut u8
32 let ptr
= self.alloc(layout
);
34 ptr
::write_bytes(ptr
, 0, layout
.size());
41 unsafe fn dealloc(&self, ptr
: *mut u8, _layout
: Layout
) {
42 libc
::free(ptr
as *mut libc
::c_void
)
46 unsafe fn realloc(&self, ptr
: *mut u8, layout
: Layout
, new_size
: usize) -> *mut u8 {
47 if layout
.align() <= MIN_ALIGN
&& layout
.align() <= new_size
{
48 libc
::realloc(ptr
as *mut libc
::c_void
, new_size
) as *mut u8
50 realloc_fallback(self, ptr
, layout
, new_size
)
57 target_os
= "android",
58 target_os
= "illumos",
63 unsafe fn aligned_malloc(layout
: &Layout
) -> *mut u8 {
64 // On android we currently target API level 9 which unfortunately
65 // doesn't have the `posix_memalign` API used below. Instead we use
66 // `memalign`, but this unfortunately has the property on some systems
67 // where the memory returned cannot be deallocated by `free`!
69 // Upon closer inspection, however, this appears to work just fine with
70 // Android, so for this platform we should be fine to call `memalign`
71 // (which is present in API level 9). Some helpful references could
72 // possibly be chromium using memalign [1], attempts at documenting that
73 // memalign + free is ok [2] [3], or the current source of chromium
74 // which still uses memalign on android [4].
76 // [1]: https://codereview.chromium.org/10796020/
77 // [2]: https://code.google.com/p/android/issues/detail?id=35391
78 // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
79 // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
80 // /memory/aligned_memory.cc
81 libc
::memalign(layout
.align(), layout
.size()) as *mut u8
83 } else if #[cfg(target_os = "wasi")] {
85 unsafe fn aligned_malloc(layout
: &Layout
) -> *mut u8 {
86 libc
::aligned_alloc(layout
.align(), layout
.size()) as *mut u8
90 unsafe fn aligned_malloc(layout
: &Layout
) -> *mut u8 {
91 let mut out
= ptr
::null_mut();
92 // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
93 // Since these are all powers of 2, we can just use max.
94 let align
= layout
.align().max(crate::mem
::size_of
::<usize>());
95 let ret
= libc
::posix_memalign(&mut out
, align
, layout
.size());
96 if ret
!= 0 { ptr::null_mut() }
else { out as *mut u8 }