diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-05-02 08:02:57 +0200 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-05-27 17:28:35 +0200 |
| commit | 6c2d875261e10105dcfcbd9be84d05a730edd235 (patch) | |
| tree | 490055facae889ab36bd2025ef326eae63767333 /src/libarena | |
| parent | a52b01bc67068fbd30206db53f2a3461f65e629e (diff) | |
Make &Slice a thin pointer
Diffstat (limited to 'src/libarena')
| -rw-r--r-- | src/libarena/lib.rs | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index f7143a4f981..b6a81596d06 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -314,8 +314,7 @@ impl DroplessArena { false } - fn align_for<T>(&self) { - let align = mem::align_of::<T>(); + fn align(&self, align: usize) { let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1); self.ptr.set(final_address as *mut u8); assert!(self.ptr <= self.end); @@ -323,8 +322,7 @@ impl DroplessArena { #[inline(never)] #[cold] - fn grow<T>(&self, n: usize) { - let needed_bytes = n * mem::size_of::<T>(); + fn grow(&self, needed_bytes: usize) { unsafe { let mut chunks = self.chunks.borrow_mut(); let (chunk, mut new_capacity); @@ -356,25 +354,38 @@ impl DroplessArena { } #[inline] - pub fn alloc<T>(&self, object: T) -> &mut T { + pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] { unsafe { - assert!(!mem::needs_drop::<T>()); - assert!(mem::size_of::<T>() != 0); + assert!(bytes != 0); + + self.align(align); - self.align_for::<T>(); - let future_end = intrinsics::arith_offset(self.ptr.get(), mem::size_of::<T>() as isize); + let future_end = intrinsics::arith_offset(self.ptr.get(), bytes as isize); if (future_end as *mut u8) >= self.end.get() { - self.grow::<T>(1) + self.grow(bytes); } let ptr = self.ptr.get(); // Set the pointer past ourselves self.ptr.set( - intrinsics::arith_offset(self.ptr.get(), mem::size_of::<T>() as isize) as *mut u8, + intrinsics::arith_offset(self.ptr.get(), bytes as isize) as *mut u8, ); + slice::from_raw_parts_mut(ptr, bytes) + } + } + + #[inline] + pub fn alloc<T>(&self, object: T) -> &mut T { + assert!(!mem::needs_drop::<T>()); + + let mem = self.alloc_raw( + mem::size_of::<T>(), + mem::align_of::<T>()) as *mut _ as *mut T; + + unsafe { // Write into uninitialized memory. - ptr::write(ptr as *mut T, object); - &mut *(ptr as *mut T) + ptr::write(mem, object); + &mut *mem } } @@ -393,21 +404,13 @@ impl DroplessArena { assert!(!mem::needs_drop::<T>()); assert!(mem::size_of::<T>() != 0); assert!(slice.len() != 0); - self.align_for::<T>(); - let future_end = unsafe { - intrinsics::arith_offset(self.ptr.get(), (slice.len() * mem::size_of::<T>()) as isize) - }; - if (future_end as *mut u8) >= self.end.get() { - self.grow::<T>(slice.len()); - } + let mem = self.alloc_raw( + slice.len() * mem::size_of::<T>(), + mem::align_of::<T>()) as *mut _ as *mut T; unsafe { - let arena_slice = slice::from_raw_parts_mut(self.ptr.get() as *mut T, slice.len()); - self.ptr.set(intrinsics::arith_offset( - self.ptr.get(), - (slice.len() * mem::size_of::<T>()) as isize, - ) as *mut u8); + let arena_slice = slice::from_raw_parts_mut(mem, slice.len()); arena_slice.copy_from_slice(slice); arena_slice } @@ -465,6 +468,12 @@ impl SyncDroplessArena { } #[inline(always)] + pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] { + // Extend the lifetime of the result since it's limited to the lock guard + unsafe { &mut *(self.lock.lock().alloc_raw(bytes, align) as *mut [u8]) } + } + + #[inline(always)] pub fn alloc<T>(&self, object: T) -> &mut T { // Extend the lifetime of the result since it's limited to the lock guard unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) } |
