From 57688a826ae8e70c2cfb7c87c945d6f6b44431d6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 5 Apr 2026 18:07:14 -0400 Subject: [PATCH] xo-gc stack: refactor: introduce GCObjectVisitor facet Plan using to properly level GCObjectStore and MutationLogStore below Collector. [WIP] not used yet --- xo-alloc2/CMakeLists.txt | 9 ++ xo-alloc2/idl/GCObjectVisitor.json5 | 75 ++++++++++++++++ .../include/xo/alloc2/GCObjectVisitor.hpp | 22 +++++ .../include/xo/alloc2/gc/AGCObjectVisitor.hpp | 79 +++++++++++++++++ .../xo/alloc2/gc/IGCObjectVisitor_Any.hpp | 88 +++++++++++++++++++ .../xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp | 82 +++++++++++++++++ .../include/xo/alloc2/gc/RGCObjectVisitor.hpp | 84 ++++++++++++++++++ xo-alloc2/src/alloc2/CMakeLists.txt | 2 + .../src/alloc2/facet/IGCObjectVisitor_Any.cpp | 48 ++++++++++ xo-gc/CMakeLists.txt | 7 ++ xo-gc/idl/IGCObjectVisitor_DX1Collector.json5 | 27 ++++++ xo-gc/include/xo/gc/DX1Collector.hpp | 10 +-- .../detail/IGCObjectVisitor_DX1Collector.hpp | 58 ++++++++++++ xo-gc/src/gc/CMakeLists.txt | 1 + xo-gc/src/gc/DX1Collector.cpp | 20 +++++ .../facet/IGCObjectVisitor_DX1Collector.cpp | 27 ++++++ 16 files changed, 632 insertions(+), 7 deletions(-) create mode 100644 xo-alloc2/idl/GCObjectVisitor.json5 create mode 100644 xo-alloc2/include/xo/alloc2/GCObjectVisitor.hpp create mode 100644 xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp create mode 100644 xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp create mode 100644 xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp create mode 100644 xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp create mode 100644 xo-alloc2/src/alloc2/facet/IGCObjectVisitor_Any.cpp create mode 100644 xo-gc/idl/IGCObjectVisitor_DX1Collector.json5 create mode 100644 xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp create mode 100644 xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp diff --git a/xo-alloc2/CMakeLists.txt b/xo-alloc2/CMakeLists.txt index 0b2b0267..9c102706 100644 --- a/xo-alloc2/CMakeLists.txt +++ b/xo-alloc2/CMakeLists.txt @@ -35,6 +35,15 @@ xo_add_genfacet( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacet( + TARGET xo-alloc2-facet-gcobjectvisitor + FACET GCObjectVisitor + INPUT idl/GCObjectVisitor.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacet( TARGET xo-alloc2-facet-resourcevisitor diff --git a/xo-alloc2/idl/GCObjectVisitor.json5 b/xo-alloc2/idl/GCObjectVisitor.json5 new file mode 100644 index 00000000..b4658428 --- /dev/null +++ b/xo-alloc2/idl/GCObjectVisitor.json5 @@ -0,0 +1,75 @@ +{ + mode: "facet", + output_cpp_dir: "src/alloc2/facet", + output_hpp_dir: "include/xo/alloc2", + output_impl_subdir: "gc", + includes: [ +// "", +// "", +// "", +// "", + ], + // extra includes in GCObject.hpp, if any + user_hpp_includes: [ +// "\"gc/RCollector_aux.hpp\"", + ], + namespace1: "xo", + namespace2: "mm", + pretext: [ + "// see GCObject.hpp, also in xo-alloc2/", + "namespace xo { namespace mm { class AGCObject; }}", + ], + facet: "GCObjectVisitor", + detail_subdir: "gc", + brief: "gc-aware object visitor", + using_doxygen: true, + doc: [ + "Visit a gc-aware object. Visitor can traverse and update child pointers in-place." + ], + types: [ + // using size_type = std::size_t +// { +// name: "size_type", +// doc: ["type for an amount of memory"], +// definition: "std::size_t", +// }, +// { +// name: "AAllocator", +// doc: ["fomo allocator type"], +// definition: "xo::mm::AAllocator", +// }, +// { +// name: "ACollector", +// doc: ["fomo collector type"], +// definition: "xo::mm::ACollector", +// }, + ], + const_methods: [ + // size_type shallow_size() const noexcept +// { +// name: "shallow_size", +// doc: ["memory consumption for this instance"], +// return_type: "size_type", +// args: [], +// const: true, +// noexcept: true, +// attributes: [], +// }, + ], + nonconst_methods: [ + // void visit_child(AGCObject * iface, void ** pp_data) noexcept; + { + name: "visit_child", + doc: ["visit child of a gc-aware object. May update child in-place!"], + return_type: "void", + args:[ + {type: "AGCObject *", name: "iface"}, + {type: "void **", name: "pp_data"}, + ], + const: true, // technical const. I/face not modified + noexcept: true, + attributes: [], + }, + ], + router_facet_explicit_content: [] +} diff --git a/xo-alloc2/include/xo/alloc2/GCObjectVisitor.hpp b/xo-alloc2/include/xo/alloc2/GCObjectVisitor.hpp new file mode 100644 index 00000000..7805cc93 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/GCObjectVisitor.hpp @@ -0,0 +1,22 @@ +/** @file GCObjectVisitor.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObjectVisitor.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/GCObjectVisitor.json5] + **/ + +#pragma once + +#include "gc/AGCObjectVisitor.hpp" +#include "gc/IGCObjectVisitor_Any.hpp" +#include "gc/IGCObjectVisitor_Xfer.hpp" +#include "gc/RGCObjectVisitor.hpp" + + +/* end GCObjectVisitor.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp b/xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp new file mode 100644 index 00000000..b533076d --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp @@ -0,0 +1,79 @@ +/** @file AGCObjectVisitor.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObjectVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/GCObjectVisitor.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include +#include +#include + +// see GCObject.hpp, also in xo-alloc2/ +namespace xo { namespace mm { class AGCObject; }} + +namespace xo { +namespace mm { + +using Copaque = const void *; +using Opaque = void *; + +/** +Visit a gc-aware object. Visitor can traverse and update child pointers in-place. +**/ +class AGCObjectVisitor { +public: + /** @defgroup mm-gcobjectvisitor-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + ///@} + + /** @defgroup mm-gcobjectvisitor-methods **/ + ///@{ + // const methods + /** An uninitialized AGCObjectVisitor 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; + + // nonconst methods + /** visit child of a gc-aware object. May update child in-place! **/ + virtual void visit_child(Opaque data, AGCObject * iface, void ** pp_data) const noexcept = 0; + ///@} +}; /*AGCObjectVisitor*/ + +/** Implementation IGCObjectVisitor_DRepr of AGCObjectVisitor for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = IGCObjectVisitor_DRepr; + * }; + * + * then IGCObjectVisitor_ImplType --> IGCObjectVisitor_DRepr + **/ +template +using IGCObjectVisitor_ImplType = xo::facet::FacetImplType; + +} /*namespace mm*/ +} /*namespace xo*/ + +/* AGCObjectVisitor.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp new file mode 100644 index 00000000..287252cc --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp @@ -0,0 +1,88 @@ +/** @file IGCObjectVisitor_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObjectVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/GCObjectVisitor.json5] + **/ + +#pragma once + +#include "AGCObjectVisitor.hpp" +#include + +namespace xo { namespace mm { class IGCObjectVisitor_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::mm::IGCObjectVisitor_Any; +}; + +} +} + +namespace xo { +namespace mm { + + /** @class IGCObjectVisitor_Any + * @brief AGCObjectVisitor implementation for empty variant instance + **/ + class IGCObjectVisitor_Any : public AGCObjectVisitor { + public: + /** @defgroup mm-gcobjectvisitor-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + + ///@} + /** @defgroup mm-gcobjectvisitor-any-methods **/ + ///@{ + + const AGCObjectVisitor * iface() const { return std::launder(this); } + + // from AGCObjectVisitor + + // builtin methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods + + // nonconst methods + [[noreturn]] void visit_child(Opaque, AGCObject *, void **) const noexcept override; + + ///@} + + private: + /** @defgraoup mm-gcobjectvisitor-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup mm-gcobjectvisitor-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace mm */ +} /*namespace xo */ + +/* IGCObjectVisitor_Any.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp new file mode 100644 index 00000000..aa9b476b --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp @@ -0,0 +1,82 @@ +/** @file IGCObjectVisitor_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObjectVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/GCObjectVisitor.json5] + **/ + +#pragma once + + +namespace xo { +namespace mm { + /** @class IGCObjectVisitor_Xfer + **/ + template + class IGCObjectVisitor_Xfer : public AGCObjectVisitor { + public: + /** @defgroup mm-gcobjectvisitor-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = IGCObjectVisitor_DRepr; + /** integer identifying a type **/ + using typeseq = AGCObjectVisitor::typeseq; + ///@} + + /** @defgroup mm-gcobjectvisitor-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from AGCObjectVisitor + + // builtin methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods + + // non-const methods + void visit_child(Opaque data, AGCObject * iface, void ** pp_data) const noexcept override { + return I::visit_child(_dcast(data), iface, pp_data); + } + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup mm-gcobjectvisitor-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + IGCObjectVisitor_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + IGCObjectVisitor_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace mm */ +} /*namespace xo*/ + +/* end IGCObjectVisitor_Xfer.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp b/xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp new file mode 100644 index 00000000..800d197f --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp @@ -0,0 +1,84 @@ +/** @file RGCObjectVisitor.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObjectVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/GCObjectVisitor.json5] + **/ + +#pragma once + +#include "AGCObjectVisitor.hpp" + +namespace xo { +namespace mm { + +/** @class RGCObjectVisitor + **/ +template +class RGCObjectVisitor : public Object { +private: + using O = Object; + +public: + /** @defgroup mm-gcobjectvisitor-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + ///@} + + /** @defgroup mm-gcobjectvisitor-router-ctors **/ + ///@{ + RGCObjectVisitor() {} + RGCObjectVisitor(Object::DataPtr data) : Object{std::move(data)} {} + RGCObjectVisitor(const AGCObjectVisitor * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup mm-gcobjectvisitor-router-methods **/ + ///@{ + + // explicit injected content + + // builtin methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods + + // non-const methods (still const in router!) + void visit_child(AGCObject * iface, void ** pp_data) noexcept { + return O::iface()->visit_child(O::data(), iface, pp_data); + } + + ///@} + /** @defgroup mm-gcobjectvisitor-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RGCObjectVisitor::_valid = xo::facet::valid_object_router(); + +} /*namespace mm*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::mm::RGCObjectVisitor; + }; +} } + +/* end RGCObjectVisitor.hpp */ diff --git a/xo-alloc2/src/alloc2/CMakeLists.txt b/xo-alloc2/src/alloc2/CMakeLists.txt index 8399d1bb..7929371a 100644 --- a/xo-alloc2/src/alloc2/CMakeLists.txt +++ b/xo-alloc2/src/alloc2/CMakeLists.txt @@ -9,7 +9,9 @@ set(SELF_SRCS CollectorTypeRegistry.cpp facet/ICollector_Any.cpp + IGCObject_Any.cpp + facet/IGCObjectVisitor_Any.cpp AAllocator.cpp IAllocator_Any.cpp diff --git a/xo-alloc2/src/alloc2/facet/IGCObjectVisitor_Any.cpp b/xo-alloc2/src/alloc2/facet/IGCObjectVisitor_Any.cpp new file mode 100644 index 00000000..53d13ca5 --- /dev/null +++ b/xo-alloc2/src/alloc2/facet/IGCObjectVisitor_Any.cpp @@ -0,0 +1,48 @@ +/** @file IGCObjectVisitor_Any.cpp + * + **/ + +#include "gc/IGCObjectVisitor_Any.hpp" +#include +#include + +namespace xo { +namespace mm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +IGCObjectVisitor_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " IGCObjectVisitor_Any method" + << std::endl; + std::terminate(); +} + +typeseq +IGCObjectVisitor_Any::s_typeseq = typeseq::id(); + +bool +IGCObjectVisitor_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + +auto +IGCObjectVisitor_Any::visit_child(Opaque, AGCObject *, void **) const noexcept -> void +{ + _fatal(); +} + + +} /*namespace mm*/ +} /*namespace xo*/ + +/* end IGCObjectVisitor_Any.cpp */ diff --git a/xo-gc/CMakeLists.txt b/xo-gc/CMakeLists.txt index bacf4f14..aa0df8ef 100644 --- a/xo-gc/CMakeLists.txt +++ b/xo-gc/CMakeLists.txt @@ -25,6 +25,13 @@ xo_add_genfacetimpl( INPUT idl/ICollector_DX1Collector.json5 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-gc-facetimpl-gcobjectvisitor-x1collector + FACET_PKG xo_alloc2 + INPUT idl/IGCObjectVisitor_DX1Collector.json5 +) + # ---------------------------------------------------------------- xo_add_genfacet_all(xo-gc-genfacet-all) diff --git a/xo-gc/idl/IGCObjectVisitor_DX1Collector.json5 b/xo-gc/idl/IGCObjectVisitor_DX1Collector.json5 new file mode 100644 index 00000000..438aad0a --- /dev/null +++ b/xo-gc/idl/IGCObjectVisitor_DX1Collector.json5 @@ -0,0 +1,27 @@ +{ + mode: "implementation", + output_cpp_dir: "src/gc/facet", + output_hpp_dir: "include/xo/gc", + output_impl_subdir: "detail", + includes: [ +// "", +// "" + ], + local_types: [ +// { +// name: "typeseq", +// doc: ["identifies a c++ type"], +// definition: "xo::reflect::typeseq" +// }, + ], + namespace1: "xo", + namespace2: "mm", + facet_idl: "idl/GCObjectVisitor.json5", + brief: "provide AGCObjectVisitor interface for DX1Collector", + using_doxygen: true, + repr: "DX1Collector", + doc: [ + "Implement AGCObjectVisitor for DX1Collector.", + "Evacuate object pointer (migrate to to-space) during collection phase" + ], +} diff --git a/xo-gc/include/xo/gc/DX1Collector.hpp b/xo-gc/include/xo/gc/DX1Collector.hpp index 5fe82353..6139dbb2 100644 --- a/xo-gc/include/xo/gc/DX1Collector.hpp +++ b/xo-gc/include/xo/gc/DX1Collector.hpp @@ -279,14 +279,10 @@ namespace xo { **/ void forward_inplace(AGCObject * lhs_iface, void ** lhs_data); -#ifdef OBSOLETE - /** true iff {alloc_hdr, object_data} should move for - * currently-running collection. - * - * Require: runstate_.is_running() + /** Supports the GCObjectVisitor facet. + * Synonym for forward_inplace **/ - bool check_move_policy(header_type alloc_hdr, void * object_data) const noexcept; -#endif + void visit_child(AGCObject * lhs_iface, void ** lhs_data); // ----- allocation ----- diff --git a/xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp b/xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp new file mode 100644 index 00000000..c2696a78 --- /dev/null +++ b/xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp @@ -0,0 +1,58 @@ +/** @file IGCObjectVisitor_DX1Collector.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObjectVisitor_DX1Collector.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObjectVisitor_DX1Collector.json5] + **/ + +#pragma once + +#include "GCObjectVisitor.hpp" +#include "DX1Collector.hpp" + +namespace xo { namespace mm { class IGCObjectVisitor_DX1Collector; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObjectVisitor_Xfer + ; + }; + } +} + +namespace xo { + namespace mm { + /** @class IGCObjectVisitor_DX1Collector + **/ + class IGCObjectVisitor_DX1Collector { + public: + /** @defgroup mm-gcobjectvisitor-dx1collector-type-traits **/ + ///@{ + using Copaque = xo::mm::AGCObjectVisitor::Copaque; + using Opaque = xo::mm::AGCObjectVisitor::Opaque; + ///@} + /** @defgroup mm-gcobjectvisitor-dx1collector-methods **/ + ///@{ + // const methods + + // non-const methods + /** visit child of a gc-aware object. May update child in-place! **/ + static void visit_child(DX1Collector & self, AGCObject * iface, void ** pp_data) noexcept; + ///@} + }; + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-gc/src/gc/CMakeLists.txt b/xo-gc/src/gc/CMakeLists.txt index 9539bcdc..7cbce173 100644 --- a/xo-gc/src/gc/CMakeLists.txt +++ b/xo-gc/src/gc/CMakeLists.txt @@ -12,6 +12,7 @@ set(SELF_SRCS X1CollectorConfig.cpp DX1Collector.cpp facet/ICollector_DX1Collector.cpp + facet/IGCObjectVisitor_DX1Collector.cpp DX1CollectorIterator.cpp diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index b589bcd1..d31c78ca 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -587,6 +587,10 @@ namespace xo { DX1Collector::forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { + // TODO: streamline once GCObject refactored so that + // forward_children takes GCObjectVisitor instead of Collector + // argument. + Generation upto = runstate_.gc_upto(); if (runstate_.is_running()) { @@ -601,6 +605,22 @@ namespace xo { } } + void + DX1Collector::visit_child(AGCObject * lhs_iface, + void ** lhs_data) + { + if (runstate_.is_running()) { + // called during collection phase + this->forward_inplace(lhs_iface, lhs_data); + } else if (runstate_.is_verify()) { + // called during verify_ok + this->_verify_aux(lhs_iface, *lhs_data); + } else { + // should be unreachable + assert(false); + } + } + void DX1Collector::_verify_aux(AGCObject * iface, void * data) { diff --git a/xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp b/xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp new file mode 100644 index 00000000..edb35061 --- /dev/null +++ b/xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp @@ -0,0 +1,27 @@ +/** @file IGCObjectVisitor_DX1Collector.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObjectVisitor_DX1Collector.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObjectVisitor_DX1Collector.json5] +**/ + +#include "detail/IGCObjectVisitor_DX1Collector.hpp" + +namespace xo { + namespace mm { + auto + IGCObjectVisitor_DX1Collector::visit_child(DX1Collector & self, AGCObject * iface, void ** pp_data) noexcept -> void + { + self.visit_child(iface, pp_data); + } + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end IGCObjectVisitor_DX1Collector.cpp */