|
1 | | -use arena::{DroplessArena, TypedArena}; |
2 | | -use smallvec::SmallVec; |
3 | | -use std::cell::RefCell; |
| 1 | +use arena::{DropArena, DroplessArena, TypedArena}; |
4 | 2 | use std::marker::PhantomData; |
5 | 3 | use std::mem; |
6 | | -use std::ptr; |
7 | | -use std::slice; |
8 | 4 |
|
9 | 5 | /// This declares a list of types which can be allocated by `Arena`. |
10 | 6 | /// |
@@ -275,84 +271,3 @@ impl<'tcx> Arena<'tcx> { |
275 | 271 | } |
276 | 272 | } |
277 | 273 | } |
278 | | - |
279 | | -/// Calls the destructor for an object when dropped. |
280 | | -struct DropType { |
281 | | - drop_fn: unsafe fn(*mut u8), |
282 | | - obj: *mut u8, |
283 | | -} |
284 | | - |
285 | | -unsafe fn drop_for_type<T>(to_drop: *mut u8) { |
286 | | - std::ptr::drop_in_place(to_drop as *mut T) |
287 | | -} |
288 | | - |
289 | | -impl Drop for DropType { |
290 | | - fn drop(&mut self) { |
291 | | - unsafe { (self.drop_fn)(self.obj) } |
292 | | - } |
293 | | -} |
294 | | - |
295 | | -/// An arena which can be used to allocate any type. |
296 | | -/// Allocating in this arena is unsafe since the type system |
297 | | -/// doesn't know which types it contains. In order to |
298 | | -/// allocate safely, you must store a PhantomData<T> |
299 | | -/// alongside this arena for each type T you allocate. |
300 | | -#[derive(Default)] |
301 | | -struct DropArena { |
302 | | - /// A list of destructors to run when the arena drops. |
303 | | - /// Ordered so `destructors` gets dropped before the arena |
304 | | - /// since its destructor can reference memory in the arena. |
305 | | - destructors: RefCell<Vec<DropType>>, |
306 | | - arena: DroplessArena, |
307 | | -} |
308 | | - |
309 | | -impl DropArena { |
310 | | - #[inline] |
311 | | - unsafe fn alloc<T>(&self, object: T) -> &mut T { |
312 | | - let mem = |
313 | | - self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T; |
314 | | - // Write into uninitialized memory. |
315 | | - ptr::write(mem, object); |
316 | | - let result = &mut *mem; |
317 | | - // Record the destructor after doing the allocation as that may panic |
318 | | - // and would cause `object`'s destuctor to run twice if it was recorded before |
319 | | - self.destructors |
320 | | - .borrow_mut() |
321 | | - .push(DropType { drop_fn: drop_for_type::<T>, obj: result as *mut T as *mut u8 }); |
322 | | - result |
323 | | - } |
324 | | - |
325 | | - #[inline] |
326 | | - unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] { |
327 | | - let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect(); |
328 | | - if vec.is_empty() { |
329 | | - return &mut []; |
330 | | - } |
331 | | - let len = vec.len(); |
332 | | - |
333 | | - let start_ptr = self |
334 | | - .arena |
335 | | - .alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>()) |
336 | | - as *mut _ as *mut T; |
337 | | - |
338 | | - let mut destructors = self.destructors.borrow_mut(); |
339 | | - // Reserve space for the destructors so we can't panic while adding them |
340 | | - destructors.reserve(len); |
341 | | - |
342 | | - // Move the content to the arena by copying it and then forgetting |
343 | | - // the content of the SmallVec |
344 | | - vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); |
345 | | - mem::forget(vec.drain(..)); |
346 | | - |
347 | | - // Record the destructors after doing the allocation as that may panic |
348 | | - // and would cause `object`'s destuctor to run twice if it was recorded before |
349 | | - for i in 0..len { |
350 | | - destructors.push(DropType { |
351 | | - drop_fn: drop_for_type::<T>, |
352 | | - obj: start_ptr.offset(i as isize) as *mut u8, |
353 | | - }); |
354 | | - } |
355 | | - |
356 | | - slice::from_raw_parts_mut(start_ptr, len) |
357 | | - } |
358 | | -} |
0 commit comments