diff --git a/CMakeLists.txt b/CMakeLists.txt index 79323a6..0b2b026 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,9 +19,9 @@ add_definitions(${PROJECT_CXX_FLAGS}) # ---------------------------------------------------------------- xo_add_genfacet( - TARGET xo-alloc2-facet-collector2 - FACET Collector2 - INPUT idl/Collector2.json5 + TARGET xo-alloc2-facet-collector + FACET Collector + INPUT idl/Collector.json5 ) # ---------------------------------------------------------------- diff --git a/idl/Collector2.json5 b/idl/Collector.json5 similarity index 84% rename from idl/Collector2.json5 rename to idl/Collector.json5 index 7bc9457..1d34445 100644 --- a/idl/Collector2.json5 +++ b/idl/Collector.json5 @@ -17,10 +17,11 @@ namespace1: "xo", namespace2: "mm", pretext: [ - "class AGCObject;", + "namespace xo { namespace mm { class AGCObject; } }", + "namespace xo { namespace mm { class IGCObject_Any; } }", "// more pretext here..", ], - facet: "Collector2", + facet: "Collector", detail_subdir: "gc", brief: "garbage collector interface", using_doxygen: true, @@ -218,5 +219,32 @@ attributes: [], }, ], - router_facet_explicit_content: [] + router_facet_explicit_content: [ + "/** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/", + "template ", + "void forward_inplace(obj * p_obj);", + "", + "/** another convenience template for forwarding.", + " * Defined in RGCObject.hpp to avoid #include cycle.", + "**/", + "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);", + "", + "/** add root @p p_root **/", + "template", + "void add_gc_root(obj * p_root) {", + " 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);", + "}", + ], } diff --git a/include/xo/alloc2/Collector.hpp b/include/xo/alloc2/Collector.hpp index 45c7fdb..afa41a6 100644 --- a/include/xo/alloc2/Collector.hpp +++ b/include/xo/alloc2/Collector.hpp @@ -1,6 +1,14 @@ /** @file Collector.hpp * - * @author Roland Conybeare, Dec 2025 + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Collector.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/Collector.json5] **/ #pragma once @@ -10,4 +18,5 @@ #include "gc/ICollector_Xfer.hpp" #include "gc/RCollector.hpp" + /* end Collector.hpp */ diff --git a/include/xo/alloc2/gc/ACollector.hpp b/include/xo/alloc2/gc/ACollector.hpp index 6b0cb90..0f5f91f 100644 --- a/include/xo/alloc2/gc/ACollector.hpp +++ b/include/xo/alloc2/gc/ACollector.hpp @@ -1,102 +1,127 @@ /** @file ACollector.hpp * - * @author Roland Conybeare, Dec 2025 + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Collector.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/Collector.json5] **/ #pragma once -//#include "IGCObject_Any.hpp" - -#include -#include -#include - +// includes (via {facet_includes}) +#include #include #include +#include +#include +#include -#include -#include +namespace xo { namespace mm { class AGCObject; } } +namespace xo { namespace mm { class IGCObject_Any; } } +// more pretext here.. namespace xo { - namespace mm { - using Copaque = const void *; - using Opaque = void *; +namespace mm { - class AGCObject; - class IGCObject_Any; // see IGCObject_Any.hpp +using Copaque = const void *; +using Opaque = void *; - /** @class ACollector - * @brief Abstract facet for the XO garbage collector - * - * A collector implementation will also support the @ref AAllocator facet, see also - **/ - class ACollector { - public: - using typeseq = xo::facet::typeseq; - using size_type = std::size_t; +/** +A collector must also suppose the @ref AAllocator facet, see also +**/ +class ACollector { +public: + /** @defgroup mm-collector-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + /** allocation size type **/ + using size_type = std::size_t; + ///@} - virtual typeseq _typeseq() const noexcept = 0; + /** @defgroup mm-collector-methods **/ + ///@{ + // const methods + /** An uninitialized ACollector instance will have zero vtable pointer (per {linux,osx} abi). + * Use case for this is narrow. We go to some lengths to avoid null vtable pointers. For example + * obj will have non-null vtable (via IFacet_Any) with all methods terminating. + **/ + bool _has_null_vptr() const noexcept { return *reinterpret_cast(this) == nullptr; } + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; + /** memory in use for this collector **/ + virtual size_type allocated(Copaque data, Generation g, role r) const noexcept = 0; + /** memory committed for this collector **/ + virtual size_type committed(Copaque data, Generation g, role r) const noexcept = 0; + /** address space reserved for this collector **/ + virtual size_type reserved(Copaque data, Generation g, role r) const noexcept = 0; + /** true if gc responsible for data at @p addr, and data belongs to role @p r **/ + virtual bool contains(Copaque data, role r, const void * addr) const noexcept = 0; + /** true iff gc-aware object of type @p tseq is installed in this collector **/ + virtual bool is_type_installed(Copaque data, typeseq tseq) const noexcept = 0; - virtual size_type allocated(Copaque d, - Generation g, role r) const noexcept = 0; - virtual size_type reserved(Copaque d, - Generation g, role r) const noexcept = 0; - virtual size_type committed(Copaque d, - Generation g, role r) const noexcept = 0; + // nonconst methods + /** install interface @p iface for representation with typeseq @p tseq +in collector @p d. - /** true if gc responsible for address @p addr with role @p r - **/ - virtual bool contains(Copaque d, - role r, const void * addr) const noexcept = 0; +The type AGCObject_Any here is misleading. +Will have been replaced by an instance of + @c AGCObject_Xfer for some @c DFoo +in which case calls through @c std::launder(&iface) +will properly act on @c DFoo. - virtual bool is_type_installed(Copaque d, - typeseq tseq) const noexcept = 0; +Return false if installation fails (e.g. memory exhausted) **/ + virtual bool install_type(Opaque data, const AGCObject & iface) = 0; + /** add gc root with address @p p_root. gc will preserve subgraph at this address **/ + virtual void add_gc_root_poly(Opaque data, obj * p_root) = 0; + /** remove gc root with address @p p_root. Reverse effect of prior add_gc_root_poly call **/ + virtual void remove_gc_root_poly(Opaque data, obj * p_root) = 0; + /** Request immediate collection. + 1. if collection is enabled, immediately collect all generations + up to (but not including) g + 2. may nevertheless escalate to older generations, + depending on collector state. + 3. if collection is currently disabled, + collection will trigger the next time gc is enabled. + **/ + virtual void request_gc(Opaque data, Generation upto) = 0; + /** Assign pointer @p p_lhs to destination @p rhs, within parent allocation @p parent - /** install interface @p iface for representation with typeseq @p tseq - * in collector @p d. - * - * The type AGCObject_Any here is misleading. - * Will have been replaced by an instance of - * @c AGCObject_Xfer for some @c DFoo - * in which case calls through @c std::launder(&iface) - * will properly act on @c DFoo. - * - * Return false if installation fails (e.g. memory exhausted) - **/ - virtual bool install_type(Opaque d, const AGCObject & iface) = 0; +Require: gc not in progress **/ + virtual void assign_member(Opaque data, void * parent, obj * p_lhs, obj & rhs) = 0; + /** evacuate @p *lhs, that refers to state with interface @p lhs_iface, +to collector @p d's to-space. Replace *lhs_data with forwarding pointer - /** add gc root with address @p p_root **/ - virtual void add_gc_root_poly(Opaque d, obj * p_root) = 0; +Require: gc in progress + **/ + virtual void forward_inplace(Opaque data, AGCObject * lhs_iface, void ** lhs_data) = 0; + ///@} +}; /*ACollector*/ - /** 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 - * 2. may nevertheless escalate to older generations, - * depending on collector state. - * 3. if collection is currently disabled, - * collection will trigger the next time gc is enabled. - **/ - virtual void request_gc(Opaque d, Generation upto) = 0; - - /** Assign pointer @p p_lhs to destination @p rhs, within parent allocation @p parent - * - * Require: gc not in progress - **/ - virtual void assign_member(Opaque d, - void * parent, - obj * p_lhs, - obj & rhs) = 0; - - /** evacuate @p *lhs, that refers to state with interface @p lhs_iface, - * to collector @p d's to-space. Replace *lhs_data with forwarding pointer - * - * Require: gc in progress - **/ - virtual void forward_inplace(Opaque d, AGCObject * lhs_iface, void ** lhs_data) = 0; - }; - } +/** Implementation ICollector_DRepr of ACollector for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = ICollector_DRepr; + * }; + * + * then ICollector_ImplType --> ICollector_DRepr + **/ +template +using ICollector_ImplType = xo::facet::FacetImplType; +} /*namespace mm*/ } /*namespace xo*/ + +/* ACollector.hpp */ diff --git a/include/xo/alloc2/gc/ICollector_Any.hpp b/include/xo/alloc2/gc/ICollector_Any.hpp index ecc8cfc..285467c 100644 --- a/include/xo/alloc2/gc/ICollector_Any.hpp +++ b/include/xo/alloc2/gc/ICollector_Any.hpp @@ -1,59 +1,99 @@ /** @file ICollector_Any.hpp * - * @author Roland Conybeare, Dec 2025 + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Collector.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Collector.json5] **/ #pragma once #include "ACollector.hpp" -#include "AGCObject.hpp" -//#include +#include + +namespace xo { namespace mm { class ICollector_Any; } } namespace xo { - namespace mm { struct ICollector_Any; } +namespace facet { - namespace facet { - template <> - struct FacetImplementation { - using ImplType = xo::mm::ICollector_Any; - }; - } +template <> +struct FacetImplementation +{ + using ImplType = xo::mm::ICollector_Any; +}; - namespace mm { - /** @class ICollector_Any - * @brief Stub Collector Implementation for empty variant instance - **/ - struct ICollector_Any : public ACollector { - using typeseq = xo::facet::typeseq; - using size_type = std::size_t; +} +} - // from ACollector - typeseq _typeseq() const noexcept override { return s_typeseq; } +namespace xo { +namespace mm { - // const methods - [[noreturn]] size_type allocated(Copaque, Generation, role) const noexcept override { _fatal(); } - [[noreturn]] size_type reserved(Copaque, Generation, role) const noexcept override { _fatal(); } - [[noreturn]] size_type committed(Copaque, Generation, role) const noexcept override { _fatal(); } - [[noreturn]] bool contains(Copaque, role, const void *) const noexcept override { _fatal(); } - [[noreturn]] bool is_type_installed(Copaque, typeseq) const noexcept override { _fatal(); } + /** @class ICollector_Any + * @brief ACollector implementation for empty variant instance + **/ + class ICollector_Any : public ACollector { + public: + /** @defgroup mm-collector-any-type-traits **/ + ///@{ - // 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 assign_member(Opaque, void *, - obj *, obj &) override { _fatal(); } - [[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override { _fatal(); } + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using size_type = ACollector::size_type; - private: - [[noreturn]] static void _fatal(); + ///@} + /** @defgroup mm-collector-any-methods **/ + ///@{ - public: - static typeseq s_typeseq; - static bool _valid; - }; - } /*namespace mm*/ -} /*namespace xo*/ + const ACollector * iface() const { return std::launder(this); } -/* end ICollector_Any.hpp */ + // from ACollector + + // builtin methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods + [[noreturn]] size_type allocated(Copaque, Generation, role) const noexcept override { _fatal(); } + [[noreturn]] size_type committed(Copaque, Generation, role) const noexcept override { _fatal(); } + [[noreturn]] size_type reserved(Copaque, Generation, role) const noexcept override { _fatal(); } + [[noreturn]] bool contains(Copaque, role, const void *) const noexcept override { _fatal(); } + [[noreturn]] bool is_type_installed(Copaque, typeseq) const noexcept override { _fatal(); } + + // nonconst methods + [[noreturn]] bool install_type(Opaque, const AGCObject &) override; + [[noreturn]] void add_gc_root_poly(Opaque, obj *) override; + [[noreturn]] void remove_gc_root_poly(Opaque, obj *) override; + [[noreturn]] void request_gc(Opaque, Generation) override; + [[noreturn]] void assign_member(Opaque, void *, obj *, obj &) override; + [[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override; + + ///@} + + private: + /** @defgraoup mm-collector-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup mm-collector-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace mm */ +} /*namespace xo */ + +/* ICollector_Any.hpp */ diff --git a/include/xo/alloc2/gc/ICollector_Xfer.hpp b/include/xo/alloc2/gc/ICollector_Xfer.hpp index dd21804..b1df145 100644 --- a/include/xo/alloc2/gc/ICollector_Xfer.hpp +++ b/include/xo/alloc2/gc/ICollector_Xfer.hpp @@ -1,93 +1,116 @@ /** @file ICollector_Xfer.hpp * - * @author Roland Conybeare, 2025 + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Collector.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Collector.json5] **/ #pragma once -#include "ACollector.hpp" -#include "AGCObject.hpp" +#include +#include +#include namespace xo { - namespace mm { - /** @class ICollector_Xfer - * - * Adapts typed ACollector implementation @tparam ICollector_DRepr - * to type-erased @ref ACollector interface - * - * See for example - * @ref ICollector_DX1Collector - **/ - template - struct ICollector_Xfer : public ACollector { - public: - using Impl = ICollector_DRepr; - using size_type = ACollector::size_type; +namespace mm { + /** @class ICollector_Xfer + **/ + template + class ICollector_Xfer : public ACollector { + public: + /** @defgroup mm-collector-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = ICollector_DRepr; + /** integer identifying a type **/ + using typeseq = ACollector::typeseq; + using size_type = ACollector::size_type; + ///@} - static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } - static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + /** @defgroup mm-collector-xfer-methods **/ + ///@{ - // from ACollector + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } - // const methods + // from ACollector - typeseq _typeseq() const noexcept override { return s_typeseq; } - size_type allocated(Copaque d, Generation g, role r) const noexcept override { - return I::allocated(_dcast(d), g, r); - } - size_type reserved(Copaque d, Generation g, role r) const noexcept override { - return I::reserved(_dcast(d), g, r); - } - size_type committed(Copaque d, Generation g, role r) const noexcept override { - return I::committed(_dcast(d), g, r); - } - bool is_type_installed(Copaque d, typeseq tseq) const noexcept override { - return I::is_type_installed(_dcast(d), tseq); - } - bool contains(Copaque d, role r, const void * addr) const noexcept override { - return I::contains(_dcast(d), r, addr); - } + // builtin methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } - // non-const methods + // const methods + size_type allocated(Copaque data, Generation g, role r) const noexcept override { + return I::allocated(_dcast(data), g, r); + } + size_type committed(Copaque data, Generation g, role r) const noexcept override { + return I::committed(_dcast(data), g, r); + } + size_type reserved(Copaque data, Generation g, role r) const noexcept override { + return I::reserved(_dcast(data), g, r); + } + bool contains(Copaque data, role r, const void * addr) const noexcept override { + return I::contains(_dcast(data), r, addr); + } + bool is_type_installed(Copaque data, typeseq tseq) const noexcept override { + return I::is_type_installed(_dcast(data), tseq); + } - bool install_type(Opaque d, const AGCObject & iface) override { - return I::install_type(_dcast(d), iface); - } - 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); - } - void assign_member(Opaque d, void * parent, - obj * p_lhs, obj & rhs) override { - I::assign_member(_dcast(d), parent, p_lhs, rhs); - } - void forward_inplace(Opaque d, - AGCObject * lhs_iface, void ** lhs_data) override { - I::forward_inplace(_dcast(d), lhs_iface, lhs_data); - } + // non-const methods + bool install_type(Opaque data, const AGCObject & iface) override { + return I::install_type(_dcast(data), iface); + } + void add_gc_root_poly(Opaque data, obj * p_root) override { + return I::add_gc_root_poly(_dcast(data), p_root); + } + void remove_gc_root_poly(Opaque data, obj * p_root) override { + return I::remove_gc_root_poly(_dcast(data), p_root); + } + void request_gc(Opaque data, Generation upto) override { + return I::request_gc(_dcast(data), upto); + } + void assign_member(Opaque data, void * parent, obj * p_lhs, obj & rhs) override { + return I::assign_member(_dcast(data), parent, p_lhs, rhs); + } + void forward_inplace(Opaque data, AGCObject * lhs_iface, void ** lhs_data) override { + return I::forward_inplace(_dcast(data), lhs_iface, lhs_data); + } - private: - using I = Impl; + ///@} - public: - static typeseq s_typeseq; - static bool _valid; - }; + private: + using I = Impl; - template - xo::facet::typeseq - ICollector_Xfer::s_typeseq = facet::typeseq::id(); + public: + /** @defgroup mm-collector-xfer-member-vars **/ + ///@{ - template - bool - ICollector_Xfer::_valid = facet::valid_facet_implementation(); + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; - } /*namespace mm*/ + ///@} + }; + + template + xo::facet::typeseq + ICollector_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + ICollector_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace mm */ } /*namespace xo*/ /* end ICollector_Xfer.hpp */ diff --git a/include/xo/alloc2/gc/RCollector.hpp b/include/xo/alloc2/gc/RCollector.hpp index f63fb4a..345eb1f 100644 --- a/include/xo/alloc2/gc/RCollector.hpp +++ b/include/xo/alloc2/gc/RCollector.hpp @@ -1,90 +1,141 @@ /** @file RCollector.hpp * - * @author Roland Conybeare, Dec 2025 + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Collector.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Collector.json5] **/ +#pragma once + #include "ACollector.hpp" -#include namespace xo { - namespace mm { - /** @class RCollector **/ - template - struct RCollector : public Object { - private: - using O = Object; - public: - using ObjectType = Object; - using DataPtr = Object::DataPtr; - using size_type = std::size_t; - using typeseq = ACollector::typeseq; - //using value_type = std::byte *; +namespace mm { - RCollector() = default; - RCollector(DataPtr data) : Object{std::move(data)} {} - RCollector(const ACollector * iface, void * data) - requires std::is_same_v - : Object(iface, data) {} +/** @class RCollector + **/ +template +class RCollector : public Object { +private: + using O = Object; - /** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/ - template - void forward_inplace(obj * p_obj); +public: + /** @defgroup mm-collector-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + using size_type = ACollector::size_type; + ///@} - /** another convenience template for forwarding. - * Defined in RGCObject.hpp to avoid #include cycle. - **/ - template - void forward_inplace(DRepr ** pp_repr); + /** @defgroup mm-collector-router-ctors **/ + ///@{ + RCollector() {} + RCollector(Object::DataPtr data) : Object{std::move(data)} {} + RCollector(const ACollector * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} - /** convenience template where pointer requires pivot **/ - template - requires (!std::is_same_v) - void forward_pivot_inplace(obj * p_obj); + ///@} + /** @defgroup mm-collector-router-methods **/ + ///@{ - 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); } - size_type committed(Generation g, role r) const noexcept { return O::iface()->committed(O::data(), g, r); } - bool contains(role r, const void * addr) const noexcept { return O::iface()->contains(O::data(), r, addr); } - bool is_type_installed(typeseq tseq) const noexcept { return O::iface()->is_type_installed(O::data(), tseq); } - - 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 assign_member(void * parent, - obj * p_lhs, - obj & rhs) { O::iface()->assign_member(O::data(), parent, p_lhs, rhs); } - - void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data); } - - /** add root @p p_root **/ - template - void add_gc_root(obj * p_root) { - 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; - }; - - template - bool - RCollector::_valid = facet::valid_object_router(); - } /*namespace mm*/ - - namespace facet { - template - struct RoutingFor { - using RoutingType = xo::mm::RCollector; - }; + // explicit injected content + /** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/ + template + void forward_inplace(obj * p_obj); + + /** another convenience template for forwarding. + * Defined in RGCObject.hpp to avoid #include cycle. + **/ + 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); + + /** add root @p p_root **/ + template + void add_gc_root(obj * p_root) { + 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); + } + + // builtin methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods + size_type allocated(Generation g, role r) const noexcept { + return O::iface()->allocated(O::data(), g, r); + } + size_type committed(Generation g, role r) const noexcept { + return O::iface()->committed(O::data(), g, r); + } + size_type reserved(Generation g, role r) const noexcept { + return O::iface()->reserved(O::data(), g, r); + } + bool contains(role r, const void * addr) const noexcept { + return O::iface()->contains(O::data(), r, addr); + } + bool is_type_installed(typeseq tseq) const noexcept { + return O::iface()->is_type_installed(O::data(), tseq); + } + + // non-const methods (still const in router!) + bool install_type(const AGCObject & iface) { + return O::iface()->install_type(O::data(), iface); + } + void add_gc_root_poly(obj * p_root) { + return O::iface()->add_gc_root_poly(O::data(), p_root); + } + void remove_gc_root_poly(obj * p_root) { + return O::iface()->remove_gc_root_poly(O::data(), p_root); + } + void request_gc(Generation upto) { + return O::iface()->request_gc(O::data(), upto); + } + void assign_member(void * parent, obj * p_lhs, obj & rhs) { + return O::iface()->assign_member(O::data(), parent, p_lhs, rhs); + } + void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { + return O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data); + } + + ///@} + /** @defgroup mm-collector-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RCollector::_valid = xo::facet::valid_object_router(); + +} /*namespace mm*/ } /*namespace xo*/ +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::mm::RCollector; + }; +} } + /* end RCollector.hpp */ diff --git a/src/alloc2/CMakeLists.txt b/src/alloc2/CMakeLists.txt index ac73207..8399d1b 100644 --- a/src/alloc2/CMakeLists.txt +++ b/src/alloc2/CMakeLists.txt @@ -8,9 +8,7 @@ set(SELF_SRCS CollectorTypeRegistry.cpp - facet/ICollector2_Any.cpp - - ICollector_Any.cpp + facet/ICollector_Any.cpp IGCObject_Any.cpp AAllocator.cpp diff --git a/src/alloc2/ICollector_Any.cpp b/src/alloc2/ICollector_Any.cpp deleted file mode 100644 index b39aa99..0000000 --- a/src/alloc2/ICollector_Any.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/** @file ICollector_Any.cpp - * - * @author Roland Conybeare, Dec 2025 - **/ - -#include "gc/ICollector_Any.hpp" -#include -#include - -namespace xo { - using xo::facet::DVariantPlaceholder; - using xo::facet::typeseq; - using xo::facet::valid_facet_implementation; - - namespace mm { - - void - ICollector_Any::_fatal() { - /* control here on uninitialized ICollector_Any. - * Initialized instance will have specific implementation type - * e.g. ICollector_Xfer - */ - - std::cerr << "fatal" - << ": attempt to call uninitialized" - << " ICollector_Any method" - << std::endl; - std::terminate(); - } - - typeseq - ICollector_Any::s_typeseq = typeseq::id(); - - bool - ICollector_Any::_valid = valid_facet_implementation(); - - } /*namespace mm*/ -} /*namespace xo*/ - -/** end ICollector_Any.cpp */ diff --git a/src/alloc2/facet/ICollector2_Any.cpp b/src/alloc2/facet/ICollector2_Any.cpp deleted file mode 100644 index fc08a51..0000000 --- a/src/alloc2/facet/ICollector2_Any.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/** @file ICollector2_Any.cpp - * - **/ - -#include "gc/ICollector2_Any.hpp" -#include -#include - -namespace xo { -namespace mm { - -using xo::facet::DVariantPlaceholder; -using xo::facet::typeseq; -using xo::facet::valid_facet_implementation; - -void -ICollector2_Any::_fatal() -{ - /* control here on uninitialized IAllocator_Any. - * Initialized instance will have specific implementation type - */ - std::cerr << "fatal" - << ": attempt to call uninitialized" - << " ICollector2_Any method" - << std::endl; - std::terminate(); -} - -typeseq -ICollector2_Any::s_typeseq = typeseq::id(); - -bool -ICollector2_Any::_valid - = valid_facet_implementation(); - -// nonconst methods - -auto -ICollector2_Any::install_type(Opaque, const AGCObject &) -> bool -{ - _fatal(); -} - -auto -ICollector2_Any::add_gc_root_poly(Opaque, obj *) -> void -{ - _fatal(); -} - -auto -ICollector2_Any::remove_gc_root_poly(Opaque, obj *) -> void -{ - _fatal(); -} - -auto -ICollector2_Any::request_gc(Opaque, Generation) -> void -{ - _fatal(); -} - -auto -ICollector2_Any::assign_member(Opaque, void *, obj *, obj &) -> void -{ - _fatal(); -} - -auto -ICollector2_Any::forward_inplace(Opaque, AGCObject *, void **) -> void -{ - _fatal(); -} - - -} /*namespace mm*/ -} /*namespace xo*/ - -/* end ICollector2_Any.cpp */ diff --git a/src/alloc2/facet/ICollector_Any.cpp b/src/alloc2/facet/ICollector_Any.cpp new file mode 100644 index 0000000..aa24409 --- /dev/null +++ b/src/alloc2/facet/ICollector_Any.cpp @@ -0,0 +1,78 @@ +/** @file ICollector_Any.cpp + * + **/ + +#include "gc/ICollector_Any.hpp" +#include +#include + +namespace xo { +namespace mm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +ICollector_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " ICollector_Any method" + << std::endl; + std::terminate(); +} + +typeseq +ICollector_Any::s_typeseq = typeseq::id(); + +bool +ICollector_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + +auto +ICollector_Any::install_type(Opaque, const AGCObject &) -> bool +{ + _fatal(); +} + +auto +ICollector_Any::add_gc_root_poly(Opaque, obj *) -> void +{ + _fatal(); +} + +auto +ICollector_Any::remove_gc_root_poly(Opaque, obj *) -> void +{ + _fatal(); +} + +auto +ICollector_Any::request_gc(Opaque, Generation) -> void +{ + _fatal(); +} + +auto +ICollector_Any::assign_member(Opaque, void *, obj *, obj &) -> void +{ + _fatal(); +} + +auto +ICollector_Any::forward_inplace(Opaque, AGCObject *, void **) -> void +{ + _fatal(); +} + + +} /*namespace mm*/ +} /*namespace xo*/ + +/* end ICollector_Any.cpp */