garbage collection - traduccion - Gestionar la vida útil de los objetos recogidos en la basura.
garbage collector yugioh (0)
Estoy haciendo un recolector de basura de marca y compacta simplista. Sin entrar demasiado en los detalles, la API que expone es así:
/// 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;
}
Esta API es, obviamente, fundamentalmente insegura. Me gustaría volver a trabajar en la API (sin cambiar los elementos internos, ¡lo cual está bien!) Para tener en cuenta los siguientes hechos:
Todos los
Pointer
a (objetos asignados en) unHeap
vuelven inválidos cuando el montón semerge
d en otro montón.merge
devuelve unAdjust
cuyos valores sonPointer
válidos a (objetos asignados en)self
.
Tengo la siguiente solución tentativa:
// 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>;
}
¿Es este diseño correcto? Si no, ¿qué necesita ser cambiado?