Skip to content

Commit c213036

Browse files
bugadaniLonamiest31
committed
Don't copy into arena when we had to heap allocate for iter
Co-authored-by: Lonami <totufals@hotmail.com> Co-authored-by: est31 <est31@users.noreply.github.com>
1 parent 8850893 commit c213036

File tree

1 file changed

+23
-11
lines changed
  • compiler/rustc_arena/src

1 file changed

+23
-11
lines changed

compiler/rustc_arena/src/lib.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ pub struct TypedArena<T> {
4444
/// A vector of arena chunks.
4545
chunks: RefCell<Vec<TypedArenaChunk<T>>>,
4646

47+
/// A vector that holds references to heap allocated vectors.
48+
vecs: RefCell<Vec<Vec<T>>>,
49+
4750
/// Marker indicating that dropping the arena causes its owned
4851
/// instances of `T` to be dropped.
4952
_own: PhantomData<T>,
@@ -109,6 +112,7 @@ impl<T> Default for TypedArena<T> {
109112
ptr: Cell::new(ptr::null_mut()),
110113
end: Cell::new(ptr::null_mut()),
111114
chunks: RefCell::new(vec![]),
115+
vecs: RefCell::new(vec![]),
112116
_own: PhantomData,
113117
}
114118
}
@@ -192,17 +196,25 @@ impl<T> TypedArena<T> {
192196
pub fn alloc_from_iter<I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
193197
assert!(mem::size_of::<T>() != 0);
194198
let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
195-
if vec.is_empty() {
196-
return &mut [];
197-
}
198-
// Move the content to the arena by copying it and then forgetting
199-
// the content of the SmallVec
200-
unsafe {
201-
let len = vec.len();
202-
let start_ptr = self.alloc_raw_slice(len);
203-
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
204-
vec.set_len(0);
205-
slice::from_raw_parts_mut(start_ptr, len)
199+
if vec.spilled() {
200+
// Don't copy the vector contents, store the vector in a separate list instead
201+
let mut vec = vec.into_vec();
202+
let slice = unsafe { slice::from_raw_parts_mut(vec.as_mut_ptr(), vec.len()) };
203+
self.vecs.borrow_mut().push(vec);
204+
slice
205+
} else {
206+
if vec.is_empty() {
207+
return &mut [];
208+
}
209+
// Move the content to the arena by copying it and then forgetting
210+
// the content of the SmallVec
211+
unsafe {
212+
let len = vec.len();
213+
let start_ptr = self.alloc_raw_slice(len);
214+
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
215+
vec.set_len(0);
216+
slice::from_raw_parts_mut(start_ptr, len)
217+
}
206218
}
207219
}
208220

0 commit comments

Comments
 (0)