Skip to content

Commit 841b7cd

Browse files
committed
fix alignment in zeroed allocations
1 parent bd56eec commit 841b7cd

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

zlib-rs/src/allocate.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use alloc::alloc::GlobalAlloc;
1515
#[allow(non_camel_case_types)]
1616
type size_t = usize;
1717

18+
const ALIGN: u8 = 64;
19+
1820
/// # Safety
1921
///
2022
/// This function is safe, but must have this type signature to be used elsewhere in the library
@@ -27,7 +29,7 @@ unsafe extern "C" fn zalloc_c(opaque: *mut c_void, items: c_uint, size: c_uint)
2729
}
2830

2931
let mut ptr = core::ptr::null_mut();
30-
match posix_memalign(&mut ptr, 64, items as size_t * size as size_t) {
32+
match posix_memalign(&mut ptr, ALIGN.into(), items as size_t * size as size_t) {
3133
0 => ptr,
3234
_ => core::ptr::null_mut(),
3335
}
@@ -82,17 +84,35 @@ unsafe extern "C" fn zfree_c(opaque: *mut c_void, ptr: *mut c_void) {
8284
/// This function is safe to call.
8385
#[cfg(feature = "rust-allocator")]
8486
unsafe extern "C" fn zalloc_rust(_opaque: *mut c_void, count: c_uint, size: c_uint) -> *mut c_void {
85-
let align = 64;
8687
let size = count as usize * size as usize;
8788

8889
// internally, we want to align allocations to 64 bytes (in part for SIMD reasons)
89-
let layout = Layout::from_size_align(size, align).unwrap();
90+
let layout = Layout::from_size_align(size, ALIGN.into()).unwrap();
9091

9192
let ptr = std::alloc::System.alloc(layout);
9293

9394
ptr as *mut c_void
9495
}
9596

97+
/// # Safety
98+
///
99+
/// This function is safe to call.
100+
#[cfg(feature = "rust-allocator")]
101+
unsafe extern "C" fn zalloc_rust_calloc(
102+
_opaque: *mut c_void,
103+
count: c_uint,
104+
size: c_uint,
105+
) -> *mut c_void {
106+
let size = count as usize * size as usize;
107+
108+
// internally, we want to align allocations to 64 bytes (in part for SIMD reasons)
109+
let layout = Layout::from_size_align(size, ALIGN.into()).unwrap();
110+
111+
let ptr = std::alloc::System.alloc_zeroed(layout);
112+
113+
ptr as *mut c_void
114+
}
115+
96116
/// # Safety
97117
///
98118
/// - `ptr` must be allocated with the rust `alloc::System` allocator
@@ -110,9 +130,8 @@ unsafe extern "C" fn zfree_rust(opaque: *mut c_void, ptr: *mut c_void) {
110130
}
111131

112132
let size = *(opaque as *mut usize);
113-
let align = 64;
114133

115-
let layout = Layout::from_size_align(size, align);
134+
let layout = Layout::from_size_align(size, ALIGN.into());
116135
let layout = layout.unwrap();
117136

118137
std::alloc::System.dealloc(ptr.cast(), layout);
@@ -251,7 +270,11 @@ impl Allocator<'_> {
251270
fn allocate_layout_zeroed(&self, layout: Layout) -> *mut c_void {
252271
#[cfg(feature = "rust-allocator")]
253272
if self.zalloc == Allocator::RUST.zalloc {
254-
return unsafe { std::alloc::System.alloc_zeroed(layout).cast() };
273+
let ptr = unsafe { zalloc_rust_calloc(self.opaque, layout.size() as _, 1) };
274+
275+
debug_assert_eq!(ptr as usize % layout.align(), 0);
276+
277+
return ptr;
255278
}
256279

257280
#[cfg(feature = "c-allocator")]
@@ -263,17 +286,15 @@ impl Allocator<'_> {
263286
_marker: PhantomData,
264287
};
265288

266-
let ptr = alloc.allocate_layout(layout);
267-
268-
return ptr;
289+
return alloc.allocate_layout(layout);
269290
}
270291

271292
// create the allocation (contents are uninitialized)
272293
let ptr = self.allocate_layout(layout);
273294

274295
if !ptr.is_null() {
275296
// zero all contents (thus initializing the buffer)
276-
unsafe { core::ptr::write_bytes(ptr, 0, layout.size()) };
297+
unsafe { core::ptr::write_bytes(ptr, 0u8, layout.size()) };
277298
}
278299

279300
ptr
@@ -293,7 +314,7 @@ impl Allocator<'_> {
293314

294315
pub fn allocate_zeroed_buffer(&self, len: usize) -> Option<NonNull<u8>> {
295316
// internally, we want to align allocations to 64 bytes (in part for SIMD reasons)
296-
let layout = Layout::from_size_align(len, 64).unwrap();
317+
let layout = Layout::from_size_align(len, ALIGN.into()).unwrap();
297318
NonNull::new(self.allocate_layout_zeroed(layout).cast())
298319
}
299320

0 commit comments

Comments
 (0)