From 5542fdea8bd2b5912584db285365cca27d5d3f04 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 4 Dec 2025 21:31:55 -0500 Subject: [PATCH] xo-alloc/xo-ordinaltree: refactor rbtree Node alloc progress toward careful gc-aware assignment --- xo-alloc/include/xo/alloc/Object.hpp | 2 +- xo-alloc/src/alloc/Object.cpp | 9 +++ .../include/xo/allocutil/ObjectVisitor.hpp | 3 +- .../xo/allocutil/gc_allocator_traits.hpp | 61 ++++++++++++------- .../include/xo/ordinaltree/RedBlackTree.hpp | 8 ++- .../include/xo/ordinaltree/rbtree/Node.hpp | 8 ++- 6 files changed, 62 insertions(+), 29 deletions(-) diff --git a/xo-alloc/include/xo/alloc/Object.hpp b/xo-alloc/include/xo/alloc/Object.hpp index c1217418..742fba4c 100644 --- a/xo-alloc/include/xo/alloc/Object.hpp +++ b/xo-alloc/include/xo/alloc/Object.hpp @@ -118,7 +118,7 @@ namespace xo { /** tagged pointer with runtime type information **/ - virtual TaggedPtr self_tp() const = 0; + virtual TaggedPtr self_tp() const; /** print on stream @p os **/ virtual void display(std::ostream & os) const = 0; diff --git a/xo-alloc/src/alloc/Object.cpp b/xo-alloc/src/alloc/Object.cpp index 75abec14..ab23b76a 100644 --- a/xo-alloc/src/alloc/Object.cpp +++ b/xo-alloc/src/alloc/Object.cpp @@ -20,9 +20,18 @@ operator new (std::size_t z, const xo::Cpof & cpof) } namespace xo { + using xo::reflect::TaggedPtr; + gc::IAlloc * Object::mm = nullptr; + TaggedPtr + Object::self_tp() const + { + assert(false); + return TaggedPtr::universal_null(); + } + IObject * Object::_forward(IObject * src, gc::IAlloc * gc) diff --git a/xo-allocutil/include/xo/allocutil/ObjectVisitor.hpp b/xo-allocutil/include/xo/allocutil/ObjectVisitor.hpp index 08f01d2c..df336876 100644 --- a/xo-allocutil/include/xo/allocutil/ObjectVisitor.hpp +++ b/xo-allocutil/include/xo/allocutil/ObjectVisitor.hpp @@ -36,7 +36,8 @@ namespace xo { **/ template class ObjectVisitor { - void forward_children(T & target, IAlloc * gc) { (void)target; (void)gc; } + void forward_children(T & target, + IAlloc * gc) { (void)target; (void)gc; } }; #define XO_TRIVIAL_OBJECT_VISITOR(TYPE) \ diff --git a/xo-allocutil/include/xo/allocutil/gc_allocator_traits.hpp b/xo-allocutil/include/xo/allocutil/gc_allocator_traits.hpp index 6ddda37b..88ab33ca 100644 --- a/xo-allocutil/include/xo/allocutil/gc_allocator_traits.hpp +++ b/xo-allocutil/include/xo/allocutil/gc_allocator_traits.hpp @@ -10,7 +10,36 @@ #include namespace xo { + class IObject; + namespace gc { + class IAlloc; + + /** object interface for allocators A that don't provide A::gc_object_interface. + * See gc_allocator_traits + **/ + struct FallbackObjectInterface { + /** see also IObject::_requires_gc_hooks **/ + static constexpr bool _requires_gc_hooks = false; + /** see also IObject::_requires_write_barrier **/ + static constexpr bool _requires_write_barrier = false; + + /** see also IObject::_gc_assign_member **/ + template + void _gc_assign_member(T ** lhs, + T * rhs, + AA & alloc) { + (void)alloc; + *lhs = rhs; + } + + virtual void display(std::ostream &) const {} + virtual bool _is_forwarded() const { return false; } + virtual std::size_t _shallow_size() const { assert(false); return 0; } + virtual IObject * _shallow_copy(gc::IAlloc *) const { assert(false); return nullptr; } + virtual std::size_t _forward_children(gc::IAlloc *) { assert(false); return 0; } + }; + /** Extended version of * std::allocator_traits * Introduces additional i/face methods @@ -140,26 +169,12 @@ namespace xo { // gc_allocator_traits::template object_interface // template - struct object_interface { - /** see also IObject::_requires_gc_hooks **/ - static constexpr bool _requires_gc_hooks = false; - /** see also IObject::_requires_write_barrier **/ - static constexpr bool _requires_write_barrier = false; + struct object_interface : public FallbackObjectInterface {}; - /** see also IObject::_gc_assign_member **/ - template - void _gc_assign_member(T ** lhs, - T * rhs, - A & alloc) - { - *lhs = rhs; - } - - virtual bool _is_forwarded() const { return false; } - virtual std::size_t _shallow_size() const { assert(false); return 0; } - }; - - // specialization when A provides gc_object_interface + // specialization when an allocator A + // (which will actuallly be Allocator via SFINAE) + // provides gc_object_interface + // template struct object_interface> : public A::gc_object_interface {}; @@ -179,7 +194,9 @@ namespace xo { * using has_incremental_gc_interface = std::true_type; * }; **/ - static inline constexpr bool has_incremental_gc_interface_v = has_incremental_gc_interface::value; + static inline constexpr + bool + has_incremental_gc_interface_v = has_incremental_gc_interface::value; /** true iff this allocator advertises trivial deallocate * Allocate will include: @@ -188,7 +205,9 @@ namespace xo { * using has_trivial_deallocate = std::true_type; * }; **/ - static inline constexpr bool has_trivial_deallocate_v = has_trivial_deallocate::value; + static inline constexpr + bool + has_trivial_deallocate_v = has_trivial_deallocate::value; }; } /*namespace gc*/ } /*namespace xo*/ diff --git a/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp b/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp index b4aec68f..9bf4146d 100644 --- a/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp +++ b/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp @@ -619,14 +619,16 @@ namespace xo { // ----- Inherited from GcObjectInterface ----- +#ifdef SET_ASIDE virtual TaggedPtr self_tp() const { return Reflect::make_tp(const_cast(this)); } - virtual void display(std::ostream & os) const { +#endif + virtual void display(std::ostream & os) const final override { os << ""; } virtual std::size_t _shallow_size() const final override { return sizeof(*this); } - virtual IObject * _shallow_copy(gc::IAlloc * gc) const { + virtual IObject * _shallow_copy(gc::IAlloc * gc) const final override { if constexpr (GcObjectInterface::_requires_gc_hooks) { xo::Cpof cpof(gc, this); return new (cpof) RedBlackTree(*this); @@ -635,7 +637,7 @@ namespace xo { return nullptr; } } - virtual std::size_t _forward_children(gc::IAlloc * gc) { + virtual std::size_t _forward_children(gc::IAlloc * gc) final override { if constexpr (GcObjectInterface::_requires_gc_hooks) { using xo::gc::ObjectVisitor; diff --git a/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp b/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp index 530478aa..167bdca2 100644 --- a/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp +++ b/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp @@ -314,16 +314,18 @@ namespace xo { // ----- inherited from GcObjectInterface ----- +#ifdef NOPE virtual TaggedPtr self_tp() const { return Reflect::make_tp(const_cast(this)); } - virtual void display(std::ostream & os) const { +#endif + virtual void display(std::ostream & os) const final override { os << ""; } virtual std::size_t _shallow_size() const final override { return sizeof(*this); } /* note: only relevant when GcObjectInterface is xo::IObject */ - virtual IObject * _shallow_copy(gc::IAlloc * gc) const { + virtual IObject * _shallow_copy(gc::IAlloc * gc) const final override { if constexpr (GcObjectInterface::_requires_gc_hooks) { xo::Cpof cpof(gc, this); return new (cpof) Node(*this); @@ -333,7 +335,7 @@ namespace xo { } } - virtual std::size_t _forward_children(gc::IAlloc * gc) { + virtual std::size_t _forward_children(gc::IAlloc * gc) final override { if constexpr (GcObjectInterface::_requires_gc_hooks) { using xo::gc::ObjectVisitor;