@@ -44,6 +44,9 @@ pub struct TypedArena<T> {
44
44
/// A vector of arena chunks.
45
45
chunks : RefCell < Vec < TypedArenaChunk < T > > > ,
46
46
47
+ /// A vector that holds references to heap allocated vectors.
48
+ vecs : RefCell < Vec < Vec < T > > > ,
49
+
47
50
/// Marker indicating that dropping the arena causes its owned
48
51
/// instances of `T` to be dropped.
49
52
_own : PhantomData < T > ,
@@ -109,6 +112,7 @@ impl<T> Default for TypedArena<T> {
109
112
ptr : Cell :: new ( ptr:: null_mut ( ) ) ,
110
113
end : Cell :: new ( ptr:: null_mut ( ) ) ,
111
114
chunks : RefCell :: new ( vec ! [ ] ) ,
115
+ vecs : RefCell :: new ( vec ! [ ] ) ,
112
116
_own : PhantomData ,
113
117
}
114
118
}
@@ -192,17 +196,25 @@ impl<T> TypedArena<T> {
192
196
pub fn alloc_from_iter < I : IntoIterator < Item = T > > ( & self , iter : I ) -> & mut [ T ] {
193
197
assert ! ( mem:: size_of:: <T >( ) != 0 ) ;
194
198
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
+ }
206
218
}
207
219
}
208
220
0 commit comments