Я делаю упрощенный марк-и-компактный сборщик мусора. Не вдаваясь в подробности, API, который он предоставляет, выглядит следующим образом:
/// Describes the internal structure of a managed object.
pub struct Tag { ... }
/// An unmanaged pointer to a managed object.
pub type Pointer = *mut usize;
/// Mapping from old to new locations.
pub type Adjust = BTreeMap<usize, Pointer>;
/// Mark this object and anything it points to as non-garbage.
pub unsafe fn survive(ptr: Pointer);
pub struct Heap { ... }
impl Heap {
pub fn new() -> Heap;
// Allocate an object with the specified structure.
pub fn allocate(&mut self, tag: Tag) -> Pointer;
/// Move all live objects from `heap` into `self`.
puf unsafe fn reallocate(&mut self, heap: Heap) -> Adjust;
}
Этот API, очевидно, принципиально небезопасен. Я хотел бы переработать API (без изменения внутренних функций, которые просто прекрасны!), Чтобы учесть следующие факты:
-
Все
Pointer
to (объекты, выделенные в) aHeap
становятся недействительными, когда кучаmerge
d в другую кучу. -
merge
возвращаетAdjust
, значения которого действительныPointer
to (выделенные объекты)self
.
У меня есть следующее предварительное решение:
// Replaces Pointer.
#[derive(Copy, Clone)]
pub struct Object<'a> {
ptr: *mut AtomicUsize,
mark: PhantomData<&'a usize>
}
impl<'a> Object<'a> {
pub fn survive(self); // Now supposed to be perfectly safe!
}
pub type Adjust<'a> = BTreeMap<usize, Object<'a>>;
pub struct Heap { ... }
pub struct Allocator<'a> { ... }
impl Heap {
fn allocator(&'a self) -> Allocator<'a>;
// The following doesn't work:
//
// fn allocate(&'a mut self) -> Object<'a>;
// fn reallocate(&'a mut self, heap: Heap) -> Adjust<'a>;
//
// Because it doesn't allow the user to allocate more
// than one `Object` at a time (!) in a `Heap`.
}
impl<'a> Allocator<'a> {
// Note that the resulting `Object`s are tied to the `Heap`,
// but not to the allocator itself.
fn allocate(&mut self, tag: Tag) -> Object<'a>;
fn reallocate(&mut self, heap: Heap) -> Adjust<'a>;
}
Правильно ли этот дизайн? Если нет, что нужно изменить?