From 6e6305c72fdb98262dabd725e5e3984a2d4bb4ac Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 14 Dec 2025 13:52:29 -0500 Subject: [PATCH] xo-alloc2 xo-object: bugfix + refactor -> IGCObject_DList builds --- include/xo/alloc2/ACollector.hpp | 19 +++++++++-- include/xo/alloc2/AGCObject.hpp | 2 +- include/xo/alloc2/IAllocator_Any.hpp | 2 ++ include/xo/alloc2/ICollector_Any.hpp | 51 ++++++++++++++++++++++++++++ include/xo/alloc2/RAllocator.hpp | 29 ++++++++-------- include/xo/alloc2/RCollector.hpp | 51 ++++++++++++++++++++++++++++ include/xo/alloc2/RCollector_Any.hpp | 51 ++++++++++++++++++++++++++++ include/xo/alloc2/RGCObject.hpp | 47 +++++++++++++++++++++++++ include/xo/alloc2/gc/generation.hpp | 2 ++ src/alloc2/CMakeLists.txt | 2 ++ src/alloc2/ICollector_Any.cpp | 39 +++++++++++++++++++++ 11 files changed, 278 insertions(+), 17 deletions(-) create mode 100644 include/xo/alloc2/ICollector_Any.hpp create mode 100644 include/xo/alloc2/RCollector.hpp create mode 100644 include/xo/alloc2/RCollector_Any.hpp create mode 100644 include/xo/alloc2/RGCObject.hpp create mode 100644 src/alloc2/ICollector_Any.cpp diff --git a/include/xo/alloc2/ACollector.hpp b/include/xo/alloc2/ACollector.hpp index 1b4cf4c..c88a340 100644 --- a/include/xo/alloc2/ACollector.hpp +++ b/include/xo/alloc2/ACollector.hpp @@ -3,6 +3,14 @@ * @author Roland Conybeare, Dec 2025 **/ +#pragma once + +#include "IGCObject_Any.hpp" + +#include +#include +#include + #include "gc/generation.hpp" #include "gc/role.hpp" @@ -14,6 +22,8 @@ namespace xo { using Copaque = const void *; using Opaque = void *; + struct IGCObject_Any; // see IGCObject_Any.hpp + /** @class ACollector * @brief Abstract facet for the XO garbage collector * @@ -37,8 +47,13 @@ namespace xo { * in which case calls through @c std::launder(&iface) * will properly act on @c DFoo. **/ - virtual void install_type(Opaque d, int32_t tseq, AGCObject_Any & iface); - virtual void add_gc_root(Opaque d, int32_t tid, Opaque * root) = 0; + virtual void install_type(Opaque d, int32_t tseq, IGCObject_Any & iface); + virtual void add_gc_root(Opaque d, int32_t tseq, Opaque * root) = 0; + + /** evacuate @p *lhs to to-space and replace with forwarding pointer + * Require: gc in progress + **/ + virtual void forward_inplace(Opaque d, obj * lhs) = 0; }; } diff --git a/include/xo/alloc2/AGCObject.hpp b/include/xo/alloc2/AGCObject.hpp index fc9c016..c558624 100644 --- a/include/xo/alloc2/AGCObject.hpp +++ b/include/xo/alloc2/AGCObject.hpp @@ -9,7 +9,7 @@ #include "RAllocator.hpp" #include "xo/facet/facet_implementation.hpp" #include "xo/facet/typeseq.hpp" -#include "xo/facet/obj.hpp" +#include "xo/facet/obj.hpp" // for obj in shallow_copy #include #include diff --git a/include/xo/alloc2/IAllocator_Any.hpp b/include/xo/alloc2/IAllocator_Any.hpp index c58a19d..24414fb 100644 --- a/include/xo/alloc2/IAllocator_Any.hpp +++ b/include/xo/alloc2/IAllocator_Any.hpp @@ -31,6 +31,7 @@ namespace xo { // from AAllocator int32_t _typeseq() const noexcept override { return s_typeseq; } + // const methods [[noreturn]] std::string_view name(Copaque) const noexcept override { _fatal(); } [[noreturn]] size_type reserved(Copaque) const noexcept override { _fatal(); } [[noreturn]] size_type size(Copaque) const noexcept override { _fatal(); } @@ -40,6 +41,7 @@ namespace xo { [[noreturn]] bool contains(Copaque, const void *) const noexcept override { _fatal(); } [[noreturn]] AllocatorError last_error(Copaque) const noexcept override { _fatal(); } + // non-const methods [[noreturn]] bool expand(Opaque, std::size_t) const noexcept override { _fatal(); } [[noreturn]] value_type alloc(Opaque, std::size_t) const override { _fatal(); } [[noreturn]] value_type super_alloc(Opaque, std::size_t) const override { _fatal(); } diff --git a/include/xo/alloc2/ICollector_Any.hpp b/include/xo/alloc2/ICollector_Any.hpp new file mode 100644 index 0000000..9e5d998 --- /dev/null +++ b/include/xo/alloc2/ICollector_Any.hpp @@ -0,0 +1,51 @@ +/** @file ICollector_Any.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include "ACollector.hpp" +//#include + +namespace xo { + namespace mm { struct ICollector_Any; } + + namespace facet { + 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 size_type = std::size_t; + + // from ACollector + int32_t _typeseq() const noexcept override { return s_typeseq; } + + // const methods + [[noreturn]] size_type allocated(Copaque, generation, role) const noexcept { _fatal(); } + [[noreturn]] size_type reserved(Copaque, generation, role) const noexcept { _fatal(); } + [[noreturn]] size_type committed(Copaque, generation, role) const noexcept { _fatal(); } + + // non-const methods + [[noreturn]] void install_type(Opaque, int32_t, IGCObject_Any &) noexcept { _fatal(); } + [[noreturn]] void add_gc_root(Opaque, int32_t, Opaque *) { _fatal(); } + [[noreturn]] void forward_inplace(Opaque, obj *) { _fatal(); } + + private: + [[noreturn]] static void _fatal(); + + public: + static int32_t s_typeseq; + static bool _valid; + }; + } /*namespace mm*/ +} /*namespace xo*/ + +/* end ICollector_Any.hpp */ diff --git a/include/xo/alloc2/RAllocator.hpp b/include/xo/alloc2/RAllocator.hpp index 012c7c2..6d0b4a5 100644 --- a/include/xo/alloc2/RAllocator.hpp +++ b/include/xo/alloc2/RAllocator.hpp @@ -6,7 +6,7 @@ #pragma once #include "AAllocator.hpp" -#include "xo/facet/RRouter.hpp" +#include #include namespace xo { @@ -18,28 +18,29 @@ namespace xo { using O = Object; public: using ObjectType = Object; + using DataPtr = Object::DataPtr; using size_type = std::size_t; using value_type = std::byte *; RAllocator() {} RAllocator(Object::DataPtr data) : Object{std::move(data)} {} - int32_t _typeseq() const { return O::iface()->_typeseq(); } - std::string_view name() const { return O::iface()->name(O::data()); } - size_type reserved() const { return O::iface()->reserved(O::data()); } - size_type size() const { return O::iface()->size(O::data()); } - size_type committed() const { return O::iface()->committed(O::data()); } - size_type available() const { return O::iface()->available(O::data()); } - size_type allocated() const { return O::iface()->allocated(O::data()); } - bool contains(const void * p) const { return O::iface()->contains(O::data(), p); } - AllocatorError last_error() const { return O::iface()->last_error(O::data()); } + int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + std::string_view name() const noexcept { return O::iface()->name(O::data()); } + size_type reserved() const noexcept { return O::iface()->reserved(O::data()); } + size_type size() const noexcept { return O::iface()->size(O::data()); } + size_type committed() const noexcept { return O::iface()->committed(O::data()); } + size_type available() const noexcept { return O::iface()->available(O::data()); } + size_type allocated() const noexcept { return O::iface()->allocated(O::data()); } + bool contains(const void * p) const noexcept { return O::iface()->contains(O::data(), p); } + AllocatorError last_error() const noexcept { return O::iface()->last_error(O::data()); } bool expand(size_type z) { return O::iface()->expand(O::data(), z); } - value_type alloc(size_type z) { return O::iface()->alloc(O::data(), z); } - value_type super_alloc(size_type z) { return O::iface()->super_alloc(O::data(), z); } + value_type alloc(size_type z) noexcept { return O::iface()->alloc(O::data(), z); } + value_type super_alloc(size_type z) noexcept { return O::iface()->super_alloc(O::data(), z); } value_type sub_alloc(size_type z, - bool complete_flag) { return O::iface()->sub_alloc(O::data(), - z, complete_flag); } + bool complete_flag) noexcept { return O::iface()->sub_alloc(O::data(), + z, complete_flag); } static bool _valid; }; diff --git a/include/xo/alloc2/RCollector.hpp b/include/xo/alloc2/RCollector.hpp new file mode 100644 index 0000000..5da5b30 --- /dev/null +++ b/include/xo/alloc2/RCollector.hpp @@ -0,0 +1,51 @@ +/** @file RCollector.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#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 value_type = std::byte *; + + RCollector() = default; + RCollector(DataPtr data) : Object{std::move(data)} {} + + int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + size_type allocated(generation g, role r) const noexcept { return O::iface()->allocated(O::data()); } + size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data()); } + size_type committed(generation g, role r) const noexcept { return O::iface()->committed(O::data()); } + + void install_type(int32_t tseq, IGCObject_Any & iface) { return O::iface()->install_type(O::data()); } + void add_gc_root(int32_t tseq, Opaque * root) { O::iface()->add_gc_root(O::data()); } + + void forward_inplace(obj * lhs) { O::iface()->forward_inplace(O::data(), lhs); } + + static bool _valid; + }; + + template + bool + RCollector::_valid = facet::valid_object_router(); + } /*namespace mm*/ + + namespace facet { + template + struct RoutingFor { + using RoutingType = xo::mm::RCollector; + }; + } +} /*namespace xo*/ + +/* end RCollector.hpp */ diff --git a/include/xo/alloc2/RCollector_Any.hpp b/include/xo/alloc2/RCollector_Any.hpp new file mode 100644 index 0000000..5799aa6 --- /dev/null +++ b/include/xo/alloc2/RCollector_Any.hpp @@ -0,0 +1,51 @@ +/** @file RCollector_Any.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include "ACollector.hpp" +//#include + +namespace xo { + namespace mm { struct ICollector_Any; } + + namespace facet { + 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 size_type = std::size_t; + + // from ACollector + int32_t _typeseq() const noexcept override { return s_typeseq; } + + // const methods + [[noreturn]] size_type allocated(Copaque, generation, role) const noexcept { _fatal(); } + [[noreturn]] size_type reserved(Copaque, generation, role) const noexcept { _fatal(); } + [[noreturn]] size_type committed(Copaque, generation, role) const noexcept { _fatal(); } + + // non-const methods + [[noreturn]] void install_type(Opaque, int32_t, IGCObject_Any &) noexcept { _fatal(); } + [[noreturn]] void add_gc_root(Opaque, int32_t, Opaque *) { _fatal(); } + [[noreturn]] void forward_inplace(Opaque, Opaque **) { _fatail(); } + + private: + [[noreturn]] static void _fatal(); + + public: + static int32_t s_typeseq; + static bool _valid; + }; + } /*namespace mm*/ +} /*namespace xo*/ + +/* end RCollector_Any.hpp */ diff --git a/include/xo/alloc2/RGCObject.hpp b/include/xo/alloc2/RGCObject.hpp new file mode 100644 index 0000000..054b995 --- /dev/null +++ b/include/xo/alloc2/RGCObject.hpp @@ -0,0 +1,47 @@ +/** @file RGCObject.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include "AGCObject.hpp" +#include + +namespace xo { + namespace mm { + /** @class RGCObject **/ + template + struct RGCObject : public Object { + private: + using O = Object; + public: + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using size_type = std::size_t; + + RGCObject() = default; + RGCObject(Object::DataPtr data) : Object{std::move(data)} {} + + int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + size_type shallow_size() const noexcept { O::iface()->shallow_size(O::data()); } + Opaque * shallow_copy(obj mm) const noexcept { O::iface()->shallow_copy(O::data(), mm); } + size_type forward_children() noexcept { O::iface()->forward_children(O::data()); } + + static bool _valid; + }; + + template + bool + RGCObject::_valid = facet::valid_object_router(); + } /*namespace mm*/ + + namespace facet { + template + struct RoutingFor { + using RoutingType = xo::mm::RGCObject; + }; + } +} /*namespace xo*/ + +/* end RGCObject.hpp */ diff --git a/include/xo/alloc2/gc/generation.hpp b/include/xo/alloc2/gc/generation.hpp index e7a39ee..96a69a2 100644 --- a/include/xo/alloc2/gc/generation.hpp +++ b/include/xo/alloc2/gc/generation.hpp @@ -3,6 +3,8 @@ * @author Roland Conybeare, Dec 2025 **/ +#pragma once + #include #include diff --git a/src/alloc2/CMakeLists.txt b/src/alloc2/CMakeLists.txt index 77d2976..28f8c20 100644 --- a/src/alloc2/CMakeLists.txt +++ b/src/alloc2/CMakeLists.txt @@ -8,6 +8,8 @@ set(SELF_SRCS IAllocator_Any.cpp IAllocator_DArena.cpp + ICollector_Any.cpp + IGCObject_Any.cpp ) diff --git a/src/alloc2/ICollector_Any.cpp b/src/alloc2/ICollector_Any.cpp new file mode 100644 index 0000000..8f0069b --- /dev/null +++ b/src/alloc2/ICollector_Any.cpp @@ -0,0 +1,39 @@ +/** @file ICollector_Any.cpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#include "ICollector_Any.hpp" +#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(); + } + + int32_t + ICollector_Any::s_typeseq = typeseq::id(); + + bool + ICollector_Any::_valid = valid_facet_implementation(); + + } /*namespace mm*/ +} /*namespace xo*/ + +/** end ICollector_Any.cpp */