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>.
9
13
if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
10
14
libc:: malloc ( layout. size ( ) ) as * mut u8
11
15
} else {
@@ -21,6 +25,9 @@ unsafe impl GlobalAlloc for System {
21
25
22
26
#[ inline]
23
27
unsafe fn alloc_zeroed ( & self , layout : Layout ) -> * mut u8 {
28
+ // jemalloc provides alignment less than MIN_ALIGN for small allocations.
29
+ // So only rely on MIN_ALIGN if size >= align.
30
+ // Also see <https://github.com/rust-lang/rust/issues/45955>.
24
31
if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
25
32
libc:: calloc ( layout. size ( ) , 1 ) as * mut u8
26
33
} else {
@@ -80,7 +87,10 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
80
87
#[ inline]
81
88
unsafe fn aligned_malloc ( layout : & Layout ) -> * mut u8 {
82
89
let mut out = ptr:: null_mut ( ) ;
83
- let ret = libc:: posix_memalign ( & mut out, layout. align ( ) , layout. size ( ) ) ;
90
+ // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
91
+ // Since these are all powers of 2, we can just use max.
92
+ let align = layout. align ( ) . max ( mem:: size_of :: < usize > ( ) ) ;
93
+ let ret = libc:: posix_memalign ( & mut out, align, layout. size ( ) ) ;
84
94
if ret != 0 {
85
95
ptr:: null_mut ( )
86
96
} else {
0 commit comments