Skip to content

Commit 6aff92a

Browse files
committed
move DropArena -> libarena
1 parent 38114ff commit 6aff92a

File tree

2 files changed

+82
-86
lines changed

2 files changed

+82
-86
lines changed

src/libarena/lib.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,5 +488,86 @@ impl DroplessArena {
488488
}
489489
}
490490

491+
/// Calls the destructor for an object when dropped.
492+
struct DropType {
493+
drop_fn: unsafe fn(*mut u8),
494+
obj: *mut u8,
495+
}
496+
497+
unsafe fn drop_for_type<T>(to_drop: *mut u8) {
498+
std::ptr::drop_in_place(to_drop as *mut T)
499+
}
500+
501+
impl Drop for DropType {
502+
fn drop(&mut self) {
503+
unsafe { (self.drop_fn)(self.obj) }
504+
}
505+
}
506+
507+
/// An arena which can be used to allocate any type.
508+
/// Allocating in this arena is unsafe since the type system
509+
/// doesn't know which types it contains. In order to
510+
/// allocate safely, you must store a PhantomData<T>
511+
/// alongside this arena for each type T you allocate.
512+
#[derive(Default)]
513+
pub struct DropArena {
514+
/// A list of destructors to run when the arena drops.
515+
/// Ordered so `destructors` gets dropped before the arena
516+
/// since its destructor can reference memory in the arena.
517+
destructors: RefCell<Vec<DropType>>,
518+
arena: DroplessArena,
519+
}
520+
521+
impl DropArena {
522+
#[inline]
523+
pub unsafe fn alloc<T>(&self, object: T) -> &mut T {
524+
let mem =
525+
self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
526+
// Write into uninitialized memory.
527+
ptr::write(mem, object);
528+
let result = &mut *mem;
529+
// Record the destructor after doing the allocation as that may panic
530+
// and would cause `object`'s destuctor to run twice if it was recorded before
531+
self.destructors
532+
.borrow_mut()
533+
.push(DropType { drop_fn: drop_for_type::<T>, obj: result as *mut T as *mut u8 });
534+
result
535+
}
536+
537+
#[inline]
538+
pub unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
539+
let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
540+
if vec.is_empty() {
541+
return &mut [];
542+
}
543+
let len = vec.len();
544+
545+
let start_ptr = self
546+
.arena
547+
.alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>())
548+
as *mut _ as *mut T;
549+
550+
let mut destructors = self.destructors.borrow_mut();
551+
// Reserve space for the destructors so we can't panic while adding them
552+
destructors.reserve(len);
553+
554+
// Move the content to the arena by copying it and then forgetting
555+
// the content of the SmallVec
556+
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
557+
mem::forget(vec.drain(..));
558+
559+
// Record the destructors after doing the allocation as that may panic
560+
// and would cause `object`'s destuctor to run twice if it was recorded before
561+
for i in 0..len {
562+
destructors.push(DropType {
563+
drop_fn: drop_for_type::<T>,
564+
obj: start_ptr.offset(i as isize) as *mut u8,
565+
});
566+
}
567+
568+
slice::from_raw_parts_mut(start_ptr, len)
569+
}
570+
}
571+
491572
#[cfg(test)]
492573
mod tests;

src/librustc/arena.rs

Lines changed: 1 addition & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
use arena::{DroplessArena, TypedArena};
2-
use smallvec::SmallVec;
3-
use std::cell::RefCell;
1+
use arena::{DropArena, DroplessArena, TypedArena};
42
use std::marker::PhantomData;
53
use std::mem;
6-
use std::ptr;
7-
use std::slice;
84

95
/// This declares a list of types which can be allocated by `Arena`.
106
///
@@ -275,84 +271,3 @@ impl<'tcx> Arena<'tcx> {
275271
}
276272
}
277273
}
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

Comments
 (0)