|
15 | 15 | #![feature(dropck_eyepatch)]
|
16 | 16 | #![feature(new_uninit)]
|
17 | 17 | #![feature(maybe_uninit_slice)]
|
18 |
| -#![feature(min_specialization)] |
19 | 18 | #![feature(decl_macro)]
|
20 | 19 | #![feature(pointer_byte_offsets)]
|
21 | 20 | #![feature(rustc_attrs)]
|
@@ -113,77 +112,6 @@ impl<T> ArenaChunk<T> {
|
113 | 112 | const PAGE: usize = 4096;
|
114 | 113 | const HUGE_PAGE: usize = 2 * 1024 * 1024;
|
115 | 114 |
|
116 |
| -trait IterExt<T> { |
117 |
| - fn alloc_from_iter(self, arena: &TypedArena<T>) -> &mut [T]; |
118 |
| -} |
119 |
| - |
120 |
| -impl<I, T> IterExt<T> for I |
121 |
| -where |
122 |
| - I: IntoIterator<Item = T>, |
123 |
| -{ |
124 |
| - // This default collects into a `SmallVec` and then allocates by copying |
125 |
| - // from it. The specializations below for types like `Vec` are more |
126 |
| - // efficient, copying directly without the intermediate collecting step. |
127 |
| - #[inline] |
128 |
| - default fn alloc_from_iter(self, arena: &TypedArena<T>) -> &mut [T] { |
129 |
| - // Safety: if iteration panics, `self` is untouched, and thus left in a |
130 |
| - // good state. |
131 |
| - let vec: SmallVec<[_; 8]> = self.into_iter().collect(); |
132 |
| - vec.alloc_from_iter(arena) |
133 |
| - } |
134 |
| -} |
135 |
| - |
136 |
| -impl<T, const N: usize> IterExt<T> for [T; N] { |
137 |
| - #[inline] |
138 |
| - fn alloc_from_iter(self, arena: &TypedArena<T>) -> &mut [T] { |
139 |
| - let len = self.len(); |
140 |
| - if len == 0 { |
141 |
| - return &mut []; |
142 |
| - } |
143 |
| - // Move the content to the arena by copying and then forgetting it. |
144 |
| - let start_ptr = arena.alloc_raw_slice(len); |
145 |
| - unsafe { |
146 |
| - self.as_slice().as_ptr().copy_to_nonoverlapping(start_ptr, len); |
147 |
| - mem::forget(self); |
148 |
| - slice::from_raw_parts_mut(start_ptr, len) |
149 |
| - } |
150 |
| - } |
151 |
| -} |
152 |
| - |
153 |
| -impl<T> IterExt<T> for Vec<T> { |
154 |
| - #[inline] |
155 |
| - fn alloc_from_iter(mut self, arena: &TypedArena<T>) -> &mut [T] { |
156 |
| - let len = self.len(); |
157 |
| - if len == 0 { |
158 |
| - return &mut []; |
159 |
| - } |
160 |
| - // Move the content to the arena by copying and then forgetting it. |
161 |
| - let start_ptr = arena.alloc_raw_slice(len); |
162 |
| - unsafe { |
163 |
| - self.as_ptr().copy_to_nonoverlapping(start_ptr, len); |
164 |
| - self.set_len(0); |
165 |
| - slice::from_raw_parts_mut(start_ptr, len) |
166 |
| - } |
167 |
| - } |
168 |
| -} |
169 |
| - |
170 |
| -impl<A: smallvec::Array> IterExt<A::Item> for SmallVec<A> { |
171 |
| - #[inline] |
172 |
| - fn alloc_from_iter(mut self, arena: &TypedArena<A::Item>) -> &mut [A::Item] { |
173 |
| - let len = self.len(); |
174 |
| - if len == 0 { |
175 |
| - return &mut []; |
176 |
| - } |
177 |
| - // Move the content to the arena by copying and then forgetting it. |
178 |
| - let start_ptr = arena.alloc_raw_slice(len); |
179 |
| - unsafe { |
180 |
| - self.as_ptr().copy_to_nonoverlapping(start_ptr, len); |
181 |
| - self.set_len(0); |
182 |
| - slice::from_raw_parts_mut(start_ptr, len) |
183 |
| - } |
184 |
| - } |
185 |
| -} |
186 |
| - |
187 | 115 | /// An arena that can hold objects of only one type.
|
188 | 116 | pub struct TypedArena<T> {
|
189 | 117 | /// A pointer to the next object to be allocated.
|
@@ -282,10 +210,23 @@ impl<T> TypedArena<T> {
|
282 | 210 | // will then cause UB in `TypedArena::drop`.
|
283 | 211 | //
|
284 | 212 | // Instead we use an approach where any iterator panic will occur
|
285 |
| - // before the memory is allocated, with some specialization for common |
286 |
| - // cases like `Vec` and `SmallVec`. |
| 213 | + // before the memory is allocated. This function is much less hot than |
| 214 | + // `DroplessArena::alloc_from_iter`, so it doesn't need to be |
| 215 | + // hyper-optimized. |
287 | 216 | assert!(mem::size_of::<T>() != 0);
|
288 |
| - iter.alloc_from_iter(self) |
| 217 | + |
| 218 | + let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect(); |
| 219 | + if vec.is_empty() { |
| 220 | + return &mut []; |
| 221 | + } |
| 222 | + // Move the content to the arena by copying and then forgetting it. |
| 223 | + let len = vec.len(); |
| 224 | + let start_ptr = self.alloc_raw_slice(len); |
| 225 | + unsafe { |
| 226 | + vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); |
| 227 | + vec.set_len(0); |
| 228 | + slice::from_raw_parts_mut(start_ptr, len) |
| 229 | + } |
289 | 230 | }
|
290 | 231 |
|
291 | 232 | /// Grows the arena.
|
|
0 commit comments