use crate::init;
use crate::util::MIN_ALIGN;
use core::alloc::{GlobalAlloc, Layout};
pub struct CompatMalloc;
unsafe impl GlobalAlloc for CompatMalloc {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let align = layout.align();
if size == 0 {
return align as *mut u8;
}
init::ensure_initialized();
let alloc = init::allocator();
if align <= MIN_ALIGN {
alloc.malloc(size)
} else {
alloc.memalign(align, size)
}
}
#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let align = layout.align();
if size == 0 {
return align as *mut u8;
}
init::ensure_initialized();
let alloc = init::allocator();
if align <= MIN_ALIGN {
alloc.calloc(1, size)
} else {
let ptr = alloc.memalign(align, size);
if !ptr.is_null() {
core::ptr::write_bytes(ptr, 0, size);
}
ptr
}
}
#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
if layout.size() == 0 {
return;
}
init::allocator().free(ptr);
}
#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
let old_size = layout.size();
let align = layout.align();
if old_size == 0 {
return self.alloc(Layout::from_size_align_unchecked(new_size, align));
}
debug_assert!(
new_size > 0,
"GlobalAlloc::realloc called with new_size == 0"
);
let alloc = init::allocator();
if align <= MIN_ALIGN {
alloc.realloc(ptr, new_size)
} else {
let new_ptr = alloc.memalign(align, new_size);
if !new_ptr.is_null() {
let copy_size = old_size.min(new_size);
core::ptr::copy_nonoverlapping(ptr, new_ptr, copy_size);
alloc.free(ptr);
}
new_ptr
}
}
}