xo-alloc/xo-ordinaltree: refactor rbtree Node alloc
progress toward careful gc-aware assignment
This commit is contained in:
parent
451425af87
commit
5542fdea8b
6 changed files with 63 additions and 30 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ namespace xo {
|
|||
**/
|
||||
template <typename T>
|
||||
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) \
|
||||
|
|
|
|||
|
|
@ -10,7 +10,36 @@
|
|||
#include <cassert>
|
||||
|
||||
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<A>
|
||||
**/
|
||||
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 <typename T, typename AA>
|
||||
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<Allocator>
|
||||
* Introduces additional i/face methods
|
||||
|
|
@ -140,26 +169,12 @@ namespace xo {
|
|||
// gc_allocator_traits<Allocator>::template object_interface<Allocator>
|
||||
//
|
||||
template <typename A, typename = void>
|
||||
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 <typename T>
|
||||
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 <typename A>
|
||||
struct object_interface<A, std::void_t<typename A::gc_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<Allocator>::value;
|
||||
static inline constexpr
|
||||
bool
|
||||
has_incremental_gc_interface_v = has_incremental_gc_interface<Allocator>::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<Allocator>::value;
|
||||
static inline constexpr
|
||||
bool
|
||||
has_trivial_deallocate_v = has_trivial_deallocate<Allocator>::value;
|
||||
};
|
||||
} /*namespace gc*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -619,14 +619,16 @@ namespace xo {
|
|||
|
||||
// ----- Inherited from GcObjectInterface -----
|
||||
|
||||
#ifdef SET_ASIDE
|
||||
virtual TaggedPtr self_tp() const {
|
||||
return Reflect::make_tp(const_cast<RedBlackTree *>(this));
|
||||
}
|
||||
virtual void display(std::ostream & os) const {
|
||||
#endif
|
||||
virtual void display(std::ostream & os) const final override {
|
||||
os << "<RedBlackTree>";
|
||||
}
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -314,16 +314,18 @@ namespace xo {
|
|||
|
||||
// ----- inherited from GcObjectInterface -----
|
||||
|
||||
#ifdef NOPE
|
||||
virtual TaggedPtr self_tp() const {
|
||||
return Reflect::make_tp(const_cast<Node *>(this));
|
||||
}
|
||||
virtual void display(std::ostream & os) const {
|
||||
#endif
|
||||
virtual void display(std::ostream & os) const final override {
|
||||
os << "<Node>";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue