From 59ff059cfc2d8a4b3edf72644668beffd7bbc6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 1 Apr 2019 22:35:13 +0200 Subject: [PATCH] Add ensure_capacity and rename min to len --- src/libarena/lib.rs | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index bfc09cc1f89aa..0a5b79c36aad8 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -161,14 +161,21 @@ impl TypedArena { available_capacity_bytes >= at_least_bytes } + /// Ensures there's enough space in the current chunk to fit `len` objects. + #[inline] + fn ensure_capacity(&self, len: usize) { + if !self.can_allocate(len) { + self.grow(len); + debug_assert!(self.can_allocate(len)); + } + } + #[inline] unsafe fn alloc_raw_slice(&self, len: usize) -> *mut T { assert!(mem::size_of::() != 0); assert!(len != 0); - if !self.can_allocate(len) { - self.grow(len); - } + self.ensure_capacity(len); let start_ptr = self.ptr.get(); self.ptr.set(start_ptr.add(len)); @@ -203,19 +210,20 @@ impl TypedArena { match size_hint { (min, Some(max)) if min == max => { - if min == 0 { + // We know the exact number of elements the iterator will produce here + let len = min; + + if len == 0 { return &mut []; } - if !self.can_allocate(min) { - self.grow(min); - } + self.ensure_capacity(len); let slice = self.ptr.get(); unsafe { let mut ptr = self.ptr.get(); - for _ in 0..min { + for _ in 0..len { // Write into uninitialized memory. ptr::write(ptr, iter.next().unwrap()); // Advance the pointer. @@ -224,7 +232,7 @@ impl TypedArena { // we destroy the correct amount self.ptr.set(ptr); } - slice::from_raw_parts_mut(slice, min) + slice::from_raw_parts_mut(slice, len) } } _ => { @@ -239,7 +247,7 @@ impl TypedArena { let len = vec.len(); let start_ptr = self.alloc_raw_slice(len); vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); - vev.set_len(0); + vec.set_len(0); slice::from_raw_parts_mut(start_ptr, len) } }) @@ -488,16 +496,19 @@ impl DroplessArena { match size_hint { (min, Some(max)) if min == max => { - if min == 0 { + // We know the exact number of elements the iterator will produce here + let len = min; + + if len == 0 { return &mut [] } - let size = min.checked_mul(mem::size_of::()).unwrap(); + let size = len.checked_mul(mem::size_of::()).unwrap(); let mem = self.alloc_raw(size, mem::align_of::()) as *mut _ as *mut T; unsafe { - for i in 0..min { + for i in 0..len { ptr::write(mem.offset(i as isize), iter.next().unwrap()) } - slice::from_raw_parts_mut(mem, min) + slice::from_raw_parts_mut(mem, len) } } (_, _) => { @@ -515,7 +526,7 @@ impl DroplessArena { mem::align_of::() ) as *mut _ as *mut T; vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); - vev.set_len(0); + vec.set_len(0); slice::from_raw_parts_mut(start_ptr, len) } })