alloc_jemalloc: don’t assume MIN_ALIGN for small sizes
See previous commit’s message for what is expected of allocators in general, and https://github.com/jemalloc/jemalloc/issues/1072 for discussion of what jemalloc does specifically.
This commit is contained in:
parent
21d899272a
commit
2dd268b652
2 changed files with 16 additions and 11 deletions
|
@ -20,6 +20,11 @@ fn alloc_system_overaligned_request() {
|
||||||
check_overalign_requests(System)
|
check_overalign_requests(System)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn std_heap_overaligned_request() {
|
||||||
|
check_overalign_requests(Heap)
|
||||||
|
}
|
||||||
|
|
||||||
fn check_overalign_requests<T: Alloc>(mut allocator: T) {
|
fn check_overalign_requests<T: Alloc>(mut allocator: T) {
|
||||||
let size = 8;
|
let size = 8;
|
||||||
let align = 16; // greater than size
|
let align = 16; // greater than size
|
||||||
|
|
|
@ -92,8 +92,8 @@ mod contents {
|
||||||
a.trailing_zeros() as c_int
|
a.trailing_zeros() as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align_to_flags(align: usize) -> c_int {
|
fn align_to_flags(align: usize, size: usize) -> c_int {
|
||||||
if align <= MIN_ALIGN {
|
if align <= MIN_ALIGN && align <= size {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
mallocx_align(align)
|
mallocx_align(align)
|
||||||
|
@ -111,7 +111,7 @@ mod contents {
|
||||||
pub unsafe extern fn __rde_alloc(size: usize,
|
pub unsafe extern fn __rde_alloc(size: usize,
|
||||||
align: usize,
|
align: usize,
|
||||||
err: *mut u8) -> *mut u8 {
|
err: *mut u8) -> *mut u8 {
|
||||||
let flags = align_to_flags(align);
|
let flags = align_to_flags(align, size);
|
||||||
let ptr = mallocx(size as size_t, flags) as *mut u8;
|
let ptr = mallocx(size as size_t, flags) as *mut u8;
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
let layout = Layout::from_size_align_unchecked(size, align);
|
let layout = Layout::from_size_align_unchecked(size, align);
|
||||||
|
@ -132,7 +132,7 @@ mod contents {
|
||||||
pub unsafe extern fn __rde_dealloc(ptr: *mut u8,
|
pub unsafe extern fn __rde_dealloc(ptr: *mut u8,
|
||||||
size: usize,
|
size: usize,
|
||||||
align: usize) {
|
align: usize) {
|
||||||
let flags = align_to_flags(align);
|
let flags = align_to_flags(align, size);
|
||||||
sdallocx(ptr as *mut c_void, size, flags);
|
sdallocx(ptr as *mut c_void, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ mod contents {
|
||||||
min: *mut usize,
|
min: *mut usize,
|
||||||
max: *mut usize) {
|
max: *mut usize) {
|
||||||
let layout = &*(layout as *const Layout);
|
let layout = &*(layout as *const Layout);
|
||||||
let flags = align_to_flags(layout.align());
|
let flags = align_to_flags(layout.align(), layout.size());
|
||||||
let size = nallocx(layout.size(), flags) as usize;
|
let size = nallocx(layout.size(), flags) as usize;
|
||||||
*min = layout.size();
|
*min = layout.size();
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
|
@ -166,7 +166,7 @@ mod contents {
|
||||||
return 0 as *mut u8
|
return 0 as *mut u8
|
||||||
}
|
}
|
||||||
|
|
||||||
let flags = align_to_flags(new_align);
|
let flags = align_to_flags(new_align, new_size);
|
||||||
let ptr = rallocx(ptr as *mut c_void, new_size, flags) as *mut u8;
|
let ptr = rallocx(ptr as *mut c_void, new_size, flags) as *mut u8;
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
let layout = Layout::from_size_align_unchecked(new_size, new_align);
|
let layout = Layout::from_size_align_unchecked(new_size, new_align);
|
||||||
|
@ -181,10 +181,10 @@ mod contents {
|
||||||
pub unsafe extern fn __rde_alloc_zeroed(size: usize,
|
pub unsafe extern fn __rde_alloc_zeroed(size: usize,
|
||||||
align: usize,
|
align: usize,
|
||||||
err: *mut u8) -> *mut u8 {
|
err: *mut u8) -> *mut u8 {
|
||||||
let ptr = if align <= MIN_ALIGN {
|
let ptr = if align <= MIN_ALIGN && align <= size {
|
||||||
calloc(size as size_t, 1) as *mut u8
|
calloc(size as size_t, 1) as *mut u8
|
||||||
} else {
|
} else {
|
||||||
let flags = align_to_flags(align) | MALLOCX_ZERO;
|
let flags = align_to_flags(align, size) | MALLOCX_ZERO;
|
||||||
mallocx(size as size_t, flags) as *mut u8
|
mallocx(size as size_t, flags) as *mut u8
|
||||||
};
|
};
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
|
@ -203,7 +203,7 @@ mod contents {
|
||||||
err: *mut u8) -> *mut u8 {
|
err: *mut u8) -> *mut u8 {
|
||||||
let p = __rde_alloc(size, align, err);
|
let p = __rde_alloc(size, align, err);
|
||||||
if !p.is_null() {
|
if !p.is_null() {
|
||||||
let flags = align_to_flags(align);
|
let flags = align_to_flags(align, size);
|
||||||
*excess = nallocx(size, flags) as usize;
|
*excess = nallocx(size, flags) as usize;
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
|
@ -220,7 +220,7 @@ mod contents {
|
||||||
err: *mut u8) -> *mut u8 {
|
err: *mut u8) -> *mut u8 {
|
||||||
let p = __rde_realloc(ptr, old_size, old_align, new_size, new_align, err);
|
let p = __rde_realloc(ptr, old_size, old_align, new_size, new_align, err);
|
||||||
if !p.is_null() {
|
if !p.is_null() {
|
||||||
let flags = align_to_flags(new_align);
|
let flags = align_to_flags(new_align, new_size);
|
||||||
*excess = nallocx(new_size, flags) as usize;
|
*excess = nallocx(new_size, flags) as usize;
|
||||||
}
|
}
|
||||||
p
|
p
|
||||||
|
@ -244,7 +244,7 @@ mod contents {
|
||||||
new_size: usize,
|
new_size: usize,
|
||||||
new_align: usize) -> u8 {
|
new_align: usize) -> u8 {
|
||||||
if old_align == new_align {
|
if old_align == new_align {
|
||||||
let flags = align_to_flags(new_align);
|
let flags = align_to_flags(new_align, new_size);
|
||||||
(xallocx(ptr as *mut c_void, new_size, 0, flags) == new_size) as u8
|
(xallocx(ptr as *mut c_void, new_size, 0, flags) == new_size) as u8
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue