diff --git a/include/xo/alloc2/gc/ACollector.hpp b/include/xo/alloc2/gc/ACollector.hpp index 1dfca96..72d3802 100644 --- a/include/xo/alloc2/gc/ACollector.hpp +++ b/include/xo/alloc2/gc/ACollector.hpp @@ -58,9 +58,14 @@ namespace xo { * Return false if installation fails (e.g. memory exhausted) **/ virtual bool install_type(Opaque d, const AGCObject & iface) = 0; + + /** add gc root with address @p p_root **/ virtual void add_gc_root_poly(Opaque d, obj * p_root) = 0; //virtual void add_gc_root_typed(Opaque d, typeseq tseq, Opaque * root) = 0; + /** remove gc root with address @p p_root **/ + virtual void remove_gc_root_poly(Opaque d, obj * p_root) = 0; + /** Request immediate collection. * 1. if collection is enabled, immediately collect all generations * up to (but not including) g diff --git a/include/xo/alloc2/gc/ICollector_Any.hpp b/include/xo/alloc2/gc/ICollector_Any.hpp index 6ed758c..555adc6 100644 --- a/include/xo/alloc2/gc/ICollector_Any.hpp +++ b/include/xo/alloc2/gc/ICollector_Any.hpp @@ -39,6 +39,7 @@ namespace xo { // non-const methods [[noreturn]] bool install_type(Opaque, const AGCObject &) noexcept override { _fatal(); } [[noreturn]] void add_gc_root_poly(Opaque, obj *) override { _fatal(); } + [[noreturn]] void remove_gc_root_poly(Opaque, obj *) override { _fatal(); } [[noreturn]] void request_gc(Opaque, generation) override { _fatal(); } [[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override { _fatal(); } diff --git a/include/xo/alloc2/gc/ICollector_Xfer.hpp b/include/xo/alloc2/gc/ICollector_Xfer.hpp index d7d43ef..4100c8c 100644 --- a/include/xo/alloc2/gc/ICollector_Xfer.hpp +++ b/include/xo/alloc2/gc/ICollector_Xfer.hpp @@ -53,6 +53,9 @@ namespace xo { void add_gc_root_poly(Opaque d, obj * p_root) override { I::add_gc_root_poly(_dcast(d), p_root); } + void remove_gc_root_poly(Opaque d, obj * p_root) override { + I::remove_gc_root_poly(_dcast(d), p_root); + } void request_gc(Opaque d, generation upto) override { I::request_gc(_dcast(d), upto); } diff --git a/include/xo/alloc2/gc/RCollector.hpp b/include/xo/alloc2/gc/RCollector.hpp index 9cce484..b9d3e3e 100644 --- a/include/xo/alloc2/gc/RCollector.hpp +++ b/include/xo/alloc2/gc/RCollector.hpp @@ -22,6 +22,9 @@ namespace xo { RCollector() = default; RCollector(DataPtr data) : Object{std::move(data)} {} + RCollector(const ACollector * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} /** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/ template @@ -33,6 +36,11 @@ namespace xo { template void forward_inplace(DRepr ** pp_repr); + /** convenience template where pointer requires pivot **/ + template + requires (!std::is_same_v) + void forward_pivot_inplace(obj * p_obj); + int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } size_type allocated(generation g, role r) const noexcept { return O::iface()->allocated(O::data(), g, r); } size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); } @@ -41,6 +49,7 @@ namespace xo { bool install_type(const AGCObject & iface) { return O::iface()->install_type(O::data(), iface); } void add_gc_root_poly(obj * p_root) { O::iface()->add_gc_root_poly(O::data(), p_root); } + void remove_gc_root_poly(obj * p_root) { O::iface()->remove_gc_root_poly(O::data(), p_root); } void request_gc(generation g) { O::iface()->request_gc(O::data(), g); } void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data); } @@ -50,6 +59,12 @@ namespace xo { O::iface()->add_gc_root_poly(O::data(), (obj *)p_root); } + /** remove root @p p_root **/ + template + void remove_gc_root(obj * p_root) { + O::iface()->remove_gc_root_poly(O::data(), (obj *)p_root); + } + static bool _valid; }; diff --git a/include/xo/alloc2/gc/RCollector_aux.hpp b/include/xo/alloc2/gc/RCollector_aux.hpp index b85c73b..5e56035 100644 --- a/include/xo/alloc2/gc/RCollector_aux.hpp +++ b/include/xo/alloc2/gc/RCollector_aux.hpp @@ -10,6 +10,8 @@ #pragma once +#include + namespace xo { namespace mm { /** defined here to avoid #include cycle, since @@ -34,6 +36,16 @@ namespace xo { this->forward_inplace(&iface, (void **)p_repr); } + + template + template + requires (!std::is_same_v) + void + RCollector::forward_pivot_inplace(obj * p_objs) + { + auto e = xo::facet::FacetRegistry::instance().variant(*p_objs); + this->forward_inplace(e.iface(), (void **)&(p_objs->data_)); + } } } diff --git a/src/alloc2/CollectorTypeRegistry.cpp b/src/alloc2/CollectorTypeRegistry.cpp index 98d45a8..33f307c 100644 --- a/src/alloc2/CollectorTypeRegistry.cpp +++ b/src/alloc2/CollectorTypeRegistry.cpp @@ -1,4 +1,6 @@ /** @file CollectorTypeRegistry.cpp + * + * @author Roland Conybeare, Mar 2026 **/ #include "CollectorTypeRegistry.hpp"