refactor: + narrower interface for gc pointer forwarding
add AGCObjectVisitor, instead of requiring ACollector.
This commit is contained in:
parent
57688a826a
commit
801bb9e39d
266 changed files with 952 additions and 947 deletions
|
|
@ -6,6 +6,7 @@
|
|||
includes: [
|
||||
"<xo/alloc2/Allocator.hpp>",
|
||||
"<xo/alloc2/Collector.hpp>",
|
||||
"<xo/alloc2/GCObjectVisitor.hpp>",
|
||||
"<cstdint>",
|
||||
"<cstddef>",
|
||||
],
|
||||
|
|
@ -42,6 +43,11 @@
|
|||
doc: ["fomo collector type"],
|
||||
definition: "xo::mm::ACollector",
|
||||
},
|
||||
{
|
||||
name: "AGCObjectVisitor",
|
||||
doc: ["fomo collector type"],
|
||||
definition: "xo::mm::AGCObjectVisitor",
|
||||
},
|
||||
],
|
||||
const_methods: [
|
||||
// size_type shallow_size() const noexcept
|
||||
|
|
@ -68,13 +74,17 @@
|
|||
noexcept: true,
|
||||
attributes: [],
|
||||
},
|
||||
// size_type forward_children(obj<ACollector>) noexcept
|
||||
// size_type visit_gco_children(obj<AGCObjectVisitor>) noexcept
|
||||
{
|
||||
name: "forward_children",
|
||||
doc: ["during GC: forward immdiate children"],
|
||||
name: "visit_gco_children",
|
||||
doc: [
|
||||
"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"
|
||||
],
|
||||
return_type: "void",
|
||||
args: [
|
||||
{type: "obj<ACollector>", name: "gc"},
|
||||
{type: "obj<AGCObjectVisitor>", name: "fn"},
|
||||
],
|
||||
const: true,
|
||||
noexcept: true,
|
||||
|
|
|
|||
|
|
@ -71,5 +71,26 @@
|
|||
attributes: [],
|
||||
},
|
||||
],
|
||||
router_facet_explicit_content: []
|
||||
router_facet_explicit_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);",
|
||||
"",
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ IGCObject_Any::shallow_move(Opaque, obj<ACollector>) const noexcept -> Opaque
|
|||
}
|
||||
|
||||
auto
|
||||
IGCObject_Any::forward_children(Opaque, obj<ACollector>) const noexcept -> void
|
||||
IGCObject_Any::visit_gco_children(Opaque, obj<AGCObjectVisitor>) const noexcept -> void
|
||||
{
|
||||
_fatal();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue