11use crate :: ptr;
22use crate :: sys_common:: alloc:: { MIN_ALIGN , realloc_fallback} ;
33use crate :: alloc:: { GlobalAlloc , Layout , System } ;
4+ use crate :: mem;
45
56#[ stable( feature = "alloc_system_type" , since = "1.28.0" ) ]
67unsafe impl GlobalAlloc for System {
78 #[ inline]
89 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>.
914 if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
1015 libc:: malloc ( layout. size ( ) ) as * mut u8
1116 } else {
@@ -21,6 +26,7 @@ unsafe impl GlobalAlloc for System {
2126
2227 #[ inline]
2328 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.
2430 if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
2531 libc:: calloc ( layout. size ( ) , 1 ) as * mut u8
2632 } else {
@@ -80,7 +86,10 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
8086#[ inline]
8187unsafe fn aligned_malloc ( layout : & Layout ) -> * mut u8 {
8288 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 ( ) ) ;
8493 if ret != 0 {
8594 ptr:: null_mut ( )
8695 } else {
0 commit comments