diff --git a/src/global.rs b/src/global.rs index 556286b..15621b6 100644 --- a/src/global.rs +++ b/src/global.rs @@ -1,75 +1,11 @@ -use alloc::heap::{Alloc, Layout, Excess, CannotReallocInPlace, AllocErr}; +use core::alloc::{GlobalAlloc, Layout, Void}; use core::ops::{Deref, DerefMut}; +use core::ptr::NonNull; use Dlmalloc; pub struct GlobalDlmalloc; -unsafe impl Alloc for GlobalDlmalloc { - #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - (&*self).alloc(layout) - } - - #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> - { - (&*self).alloc_zeroed(layout) - } - - #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - (&*self).dealloc(ptr, layout) - } - - #[inline] - unsafe fn realloc(&mut self, - ptr: *mut u8, - old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - (&*self).realloc(ptr, old_layout, new_layout) - } - - // fn oom(&mut self, err: AllocErr) -> ! { - // (&*self).oom(err) - // } - - #[inline] - fn usable_size(&self, layout: &Layout) -> (usize, usize) { - (&self).usable_size(layout) - } - - #[inline] - unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { - (&*self).alloc_excess(layout) - } - - #[inline] - unsafe fn realloc_excess(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result { - (&*self).realloc_excess(ptr, layout, new_layout) - } - - #[inline] - unsafe fn grow_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - (&*self).grow_in_place(ptr, layout, new_layout) - } - - #[inline] - unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - (&*self).shrink_in_place(ptr, layout, new_layout) - } -} - static mut DLMALLOC: Dlmalloc = Dlmalloc(::dlmalloc::DLMALLOC_INIT); struct Instance; @@ -98,62 +34,24 @@ impl Drop for Instance { } } -unsafe impl<'a> Alloc for &'a GlobalDlmalloc { - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - get().alloc(layout) - } - - unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> - { - get().alloc_zeroed(layout) - } - - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - get().dealloc(ptr, layout) - } - - unsafe fn realloc(&mut self, - ptr: *mut u8, - old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - get().realloc(ptr, old_layout, new_layout) - } - - // fn oom(&mut self, err: AllocErr) -> ! { - // unsafe { get().oom(err) } - // } - - fn usable_size(&self, layout: &Layout) -> (usize, usize) { - unsafe { get().usable_size(layout) } - } - +unsafe impl GlobalAlloc for GlobalDlmalloc { #[inline] - unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { - get().alloc_excess(layout) + unsafe fn alloc(&self, layout: Layout) -> *mut Void { + get().ptr_alloc(layout) as *mut Void } #[inline] - unsafe fn realloc_excess(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result { - get().realloc_excess(ptr, layout, new_layout) + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Void { + get().ptr_alloc_zeroed(layout) as *mut Void } #[inline] - unsafe fn grow_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - get().grow_in_place(ptr, layout, new_layout) + unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) { + get().ptr_dealloc(ptr as *mut u8, layout) } #[inline] - unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_layout: Layout) -> Result<(), CannotReallocInPlace> { - get().shrink_in_place(ptr, layout, new_layout) + unsafe fn realloc(&self, ptr: *mut Void, layout: Layout, new_size: usize) -> *mut Void { + get().ptr_realloc(ptr as *mut u8, layout, new_size) as *mut Void } } diff --git a/src/lib.rs b/src/lib.rs index c130d9e..0424394 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,10 @@ -#![feature(allocator_api, alloc)] +#![feature(allocator_api)] #![cfg_attr(target_arch = "wasm32", feature(link_llvm_intrinsics))] #![no_std] -extern crate alloc; - -use alloc::heap::{Alloc, Layout, AllocErr}; +use core::alloc::{Alloc, Layout, AllocErr}; use core::cmp; -use core::ptr; +use core::ptr::{self, NonNull}; pub use self::global::GlobalDlmalloc; @@ -33,134 +31,80 @@ impl Dlmalloc { } } -unsafe impl Alloc for Dlmalloc { +impl Dlmalloc { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - let ptr = if layout.align() <= self.0.malloc_alignment() { + unsafe fn ptr_alloc(&mut self, layout: Layout) -> *mut u8 { + if layout.align() <= self.0.malloc_alignment() { self.0.malloc(layout.size()) } else { self.0.memalign(layout.align(), layout.size()) - }; - if ptr.is_null() { - Err(AllocErr::Exhausted { request: layout }) - } else { - Ok(ptr) } } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> - { + unsafe fn ptr_alloc_zeroed(&mut self, layout: Layout) -> *mut u8 { let size = layout.size(); - let ptr = self.alloc(layout)?; - if self.0.calloc_must_clear(ptr) { - ptr::write_bytes(ptr, 0, size); + let ptr = self.ptr_alloc(layout); + if !ptr.is_null() { + if self.0.calloc_must_clear(ptr) { + ptr::write_bytes(ptr, 0, size); + } } - Ok(ptr) + ptr } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + unsafe fn ptr_dealloc(&mut self, ptr: *mut u8, layout: Layout) { drop(layout); self.0.free(ptr) } #[inline] - unsafe fn realloc(&mut self, - ptr: *mut u8, - old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { - if old_layout.align() != new_layout.align() { - return Err(AllocErr::Unsupported { - details: "cannot change alignment on `realloc`", - }) - } - - if new_layout.align() <= self.0.malloc_alignment() { - let ptr = self.0.realloc(ptr, new_layout.size()); - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr::Exhausted { request: new_layout }) - } + unsafe fn ptr_realloc(&mut self, + ptr: *mut u8, + layout: Layout, + new_size: usize) -> *mut u8 { + if layout.align() <= self.0.malloc_alignment() { + self.0.realloc(ptr, new_size) } else { - let res = self.alloc(new_layout.clone()); - if let Ok(new_ptr) = res { - let size = cmp::min(old_layout.size(), new_layout.size()); + let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); + let new_ptr = self.ptr_alloc(new_layout); + if !new_ptr.is_null() { + let size = cmp::min(layout.size(), new_size); ptr::copy_nonoverlapping(ptr, new_ptr, size); - self.dealloc(ptr, old_layout); + self.dealloc(ptr, layout); } - res + new_ptr } } +} - // fn oom(&mut self, err: AllocErr) -> ! { - // System.oom(err) - // } - - // #[inline] - // fn usable_size(&self, layout: &Layout) -> (usize, usize) { - // (&self).usable_size(layout) - // } - // - // #[inline] - // unsafe fn alloc_excess(&mut self, layout: Layout) -> Result { - // (&*self).alloc_excess(layout) - // } - // - // #[inline] - // unsafe fn realloc_excess(&mut self, - // ptr: *mut u8, - // layout: Layout, - // new_layout: Layout) -> Result { - // (&*self).realloc_excess(ptr, layout, new_layout) - // } - // - // #[inline] - // unsafe fn grow_in_place(&mut self, - // ptr: *mut u8, - // layout: Layout, - // new_layout: Layout) -> Result<(), CannotReallocInPlace> { - // (&*self).grow_in_place(ptr, layout, new_layout) - // } - // - // #[inline] - // unsafe fn shrink_in_place(&mut self, - // ptr: *mut u8, - // layout: Layout, - // new_layout: Layout) -> Result<(), CannotReallocInPlace> { - // (&*self).shrink_in_place(ptr, layout, new_layout) - // } +fn to_result(ptr: *mut u8) -> Result, AllocErr> { + NonNull::new(ptr).ok_or(AllocErr) } -// unsafe impl<'a> Alloc for &'a Dlmalloc { -// #[inline] -// unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { -// panic!() -// } -// -// // #[inline] -// // unsafe fn alloc_zeroed(&mut self, layout: Layout) -// // -> Result<*mut u8, AllocErr> -// // { -// // panic!() -// // } -// -// #[inline] -// unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { -// panic!() -// } -// -// // #[inline] -// // unsafe fn realloc(&mut self, -// // ptr: *mut u8, -// // old_layout: Layout, -// // new_layout: Layout) -> Result<*mut u8, AllocErr> { -// // panic!() -// // } -// -// fn oom(&mut self, err: AllocErr) -> ! { -// System.oom(err) -// } -// } +unsafe impl Alloc for Dlmalloc { + #[inline] + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { + to_result(self.ptr_alloc(layout)) + } + + #[inline] + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> + { + to_result(self.ptr_alloc_zeroed(layout)) + } + + #[inline] + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + self.ptr_dealloc(ptr.as_ptr(), layout) + } + + #[inline] + unsafe fn realloc(&mut self, + ptr: NonNull, + layout: Layout, + new_size: usize) -> Result, AllocErr> { + to_result(self.ptr_realloc(ptr.as_ptr(), layout, new_size)) + } +} diff --git a/tests/smoke.rs b/tests/smoke.rs index e5d0fbd..e39f319 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -14,12 +14,12 @@ fn smoke() { let mut a = Dlmalloc::new(); unsafe { let layout = Layout::new::(); - let ptr = a.alloc(layout.clone()).unwrap_or_else(|e| System.oom(e)); + let ptr = a.alloc(layout.clone()).unwrap_or_else(|_| System.oom()); *ptr = 9; assert_eq!(*ptr, 9); a.dealloc(ptr, layout.clone()); - let ptr = a.alloc(layout.clone()).unwrap_or_else(|e| System.oom(e)); + let ptr = a.alloc(layout.clone()).unwrap_or_else(|_| System.oom()); *ptr = 10; assert_eq!(*ptr, 10); a.dealloc(ptr, layout.clone()); @@ -59,8 +59,8 @@ fn stress() { for i in 0..cmp::min(old.size(), new.size()) { tmp.push(*ptr.offset(i as isize)); } - let ptr = a.realloc(ptr, old, new.clone()).unwrap_or_else(|e| { - System.oom(e) + let ptr = a.realloc(ptr, old, new.clone()).unwrap_or_else(|_| { + System.oom() }); for (i, byte) in tmp.iter().enumerate() { assert_eq!(*byte, *ptr.offset(i as isize)); @@ -83,9 +83,9 @@ fn stress() { let layout = Layout::from_size_align(size, align).unwrap(); let ptr = if zero { - a.alloc_zeroed(layout.clone()).unwrap_or_else(|e| System.oom(e)) + a.alloc_zeroed(layout.clone()).unwrap_or_else(|_| System.oom()) } else { - a.alloc(layout.clone()).unwrap_or_else(|e| System.oom(e)) + a.alloc(layout.clone()).unwrap_or_else(|_| System.oom()) }; for i in 0..layout.size() { if zero {