Skip to content

Commit a449d8c

Browse files
committed
also broken
1 parent 87f8696 commit a449d8c

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

src/libarena/lib.rs

+41-4
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,19 @@ impl<T> TypedArena<T> {
153153
}
154154
}
155155

156+
#[inline]
157+
fn can_allocate(&self, len: usize) -> bool {
158+
let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize;
159+
let at_least_bytes = len * mem::size_of::<T>();
160+
available_capacity_bytes >= at_least_bytes
161+
}
162+
156163
#[inline]
157164
fn alloc_raw_slice(&self, len: usize) -> *mut T {
158165
assert!(mem::size_of::<T>() != 0);
159166
assert!(len != 0);
160167

161-
let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize;
162-
let at_least_bytes = len * mem::size_of::<T>();
163-
if available_capacity_bytes < at_least_bytes {
168+
if !self.can_allocate(len) {
164169
self.grow(len);
165170
}
166171

@@ -191,7 +196,39 @@ impl<T> TypedArena<T> {
191196

192197
pub fn alloc_from_iter<I: IntoIterator<Item=T>>(&self, iter: I) -> &[T] where T: Clone {
193198
assert!(mem::size_of::<T>() != 0);
194-
let vec: Vec<_> = iter.into_iter().collect();
199+
let mut iter = iter.into_iter();
200+
let size_hint = iter.size_hint();
201+
202+
match size_hint {
203+
(min, Some(max)) if min == max => {
204+
if min == 0 {
205+
return &[];
206+
}
207+
208+
if !self.can_allocate(min) {
209+
self.grow(min);
210+
}
211+
212+
let slice = self.ptr.get();
213+
214+
unsafe {
215+
let mut ptr = self.ptr.get();
216+
for _ in 0..min {
217+
// Write into uninitialized memory.
218+
ptr::write(ptr, iter.next().unwrap());
219+
// Advance the pointer.
220+
ptr = ptr.offset(1);
221+
// Update the pointer per iteration so if `iter.next()` panics
222+
// we destroy the correct amount
223+
self.ptr.set(ptr);
224+
}
225+
return slice::from_raw_parts_mut(slice, min);
226+
}
227+
}
228+
_ => (),
229+
}
230+
231+
let vec: Vec<_> = iter.collect();
195232
if vec.is_empty() {
196233
return &[]
197234
}

0 commit comments

Comments
 (0)