Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ fn mallocx_align(a: usize) -> c_int {
a.trailing_zeros() as c_int
}

fn align_to_flags(align: usize) -> c_int {
if align <= MIN_ALIGN {
fn align_to_flags(align: usize, size: usize) -> c_int {
if align <= MIN_ALIGN && align <= size {
0
} else {
mallocx_align(align)
Expand Down Expand Up @@ -131,7 +131,7 @@ unsafe impl Alloc for Jemalloc {
unsafe impl<'a> Alloc for &'a Jemalloc {
#[inline]
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
let flags = align_to_flags(layout.align());
let flags = align_to_flags(layout.align(), layout.size());
let ptr = ffi::mallocx(layout.size(), flags);
if ptr.is_null() {
Err(AllocErr::Exhausted { request: layout })
Expand All @@ -144,10 +144,10 @@ unsafe impl<'a> Alloc for &'a Jemalloc {
unsafe fn alloc_zeroed(&mut self, layout: Layout)
-> Result<*mut u8, AllocErr>
{
let ptr = if layout.align() <= MIN_ALIGN {
let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
ffi::calloc(1, layout.size())
} else {
let flags = align_to_flags(layout.align()) | ffi::MALLOCX_ZERO;
let flags = align_to_flags(layout.align(), layout.size()) | ffi::MALLOCX_ZERO;
ffi::mallocx(layout.size(), flags)
};
if ptr.is_null() {
Expand All @@ -159,7 +159,7 @@ unsafe impl<'a> Alloc for &'a Jemalloc {

#[inline]
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
let flags = align_to_flags(layout.align());
let flags = align_to_flags(layout.align(), layout.size());
ffi::sdallocx(ptr as *mut c_void, layout.size(), flags)
}

Expand All @@ -171,7 +171,7 @@ unsafe impl<'a> Alloc for &'a Jemalloc {
if old_layout.align() != new_layout.align() {
return Err(AllocErr::Unsupported { details: "cannot change align" })
}
let flags = align_to_flags(new_layout.align());
let flags = align_to_flags(new_layout.align(), new_layout.size());
let ptr = ffi::rallocx(ptr as *mut c_void, new_layout.size(), flags);
if ptr.is_null() {
Err(AllocErr::Exhausted { request: new_layout })
Expand All @@ -186,7 +186,7 @@ unsafe impl<'a> Alloc for &'a Jemalloc {

#[inline]
fn usable_size(&self, layout: &Layout) -> (usize, usize) {
let flags = align_to_flags(layout.align());
let flags = align_to_flags(layout.align(), layout.size());
unsafe {
let max = ffi::nallocx(layout.size(), flags);
(layout.size(), max)
Expand All @@ -209,7 +209,7 @@ unsafe impl<'a> Alloc for &'a Jemalloc {
if old_layout.align() != new_layout.align() {
return Err(CannotReallocInPlace)
}
let flags = align_to_flags(new_layout.align());
let flags = align_to_flags(new_layout.align(), new_layout.size());
let size = ffi::xallocx(ptr as *mut c_void, new_layout.size(), 0, flags);
if size >= new_layout.size() {
Err(CannotReallocInPlace)
Expand Down
24 changes: 23 additions & 1 deletion tests/smoke.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#![feature(global_allocator)]
#![feature(global_allocator, allocator_api)]

extern crate jemallocator;

use jemallocator::Jemalloc;
use std::heap::{Alloc, Layout};

#[global_allocator]
static A: Jemalloc = Jemalloc;
Expand All @@ -12,3 +13,24 @@ fn smoke() {
let mut a = Vec::new();
a.push(3);
}

/// https://github.com/rust-lang/rust/issues/45955
#[test]
fn overaligned() {
let size = 8;
let align = 16; // greater than size
let iterations = 100;
unsafe {
let pointers: Vec<_> = (0..iterations).map(|_| {
Jemalloc.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
}).collect();
for &ptr in &pointers {
assert_eq!((ptr as usize) % align, 0, "Got a pointer less aligned than requested")
}

// Clean up
for &ptr in &pointers {
Jemalloc.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
}
}
}