1
1
use crate :: ptr;
2
2
use crate :: sys_common:: alloc:: { MIN_ALIGN , realloc_fallback} ;
3
3
use crate :: alloc:: { GlobalAlloc , Layout , System } ;
4
+ use crate :: mem;
4
5
5
6
#[ stable( feature = "alloc_system_type" , since = "1.28.0" ) ]
6
7
unsafe impl GlobalAlloc for System {
7
8
#[ inline]
8
9
unsafe fn alloc ( & self , layout : Layout ) -> * mut u8 {
10
+ // jemalloc provides alignment less than MIN_ALIGN for small allocations.
11
+ // So only rely on MIN_ALIGN if size >= align.
12
+ // Also see <https://github.com/rust-lang/rust/issues/45955> and
13
+ // <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
9
14
if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
10
15
libc:: malloc ( layout. size ( ) ) as * mut u8
11
16
} else {
@@ -21,6 +26,7 @@ unsafe impl GlobalAlloc for System {
21
26
22
27
#[ inline]
23
28
unsafe fn alloc_zeroed ( & self , layout : Layout ) -> * mut u8 {
29
+ // See the comment above in `alloc` for why this check looks the way it does.
24
30
if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
25
31
libc:: calloc ( layout. size ( ) , 1 ) as * mut u8
26
32
} else {
@@ -80,7 +86,10 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
80
86
#[ inline]
81
87
unsafe fn aligned_malloc ( layout : & Layout ) -> * mut u8 {
82
88
let mut out = ptr:: null_mut ( ) ;
83
- let ret = libc:: posix_memalign ( & mut out, layout. align ( ) , layout. size ( ) ) ;
89
+ // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
90
+ // Since these are all powers of 2, we can just use max.
91
+ let align = layout. align ( ) . max ( mem:: size_of :: < usize > ( ) ) ;
92
+ let ret = libc:: posix_memalign ( & mut out, align, layout. size ( ) ) ;
84
93
if ret != 0 {
85
94
ptr:: null_mut ( )
86
95
} else {
0 commit comments