@@ -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