From aa73165a5d5cbe27ef255403d7929f91d6a17cdc Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 3 Apr 2018 08:53:34 +0900 Subject: [PATCH 1/5] Use NonNull in the allocator API This adapts dlmalloc to corresponding changes to the allocator API. --- src/global.rs | 33 +++++++++++++++++---------------- src/lib.rs | 50 +++++++++++++++++++++----------------------------- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/global.rs b/src/global.rs index 556286b..5882015 100644 --- a/src/global.rs +++ b/src/global.rs @@ -1,5 +1,6 @@ use alloc::heap::{Alloc, Layout, Excess, CannotReallocInPlace, AllocErr}; use core::ops::{Deref, DerefMut}; +use core::ptr::NonNull; use Dlmalloc; @@ -7,27 +8,27 @@ pub struct GlobalDlmalloc; unsafe impl Alloc for GlobalDlmalloc { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { (&*self).alloc(layout) } #[inline] unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> + -> Result, AllocErr> { (&*self).alloc_zeroed(layout) } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { (&*self).dealloc(ptr, layout) } #[inline] unsafe fn realloc(&mut self, - ptr: *mut u8, + ptr: NonNull, old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { + new_layout: Layout) -> Result, AllocErr> { (&*self).realloc(ptr, old_layout, new_layout) } @@ -47,7 +48,7 @@ unsafe impl Alloc for GlobalDlmalloc { #[inline] unsafe fn realloc_excess(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_layout: Layout) -> Result { (&*self).realloc_excess(ptr, layout, new_layout) @@ -55,7 +56,7 @@ unsafe impl Alloc for GlobalDlmalloc { #[inline] unsafe fn grow_in_place(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { (&*self).grow_in_place(ptr, layout, new_layout) @@ -63,7 +64,7 @@ unsafe impl Alloc for GlobalDlmalloc { #[inline] unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { (&*self).shrink_in_place(ptr, layout, new_layout) @@ -99,24 +100,24 @@ impl Drop for Instance { } unsafe impl<'a> Alloc for &'a GlobalDlmalloc { - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { get().alloc(layout) } unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> + -> Result, AllocErr> { get().alloc_zeroed(layout) } - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { get().dealloc(ptr, layout) } unsafe fn realloc(&mut self, - ptr: *mut u8, + ptr: NonNull, old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { + new_layout: Layout) -> Result, AllocErr> { get().realloc(ptr, old_layout, new_layout) } @@ -135,7 +136,7 @@ unsafe impl<'a> Alloc for &'a GlobalDlmalloc { #[inline] unsafe fn realloc_excess(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_layout: Layout) -> Result { get().realloc_excess(ptr, layout, new_layout) @@ -143,7 +144,7 @@ unsafe impl<'a> Alloc for &'a GlobalDlmalloc { #[inline] unsafe fn grow_in_place(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { get().grow_in_place(ptr, layout, new_layout) @@ -151,7 +152,7 @@ unsafe impl<'a> Alloc for &'a GlobalDlmalloc { #[inline] unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, + ptr: NonNull, layout: Layout, new_layout: Layout) -> Result<(), CannotReallocInPlace> { get().shrink_in_place(ptr, layout, new_layout) diff --git a/src/lib.rs b/src/lib.rs index c130d9e..96d0bc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ extern crate alloc; use alloc::heap::{Alloc, Layout, AllocErr}; use core::cmp; -use core::ptr; +use core::ptr::{self, NonNull}; pub use self::global::GlobalDlmalloc; @@ -35,42 +35,38 @@ impl Dlmalloc { unsafe impl Alloc for Dlmalloc { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { let ptr = 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) - } + NonNull::new(ptr).ok_or_else(|| AllocErr::Exhausted { request: layout }) } #[inline] unsafe fn alloc_zeroed(&mut self, layout: Layout) - -> Result<*mut u8, AllocErr> + -> Result, AllocErr> { let size = layout.size(); let ptr = self.alloc(layout)?; - if self.0.calloc_must_clear(ptr) { - ptr::write_bytes(ptr, 0, size); + if self.0.calloc_must_clear(ptr.as_ptr()) { + ptr::write_bytes(ptr.as_ptr(), 0, size); } Ok(ptr) } #[inline] - unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { drop(layout); - self.0.free(ptr) + self.0.free(ptr.as_ptr()) } #[inline] unsafe fn realloc(&mut self, - ptr: *mut u8, + ptr: NonNull, old_layout: Layout, - new_layout: Layout) -> Result<*mut u8, AllocErr> { + new_layout: Layout) -> Result, AllocErr> { if old_layout.align() != new_layout.align() { return Err(AllocErr::Unsupported { details: "cannot change alignment on `realloc`", @@ -78,17 +74,13 @@ unsafe impl Alloc for Dlmalloc { } 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 }) - } + let ptr = self.0.realloc(ptr.as_ptr(), new_layout.size()); + NonNull::new(ptr).ok_or_else(|| AllocErr::Exhausted { request: new_layout }) } else { let res = self.alloc(new_layout.clone()); if let Ok(new_ptr) = res { let size = cmp::min(old_layout.size(), new_layout.size()); - ptr::copy_nonoverlapping(ptr, new_ptr, size); + ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), size); self.dealloc(ptr, old_layout); } res @@ -111,7 +103,7 @@ unsafe impl Alloc for Dlmalloc { // // #[inline] // unsafe fn realloc_excess(&mut self, - // ptr: *mut u8, + // ptr: NonNull, // layout: Layout, // new_layout: Layout) -> Result { // (&*self).realloc_excess(ptr, layout, new_layout) @@ -119,7 +111,7 @@ unsafe impl Alloc for Dlmalloc { // // #[inline] // unsafe fn grow_in_place(&mut self, - // ptr: *mut u8, + // ptr: NonNull, // layout: Layout, // new_layout: Layout) -> Result<(), CannotReallocInPlace> { // (&*self).grow_in_place(ptr, layout, new_layout) @@ -127,7 +119,7 @@ unsafe impl Alloc for Dlmalloc { // // #[inline] // unsafe fn shrink_in_place(&mut self, - // ptr: *mut u8, + // ptr: NonNull, // layout: Layout, // new_layout: Layout) -> Result<(), CannotReallocInPlace> { // (&*self).shrink_in_place(ptr, layout, new_layout) @@ -136,27 +128,27 @@ unsafe impl Alloc for Dlmalloc { // unsafe impl<'a> Alloc for &'a Dlmalloc { // #[inline] -// unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { +// unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { // panic!() // } // // // #[inline] // // unsafe fn alloc_zeroed(&mut self, layout: Layout) -// // -> Result<*mut u8, AllocErr> +// // -> Result, AllocErr> // // { // // panic!() // // } // // #[inline] -// unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { +// unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { // panic!() // } // // // #[inline] // // unsafe fn realloc(&mut self, -// // ptr: *mut u8, +// // ptr: NonNull, // // old_layout: Layout, -// // new_layout: Layout) -> Result<*mut u8, AllocErr> { +// // new_layout: Layout) -> Result, AllocErr> { // // panic!() // // } // From e2bafe20ab7a0298e7a54582732b1da37c59037d Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 3 Apr 2018 15:43:01 +0200 Subject: [PATCH 2/5] Make AllocErr a zero-size unit struct --- src/lib.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c130d9e..4f25d52 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ unsafe impl Alloc for Dlmalloc { self.0.memalign(layout.align(), layout.size()) }; if ptr.is_null() { - Err(AllocErr::Exhausted { request: layout }) + Err(AllocErr) } else { Ok(ptr) } @@ -72,9 +72,7 @@ unsafe impl Alloc for Dlmalloc { 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`", - }) + return Err(AllocErr) } if new_layout.align() <= self.0.malloc_alignment() { @@ -82,7 +80,7 @@ unsafe impl Alloc for Dlmalloc { if !ptr.is_null() { Ok(ptr as *mut u8) } else { - Err(AllocErr::Exhausted { request: new_layout }) + Err(AllocErr) } } else { let res = self.alloc(new_layout.clone()); From 268d930dc9a739669ed568e91ed2daf9a628a51a Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 3 Apr 2018 15:59:18 +0200 Subject: [PATCH 3/5] Remove the now-unit-struct AllocErr parameter of oom() --- tests/smoke.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 { From 2872a974034858156a9710ccb07532a107506ddf Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 17:39:01 +0200 Subject: [PATCH 4/5] realloc with a new size only, not a full new layout. Changing the alignment with realloc is not supported. --- src/global.rs | 32 ++++++++++++++++---------------- src/lib.rs | 33 +++++++++++++++------------------ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/global.rs b/src/global.rs index 556286b..b13bcc0 100644 --- a/src/global.rs +++ b/src/global.rs @@ -27,8 +27,8 @@ unsafe impl Alloc for GlobalDlmalloc { 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) + new_size: usize) -> Result<*mut u8, AllocErr> { + (&*self).realloc(ptr, old_layout, new_size) } // fn oom(&mut self, err: AllocErr) -> ! { @@ -49,24 +49,24 @@ unsafe impl Alloc for GlobalDlmalloc { unsafe fn realloc_excess(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result { - (&*self).realloc_excess(ptr, layout, new_layout) + new_size: usize) -> Result { + (&*self).realloc_excess(ptr, layout, new_size) } #[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) + new_size: usize) -> Result<(), CannotReallocInPlace> { + (&*self).grow_in_place(ptr, layout, new_size) } #[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) + new_size: usize) -> Result<(), CannotReallocInPlace> { + (&*self).shrink_in_place(ptr, layout, new_size) } } @@ -116,8 +116,8 @@ unsafe impl<'a> Alloc for &'a GlobalDlmalloc { 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) + new_size: usize) -> Result<*mut u8, AllocErr> { + get().realloc(ptr, old_layout, new_size) } // fn oom(&mut self, err: AllocErr) -> ! { @@ -137,23 +137,23 @@ unsafe impl<'a> Alloc for &'a GlobalDlmalloc { unsafe fn realloc_excess(&mut self, ptr: *mut u8, layout: Layout, - new_layout: Layout) -> Result { - get().realloc_excess(ptr, layout, new_layout) + new_size: usize) -> Result { + get().realloc_excess(ptr, layout, new_size) } #[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) + new_size: usize) -> Result<(), CannotReallocInPlace> { + get().grow_in_place(ptr, layout, new_size) } #[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) + new_size: usize) -> Result<(), CannotReallocInPlace> { + get().shrink_in_place(ptr, layout, new_size) } } diff --git a/src/lib.rs b/src/lib.rs index 4f25d52..343d983 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,25 +69,22 @@ unsafe impl Alloc for Dlmalloc { #[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) - } - - if new_layout.align() <= self.0.malloc_alignment() { - let ptr = self.0.realloc(ptr, new_layout.size()); + layout: Layout, + new_size: usize) -> Result<*mut u8, AllocErr> { + if layout.align() <= self.0.malloc_alignment() { + let ptr = self.0.realloc(ptr, new_size); if !ptr.is_null() { Ok(ptr as *mut u8) } else { Err(AllocErr) } } else { - let res = self.alloc(new_layout.clone()); + let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); + let res = self.alloc(new_layout); if let Ok(new_ptr) = res { - let size = cmp::min(old_layout.size(), new_layout.size()); + 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 } @@ -111,24 +108,24 @@ unsafe impl Alloc for Dlmalloc { // unsafe fn realloc_excess(&mut self, // ptr: *mut u8, // layout: Layout, - // new_layout: Layout) -> Result { - // (&*self).realloc_excess(ptr, layout, new_layout) + // new_size: usize) -> Result { + // (&*self).realloc_excess(ptr, layout, new_size) // } // // #[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) + // new_size: usize) -> Result<(), CannotReallocInPlace> { + // (&*self).grow_in_place(ptr, layout, new_size) // } // // #[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) + // new_size: usize) -> Result<(), CannotReallocInPlace> { + // (&*self).shrink_in_place(ptr, layout, new_size) // } } @@ -154,7 +151,7 @@ unsafe impl Alloc for Dlmalloc { // // unsafe fn realloc(&mut self, // // ptr: *mut u8, // // old_layout: Layout, -// // new_layout: Layout) -> Result<*mut u8, AllocErr> { +// // new_size: usize) -> Result<*mut u8, AllocErr> { // // panic!() // // } // From c02f7c9a97dd839941a4b2ffecdea9de394abc83 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 4 Apr 2018 18:24:56 +0200 Subject: [PATCH 5/5] `GlobalAlloc for GlobalDlmalloc` and `Alloc for Dlmalloc` only --- src/global.rs | 123 ++++------------------------------------ src/lib.rs | 154 ++++++++++++++++++-------------------------------- 2 files changed, 64 insertions(+), 213 deletions(-) diff --git a/src/global.rs b/src/global.rs index b13bcc0..2f041a7 100644 --- a/src/global.rs +++ b/src/global.rs @@ -1,75 +1,10 @@ -use alloc::heap::{Alloc, Layout, Excess, CannotReallocInPlace, AllocErr}; +use core::alloc::{GlobalAlloc, Layout, Void}; use core::ops::{Deref, DerefMut}; 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_size: usize) -> Result<*mut u8, AllocErr> { - (&*self).realloc(ptr, old_layout, new_size) - } - - // 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_size: usize) -> Result { - (&*self).realloc_excess(ptr, layout, new_size) - } - - #[inline] - unsafe fn grow_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { - (&*self).grow_in_place(ptr, layout, new_size) - } - - #[inline] - unsafe fn shrink_in_place(&mut self, - ptr: *mut u8, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { - (&*self).shrink_in_place(ptr, layout, new_size) - } -} - static mut DLMALLOC: Dlmalloc = Dlmalloc(::dlmalloc::DLMALLOC_INIT); struct Instance; @@ -98,62 +33,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_size: usize) -> Result<*mut u8, AllocErr> { - get().realloc(ptr, old_layout, new_size) - } - - // 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_size: usize) -> Result { - get().realloc_excess(ptr, layout, new_size) + 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_size: usize) -> Result<(), CannotReallocInPlace> { - get().grow_in_place(ptr, layout, new_size) + 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_size: usize) -> Result<(), CannotReallocInPlace> { - get().shrink_in_place(ptr, layout, new_size) + 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 343d983..38174ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,8 @@ -#![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; @@ -33,129 +31,85 @@ 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) - } 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, - layout: Layout, - new_size: usize) -> Result<*mut u8, AllocErr> { + unsafe fn ptr_realloc(&mut self, + ptr: *mut u8, + layout: Layout, + new_size: usize) -> *mut u8 { if layout.align() <= self.0.malloc_alignment() { - let ptr = self.0.realloc(ptr, new_size); - if !ptr.is_null() { - Ok(ptr as *mut u8) - } else { - Err(AllocErr) - } + self.0.realloc(ptr, new_size) } else { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); - let res = self.alloc(new_layout); - if let Ok(new_ptr) = res { + 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, 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_size: usize) -> Result { - // (&*self).realloc_excess(ptr, layout, new_size) - // } - // - // #[inline] - // unsafe fn grow_in_place(&mut self, - // ptr: *mut u8, - // layout: Layout, - // new_size: usize) -> Result<(), CannotReallocInPlace> { - // (&*self).grow_in_place(ptr, layout, new_size) - // } - // - // #[inline] - // unsafe fn shrink_in_place(&mut self, - // ptr: *mut u8, - // layout: Layout, - // new_size: usize) -> Result<(), CannotReallocInPlace> { - // (&*self).shrink_in_place(ptr, layout, new_size) - // } +fn to_result(ptr: *mut u8) -> Result<*mut u8, AllocErr> { + if !ptr.is_null() { + Ok(ptr) + } else { + Err(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_size: usize) -> 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<*mut u8, AllocErr> { + to_result(self.ptr_alloc(layout)) + } + + #[inline] + unsafe fn alloc_zeroed(&mut self, layout: Layout) + -> Result<*mut u8, AllocErr> + { + to_result(self.ptr_alloc_zeroed(layout)) + } + + #[inline] + unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + self.ptr_dealloc(ptr, layout) + } + + #[inline] + unsafe fn realloc(&mut self, + ptr: *mut u8, + layout: Layout, + new_size: usize) -> Result<*mut u8, AllocErr> { + to_result(self.ptr_realloc(ptr, layout, new_size)) + } +}