refactor: + narrower interface for gc pointer forwarding
add AGCObjectVisitor, instead of requiring ACollector.
This commit is contained in:
parent
df0bbe1b31
commit
90ab86f69c
9 changed files with 115 additions and 13 deletions
|
|
@ -16,6 +16,7 @@
|
|||
// includes (via {facet_includes})
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <xo/alloc2/Collector.hpp>
|
||||
#include <xo/alloc2/GCObjectVisitor.hpp>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <xo/facet/obj.hpp>
|
||||
|
|
@ -48,6 +49,8 @@ public:
|
|||
using AAllocator = xo::mm::AAllocator;
|
||||
/** fomo collector type **/
|
||||
using ACollector = xo::mm::ACollector;
|
||||
/** fomo collector type **/
|
||||
using AGCObjectVisitor = xo::mm::AGCObjectVisitor;
|
||||
///@}
|
||||
|
||||
/** @defgroup mm-gcobject-methods **/
|
||||
|
|
@ -66,8 +69,10 @@ public:
|
|||
// nonconst methods
|
||||
/** move instance using allocator **/
|
||||
virtual Opaque shallow_move(Opaque data, obj<ACollector> gc) const noexcept = 0;
|
||||
/** during GC: forward immdiate children **/
|
||||
virtual void forward_children(Opaque data, obj<ACollector> gc) const noexcept = 0;
|
||||
/** Invoke fn.visit_child(iface,data) for each child GCObject pointer.
|
||||
Context: provides address of data pointer so it can be updated in place
|
||||
when @p fn invokes garbage collector reentry point **/
|
||||
virtual void visit_gco_children(Opaque data, obj<AGCObjectVisitor> fn) const noexcept = 0;
|
||||
///@}
|
||||
}; /*AGCObject*/
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace mm {
|
|||
using size_type = AGCObject::size_type;
|
||||
using AAllocator = AGCObject::AAllocator;
|
||||
using ACollector = AGCObject::ACollector;
|
||||
using AGCObjectVisitor = AGCObject::AGCObjectVisitor;
|
||||
|
||||
///@}
|
||||
/** @defgroup mm-gcobject-any-methods **/
|
||||
|
|
@ -64,7 +65,7 @@ namespace mm {
|
|||
|
||||
// nonconst methods
|
||||
[[noreturn]] Opaque shallow_move(Opaque, obj<ACollector>) const noexcept override;
|
||||
[[noreturn]] void forward_children(Opaque, obj<ACollector>) const noexcept override;
|
||||
[[noreturn]] void visit_gco_children(Opaque, obj<AGCObjectVisitor>) const noexcept override;
|
||||
|
||||
///@}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <xo/alloc2/Collector.hpp>
|
||||
#include <xo/alloc2/GCObjectVisitor.hpp>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ namespace mm {
|
|||
using size_type = AGCObject::size_type;
|
||||
using AAllocator = AGCObject::AAllocator;
|
||||
using ACollector = AGCObject::ACollector;
|
||||
using AGCObjectVisitor = AGCObject::AGCObjectVisitor;
|
||||
///@}
|
||||
|
||||
/** @defgroup mm-gcobject-xfer-methods **/
|
||||
|
|
@ -54,8 +56,8 @@ namespace mm {
|
|||
Opaque shallow_move(Opaque data, obj<ACollector> gc) const noexcept override {
|
||||
return I::shallow_move(_dcast(data), gc);
|
||||
}
|
||||
void forward_children(Opaque data, obj<ACollector> gc) const noexcept override {
|
||||
return I::forward_children(_dcast(data), gc);
|
||||
void visit_gco_children(Opaque data, obj<AGCObjectVisitor> fn) const noexcept override {
|
||||
return I::visit_gco_children(_dcast(data), fn);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,46 @@ namespace xo {
|
|||
class ACollector;
|
||||
class AGCObject;
|
||||
|
||||
/** defined here to avoid #include cycle, since
|
||||
* template obj<AGCObject,DRepr> awkward to make available
|
||||
* in RCollector.hpp
|
||||
**/
|
||||
template <typename Object>
|
||||
template <typename DRepr>
|
||||
void
|
||||
RGCObjectVisitor<Object>::visit_child(xo::facet::obj<AGCObject,DRepr> * p_obj)
|
||||
{
|
||||
this->visit_child(p_obj->iface(), (void **)&(p_obj->data_));
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
template <typename DRepr>
|
||||
void
|
||||
RGCObjectVisitor<Object>::visit_child(DRepr ** p_repr)
|
||||
{
|
||||
// fetch static interface for DRepr (strip const: FacetImplementation specializations use non-const DRepr)
|
||||
auto iface = xo::facet::impl_for<AGCObject, std::remove_const_t<DRepr>>();
|
||||
|
||||
this->visit_child(&iface, (void **)p_repr);
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
template <typename AFacet, typename DRepr>
|
||||
requires (!std::is_same_v<AFacet, AGCObject>)
|
||||
void
|
||||
RGCObjectVisitor<Object>::visit_poly_child(obj<AFacet, DRepr> * p_objs)
|
||||
{
|
||||
if (*p_objs) {
|
||||
auto e = xo::facet::FacetRegistry::instance().variant<AGCObject,AFacet>(*p_objs);
|
||||
|
||||
this->visit_child(e.iface(), (void **)&(p_objs->data_));
|
||||
}
|
||||
}
|
||||
|
||||
// ----- DEPRECATED -----
|
||||
//
|
||||
// Moving these methods to RGCObjectVisitor
|
||||
|
||||
/** defined here to avoid #include cycle, since
|
||||
* template obj<AGCObject,DRepr> awkward to make available
|
||||
* in RCollector.hpp
|
||||
|
|
@ -52,6 +92,8 @@ namespace xo {
|
|||
}
|
||||
}
|
||||
|
||||
// ----- mm_do_assign -----
|
||||
|
||||
/** gc-aware assignment; engage special book-keeping for cross-gen pointers **/
|
||||
inline void mm_do_assign(obj<ACollector> & gc,
|
||||
void * parent,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public:
|
|||
using size_type = AGCObject::size_type;
|
||||
using AAllocator = AGCObject::AAllocator;
|
||||
using ACollector = AGCObject::ACollector;
|
||||
using AGCObjectVisitor = AGCObject::AGCObjectVisitor;
|
||||
///@}
|
||||
|
||||
/** @defgroup mm-gcobject-router-ctors **/
|
||||
|
|
@ -60,8 +61,8 @@ public:
|
|||
Opaque shallow_move(obj<ACollector> gc) noexcept {
|
||||
return O::iface()->shallow_move(O::data(), gc);
|
||||
}
|
||||
void forward_children(obj<ACollector> gc) noexcept {
|
||||
return O::iface()->forward_children(O::data(), gc);
|
||||
void visit_gco_children(obj<AGCObjectVisitor> fn) noexcept {
|
||||
return O::iface()->visit_gco_children(O::data(), fn);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,26 @@ public:
|
|||
///@{
|
||||
|
||||
// explicit injected content
|
||||
|
||||
/** visit forward faceted object child pointer in place.
|
||||
Defined in RGCObject.hpp to avoid #include cycle
|
||||
**/
|
||||
template <typename DRepr>
|
||||
void visit_child(xo::facet::obj<AGCObject,DRepr> * p_obj);
|
||||
|
||||
/** visit typed child data pointer in place.
|
||||
Defined in RGCObject.hpp to avoid #include cycle
|
||||
**/
|
||||
template <typename DRepr>
|
||||
void visit_child(DRepr ** pp_data);
|
||||
|
||||
/** visit faceted object pointer stored using some facet
|
||||
other than AGCObject
|
||||
**/
|
||||
template <typename AFacet, typename DRepr>
|
||||
requires (!std::is_same_v<AFacet, AGCObject>)
|
||||
void visit_poly_child(obj<AFacet,DRepr> * p_pivot);
|
||||
|
||||
|
||||
// builtin methods
|
||||
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue