diff --git a/xo-alloc2/include/xo/alloc2/alloc/AAllocIterator.hpp b/xo-alloc2/include/xo/alloc2/alloc/AAllocIterator.hpp index af308b6d..4b9f4ab9 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/AAllocIterator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/AAllocIterator.hpp @@ -7,6 +7,7 @@ #include "AllocInfo.hpp" #include "cmpresult.hpp" +#include "typeseq.hpp" #include namespace xo { @@ -22,11 +23,12 @@ namespace xo { **/ struct AAllocIterator { using obj_AAllocIterator = xo::facet::obj; + using typeseq = xo::facet::typeseq; /** @defgroup mm-allociterator-methods AllocIterator methods **/ ///@{ /** RTTI: unique id# for actual runtime *data* representation **/ - virtual int32_t _typeseq() const noexcept = 0; + virtual typeseq _typeseq() const noexcept = 0; /** retrieve AllocInfo for current iterator position **/ virtual AllocInfo deref(Copaque d) const noexcept = 0; diff --git a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp index 8e6e5e61..6c191c5a 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp @@ -9,6 +9,7 @@ #include "AllocInfo.hpp" //#include "AllocIterator.hpp" #include "AllocRange.hpp" +#include "typeseq.hpp" #include #include #include @@ -40,6 +41,8 @@ namespace xo { using header_type = std::uint64_t; /** iterator range. These are forward iterators over allocs **/ using range_type = AllocRange; + /** sequence number identifying a datatype **/ + using typeseq = xo::facet::typeseq; ///@} /* @@ -58,7 +61,7 @@ namespace xo { ///@{ /** RTTI: unique id# for actual runtime data representation **/ - virtual int32_t _typeseq() const noexcept = 0; + virtual typeseq _typeseq() const noexcept = 0; /** optional name for allocator @p d . * Allows labeling allocators, for diagnostics/instrumentation. **/ diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Any.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Any.hpp index 9765194b..f946c397 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Any.hpp @@ -1,4 +1,4 @@ -/** @file IAllocIter_Any.hpp +/** @file IAllocIterator_Any.hpp * * @author Roland Conybeare, Dec 2025 **/ @@ -20,10 +20,12 @@ namespace xo { * @brief AllocIterator implementation for empty variant instance **/ struct IAllocIterator_Any : public AAllocIterator { + using typeseq = xo::facet::typeseq; + const AAllocIterator * iface() const { return std::launder(this); } // from AAllocIterator - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } // const methods [[noreturn]] AllocInfo deref(Copaque) const noexcept override { _fatal(); } @@ -37,10 +39,10 @@ namespace xo { [[noreturn]] static void _fatal(); public: - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; } /*namespace mm*/ } /*namespace xo*/ -/* end IAllocIter_Any.hpp */ +/* end IAllocIterator_Any.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Xfer.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Xfer.hpp index 9aa8c33d..e61e326c 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocIterator_Xfer.hpp @@ -18,6 +18,7 @@ namespace xo { typename IAllocIterator_DRepr> struct IAllocIterator_Xfer : public AAllocIterator { using Impl = IAllocIterator_DRepr; + using typeseq = xo::facet::typeseq; static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } @@ -26,7 +27,7 @@ namespace xo { // const methods - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } AllocInfo deref(Copaque d) const noexcept override { return I::deref(_dcast(d)); } cmpresult compare(Copaque d, @@ -42,12 +43,12 @@ namespace xo { using I = Impl; public: - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; template - int32_t + xo::facet::typeseq IAllocIterator_Xfer::s_typeseq = facet::typeseq::id(); diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp index dd0df835..60b174ef 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp @@ -7,6 +7,7 @@ #include "AAllocator.hpp" #include "AllocIterator.hpp" +#include "typeseq.hpp" #include namespace xo { @@ -30,7 +31,7 @@ namespace xo { const AAllocator * iface() const { return std::launder(this); } // from AAllocator - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } // const methods [[noreturn]] std::string_view name(Copaque) const noexcept override { _fatal(); } @@ -58,7 +59,7 @@ namespace xo { [[noreturn]] static void _fatal(); public: - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; } diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp index 4f92ff0d..796549bc 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp @@ -25,6 +25,7 @@ namespace xo { using Impl = IAllocator_DRepr; using size_type = AAllocator::size_type; using value_type = AAllocator::value_type; + using typeseq = AAllocator::typeseq; ///@} /** @defgroup mm-allocator-xfer-methods IAllocator_Xfer methods **/ @@ -38,7 +39,7 @@ namespace xo { // const methods /** return typeseq for @tparam DRepr **/ - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } std::string_view name(Copaque d) const noexcept override { return I::name(_dcast(d)); } size_type reserved(Copaque d) const noexcept override { return I::reserved(_dcast(d)); } size_type size(Copaque d) const noexcept override { return I::size(_dcast(d)); } @@ -75,12 +76,12 @@ namespace xo { using I = Impl; public: - static int32_t s_typeseq; + static xo::facet::typeseq s_typeseq; static bool _valid; }; template - int32_t + xo::facet::typeseq IAllocator_Xfer::s_typeseq = facet::typeseq::id(); template diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocIterator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocIterator.hpp index 73602cc5..4e1a95f8 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocIterator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocIterator.hpp @@ -17,11 +17,12 @@ namespace xo { public: using ObjectType = Object; using DataPtr = Object::DataPtr; + using typeseq = xo::facet::typeseq; RAllocIterator() {} RAllocIterator(Object::DataPtr data) : Object{std::move(data)} {} - int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } AllocInfo deref() const noexcept { return O::iface()->deref(O::data()); } cmpresult compare(const obj & other) const noexcept { return O::iface()->compare(O::data(), other); } diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index 706b6a86..005dc44e 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -20,6 +20,7 @@ namespace xo { public: using ObjectType = Object; using DataPtr = Object::DataPtr; + using typeseq = xo::facet::typeseq; using size_type = std::size_t; using value_type = std::byte *; using range_type = AAllocator::range_type; @@ -27,7 +28,7 @@ namespace xo { RAllocator() {} RAllocator(Object::DataPtr data) : Object{std::move(data)} {} - int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } std::string_view name() const noexcept { return O::iface()->name(O::data()); } size_type reserved() const noexcept { return O::iface()->reserved(O::data()); } size_type size() const noexcept { return O::iface()->size(O::data()); } diff --git a/xo-alloc2/include/xo/alloc2/arena/ArenaConfig.hpp b/xo-alloc2/include/xo/alloc2/arena/ArenaConfig.hpp index 7c2b6f80..c8d3faca 100644 --- a/xo-alloc2/include/xo/alloc2/arena/ArenaConfig.hpp +++ b/xo-alloc2/include/xo/alloc2/arena/ArenaConfig.hpp @@ -24,7 +24,7 @@ namespace xo { /** optional name, for diagnostics **/ std::string name_; /** desired arena size -- hard max = reserved virtual memory **/ - std::size_t size_; + std::size_t size_ = 0; /** hugepage size -- using huge pages relieves some TLB pressure * (provided you use their full extent :) **/ diff --git a/xo-alloc2/src/alloc2/DArena.cpp b/xo-alloc2/src/alloc2/DArena.cpp index 095349ef..07597b67 100644 --- a/xo-alloc2/src/alloc2/DArena.cpp +++ b/xo-alloc2/src/alloc2/DArena.cpp @@ -46,14 +46,13 @@ namespace xo { // end of hugeppage-aligned range starting at aligned_base byte * aligned_hi = aligned_base + target_z; -#ifdef NOT_YET log && log("acquired memory [lo,hi) using mmap", xtag("lo", base), + xtag("aligned_lo", aligned_base), xtag("req_z", req_z), xtag("target_z", target_z), - xtag("hi", (byte *)(base) + z)); -#endif - + xtag("aligned_hi", aligned_hi), + xtag("hi", hi)); // 3. assess mmap success { @@ -109,7 +108,7 @@ namespace xo { DArena DArena::map(const ArenaConfig & cfg) { - //scope log(XO_DEBUG(debug_flag), xtag("name", name)); + scope log(XO_DEBUG(true)); /* vm page size. 4KB, probably */ size_t page_z = getpagesize(); @@ -122,6 +121,9 @@ namespace xo { */ size_t align_z = (enable_hugepage_flag ? cfg.hugepage_z_ : page_z); + log && log(xtag("page_z", page_z), + xtag("align_z", align_z)); + auto [lo, hi] = map_aligned_range(cfg.size_, align_z, enable_hugepage_flag); diff --git a/xo-alloc2/src/alloc2/IAllocIterator_Any.cpp b/xo-alloc2/src/alloc2/IAllocIterator_Any.cpp index f21acc0c..befaea8c 100644 --- a/xo-alloc2/src/alloc2/IAllocIterator_Any.cpp +++ b/xo-alloc2/src/alloc2/IAllocIterator_Any.cpp @@ -26,7 +26,7 @@ namespace xo { std::terminate(); } - int32_t + typeseq IAllocIterator_Any::s_typeseq = typeseq::id(); bool diff --git a/xo-alloc2/src/alloc2/IAllocator_Any.cpp b/xo-alloc2/src/alloc2/IAllocator_Any.cpp index 1d12c6cb..864ddf15 100644 --- a/xo-alloc2/src/alloc2/IAllocator_Any.cpp +++ b/xo-alloc2/src/alloc2/IAllocator_Any.cpp @@ -27,7 +27,7 @@ namespace xo { std::terminate(); } - int32_t + typeseq IAllocator_Any::s_typeseq = typeseq::id(); bool diff --git a/xo-facet/include/xo/facet/facet.hpp b/xo-facet/include/xo/facet/facet.hpp index 47abae46..b1a420ad 100644 --- a/xo-facet/include/xo/facet/facet.hpp +++ b/xo-facet/include/xo/facet/facet.hpp @@ -70,7 +70,7 @@ namespace xo { "Abstract facet expected to have trivial dtor since no state"); static_assert (requires(T & facet) { - { facet._typeseq() } -> std::convertible_to; }, + { facet._typeseq().seqno() } -> std::convertible_to; }, "Abstract facet must provide a _typeseq() method for safe downcasting"); return true; }; diff --git a/xo-facet/include/xo/facet/typeseq.hpp b/xo-facet/include/xo/facet/typeseq.hpp index d54ac982..b1088745 100644 --- a/xo-facet/include/xo/facet/typeseq.hpp +++ b/xo-facet/include/xo/facet/typeseq.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include namespace xo { @@ -15,6 +16,8 @@ namespace xo { */ template struct typeseq_impl { + explicit typeseq_impl(int32_t s) : seqno_{s} {} + /** Can't have this be constexpr. * We need ids in shared libraries to be generated * at load time to avoid false positives @@ -28,7 +31,7 @@ namespace xo { * when using clang. **/ template - static int32_t id() { + static typeseq_impl id() { static bool armed = true; static int32_t id = 0; @@ -37,15 +40,40 @@ namespace xo { id = ++s_next_id; } - return id; + return typeseq_impl(id); + } + int32_t seqno() const { return seqno_; } + + private: static int32_t s_next_id; + + int32_t seqno_; }; template int32_t typeseq_impl::s_next_id = 0; + template + inline bool + operator==(const typeseq_impl & lhs, const typeseq_impl & rhs) { + return lhs.seqno() == rhs.seqno(); + } + + template + inline bool + operator!=(const typeseq_impl & lhs, const typeseq_impl & rhs) { + return lhs.seqno() != rhs.seqno(); + } + + template + inline std::ostream & + operator<<(std::ostream & s, const typeseq_impl & x) { + s << x.seqno(); + return s; + } + using typeseq = typeseq_impl<>; } } /*namespace xo*/ diff --git a/xo-facet/utest/objectmodel.test.cpp b/xo-facet/utest/objectmodel.test.cpp index fbeb9440..57a80c5b 100644 --- a/xo-facet/utest/objectmodel.test.cpp +++ b/xo-facet/utest/objectmodel.test.cpp @@ -34,7 +34,7 @@ namespace xo { using TypeErasedIface = struct IComplex_Any; /** RTTI: reports unique id# for actual runtime data representation **/ - virtual int32_t _typeseq() const = 0; + virtual typeseq _typeseq() const = 0; virtual double xcoord(void * data) const = 0; virtual double ycoord(void * data) const = 0; @@ -61,7 +61,7 @@ namespace xo { // from AComplex - virtual int32_t _typeseq() const final override { return s_typeseq; } + virtual typeseq _typeseq() const final override { return s_typeseq; } virtual double xcoord(void * data) const final override { return Impl::xcoord(*(DRepr*)data); } virtual double ycoord(void * data) const final override { return Impl::ycoord(*(DRepr*)data); } @@ -70,12 +70,12 @@ namespace xo { virtual void destruct_data(void * data) const final override { Impl::destruct_data(*(DRepr*)data); } - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; template - int32_t + typeseq IComplex_Xfer::s_typeseq = typeseq::id(); template @@ -96,7 +96,7 @@ namespace xo { * such as IComplex_RectCoords or IComplex_PolarCoords. **/ struct IComplex_Any : public AComplex { - virtual int32_t _typeseq() const final override { return s_typeseq; } + virtual typeseq _typeseq() const final override { return s_typeseq; } virtual double xcoord(void *) const final override { assert(false); return 0.0; } virtual double ycoord(void *) const final override { assert(false); return 0.0; } @@ -105,11 +105,11 @@ namespace xo { virtual void destruct_data(void *) const final override { assert(false); } - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; - int32_t + typeseq IComplex_Any::s_typeseq = typeseq::id(); bool @@ -190,7 +190,7 @@ namespace xo { RComplex() {} RComplex(Object::DataPtr data) : Object{std::move(data)} {} - int32_t _typeseq() const { return Object::iface()->_typeseq(); } + typeseq _typeseq() const { return Object::iface()->_typeseq(); } double xcoord() const { return Object::iface()->xcoord(Object::data()); } double ycoord() const { return Object::iface()->ycoord(Object::data()); } double argument() const { return Object::iface()->argument(Object::data()); } diff --git a/xo-gc/include/xo/gc/detail/ACollector.hpp b/xo-gc/include/xo/gc/detail/ACollector.hpp index 5a41f913..0298ad2e 100644 --- a/xo-gc/include/xo/gc/detail/ACollector.hpp +++ b/xo-gc/include/xo/gc/detail/ACollector.hpp @@ -31,9 +31,10 @@ namespace xo { * A collector implementation will also support the @ref AAllocator facet, see also **/ struct ACollector { + using typeseq = xo::facet::typeseq; using size_type = std::size_t; - virtual int32_t _typeseq() const noexcept = 0; + virtual typeseq _typeseq() const noexcept = 0; virtual size_type allocated(Copaque d, generation g, role r) const noexcept = 0; @@ -50,8 +51,10 @@ namespace xo { * @c AGCObject_Xfer for some @c DFoo * in which case calls through @c std::launder(&iface) * will properly act on @c DFoo. + * + * Return false if installation fails (e.g. memory exhausted) **/ - virtual void install_type(Opaque d, int32_t tseq, IGCObject_Any & iface) = 0; + virtual bool install_type(Opaque d, const AGCObject & iface) = 0; virtual void add_gc_root(Opaque d, int32_t tseq, Opaque * root) = 0; /** evacuate @p *lhs, that refers to state with interface @p lhs_iface, diff --git a/xo-gc/include/xo/gc/detail/AGCObject.hpp b/xo-gc/include/xo/gc/detail/AGCObject.hpp index ae2b8a08..7c2ac308 100644 --- a/xo-gc/include/xo/gc/detail/AGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/AGCObject.hpp @@ -26,10 +26,11 @@ namespace xo { * by ACollector **/ struct AGCObject { + using typeseq = xo::facet::typeseq; using size_type = std::size_t; /** RTTI: unique id# for actual runtime data representation **/ - virtual int32_t _typeseq() const noexcept = 0; + virtual typeseq _typeseq() const noexcept = 0; virtual size_type shallow_size(Copaque d) const noexcept = 0; virtual Opaque shallow_copy(Copaque d, diff --git a/xo-gc/include/xo/gc/detail/ICollector_Any.hpp b/xo-gc/include/xo/gc/detail/ICollector_Any.hpp index b4836f66..ad55265d 100644 --- a/xo-gc/include/xo/gc/detail/ICollector_Any.hpp +++ b/xo-gc/include/xo/gc/detail/ICollector_Any.hpp @@ -6,6 +6,7 @@ #pragma once #include "ACollector.hpp" +#include "AGCObject.hpp" //#include namespace xo { @@ -34,7 +35,7 @@ namespace xo { [[noreturn]] size_type committed(Copaque, generation, role) const noexcept override { _fatal(); } // non-const methods - [[noreturn]] void install_type(Opaque, int32_t, IGCObject_Any &) noexcept override { _fatal(); } + [[noreturn]] bool install_type(Opaque, const AGCObject &) noexcept override { _fatal(); } [[noreturn]] void add_gc_root(Opaque, int32_t, Opaque *) override { _fatal(); } [[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override { _fatal(); } @@ -42,7 +43,7 @@ namespace xo { [[noreturn]] static void _fatal(); public: - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; } /*namespace mm*/ diff --git a/xo-gc/include/xo/gc/detail/ICollector_DX1Collector.hpp b/xo-gc/include/xo/gc/detail/ICollector_DX1Collector.hpp index c531ae13..19392896 100644 --- a/xo-gc/include/xo/gc/detail/ICollector_DX1Collector.hpp +++ b/xo-gc/include/xo/gc/detail/ICollector_DX1Collector.hpp @@ -41,8 +41,7 @@ namespace xo { static size_type reserved(const DX1Collector & d, generation g, role r); static size_type committed(const DX1Collector & d, generation g, role r); - static void install_type(DX1Collector & d, - int32_t seq, IGCObject_Any & iface); + static bool install_type(DX1Collector & d, const AGCObject & iface); static void add_gc_root(DX1Collector & d, int32_t tseq, Opaque * root); static void forward_inplace(DX1Collector & d, AGCObject * lhs_iface, void ** lhs_data); diff --git a/xo-gc/include/xo/gc/detail/ICollector_Xfer.hpp b/xo-gc/include/xo/gc/detail/ICollector_Xfer.hpp index c44bd3ca..d184cb9b 100644 --- a/xo-gc/include/xo/gc/detail/ICollector_Xfer.hpp +++ b/xo-gc/include/xo/gc/detail/ICollector_Xfer.hpp @@ -6,6 +6,7 @@ #pragma once #include "ACollector.hpp" +#include "AGCObject.hpp" namespace xo { namespace mm { @@ -30,7 +31,7 @@ namespace xo { // const methods - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } size_type allocated(Copaque d, generation g, role r) const noexcept override { return I::allocated(_dcast(d), g, r); } @@ -43,8 +44,8 @@ namespace xo { // non-const methods - void install_type(Opaque d, int32_t tseq, IGCObject_Any & iface) override { - I::install_type(_dcast(d), tseq, iface); + bool install_type(Opaque d, const AGCObject & iface) override { + return I::install_type(_dcast(d), iface); } void add_gc_root(Opaque d, int32_t tseq, Opaque * root) override { I::add_gc_root(_dcast(d), tseq, root); @@ -57,12 +58,12 @@ namespace xo { using I = Impl; public: - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; template - int32_t + xo::facet::typeseq ICollector_Xfer::s_typeseq = facet::typeseq::id(); template diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp index b387b9b9..88b19e8b 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp @@ -24,12 +24,13 @@ namespace xo { * @brief AGCObject implementation for empty variant instance **/ struct IGCObject_Any : public AGCObject { + using typeseq = xo::facet::typeseq; using size_type = std::size_t; const AGCObject * iface() const { return std::launder(this); } // from AGCObject - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } [[noreturn]] size_type shallow_size(Copaque) const noexcept override { _fatal(); } [[noreturn]] Opaque shallow_copy(Copaque, @@ -41,7 +42,7 @@ namespace xo { [[noreturn]] static void _fatal(); public: - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; } /*namespace mm*/ diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp index 95e20ff1..a9deb4ad 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp @@ -27,7 +27,7 @@ namespace xo { // const methods - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } size_type shallow_size(Copaque d) const noexcept override { return I::shallow_size(_dcast(d)); } @@ -46,12 +46,12 @@ namespace xo { using I = Impl; public: - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; }; template - int32_t + xo::facet::typeseq IGCObject_Xfer::s_typeseq = facet::typeseq::id(); template diff --git a/xo-gc/include/xo/gc/detail/RCollector.hpp b/xo-gc/include/xo/gc/detail/RCollector.hpp index 47e9c43b..e6eeca6a 100644 --- a/xo-gc/include/xo/gc/detail/RCollector.hpp +++ b/xo-gc/include/xo/gc/detail/RCollector.hpp @@ -27,7 +27,7 @@ namespace xo { size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); } size_type committed(generation g, role r) const noexcept { return O::iface()->committed(O::data(), g, r); } - void install_type(int32_t tseq, IGCObject_Any & iface) { return O::iface()->install_type(O::data(), tseq, iface); } + bool install_type(const AGCObject & iface) { return O::iface()->install_type(O::data(), iface); } void add_gc_root(int32_t tseq, Opaque * root) { O::iface()->add_gc_root(O::data(), tseq, root); } void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data); } diff --git a/xo-gc/include/xo/gc/detail/RGCObject.hpp b/xo-gc/include/xo/gc/detail/RGCObject.hpp index 29bebf15..4c3205b0 100644 --- a/xo-gc/include/xo/gc/detail/RGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/RGCObject.hpp @@ -18,12 +18,13 @@ namespace xo { public: using ObjectType = Object; using DataPtr = Object::DataPtr; + using typeseq = xo::facet::typeseq; using size_type = std::size_t; RGCObject() = default; RGCObject(Object::DataPtr data) : Object{std::move(data)} {} - int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } size_type shallow_size() const noexcept { O::iface()->shallow_size(O::data()); } Opaque shallow_copy(obj mm) const noexcept { O::iface()->shallow_copy(O::data(), mm); } size_type forward_children() noexcept { O::iface()->forward_children(O::data()); } diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index 7e91ddbd..de747764 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -13,9 +13,12 @@ #include #include #include +#include +#include // for ::getpagesize() namespace xo { using xo::mm::AAllocator; + using xo::facet::typeseq; using xo::facet::with_facet; namespace mm { @@ -61,6 +64,19 @@ namespace xo { config_.arena_config_.header_.age_bits_ + config_.arena_config_.header_.tseq_bits_ <= 64); + size_t page_z = getpagesize(); + + /* 1MB reserved address space enough for up to 128k distinct types. + * In this case don't want to use hugepages since actual #of types + * likely << .size/8 + */ + object_types_ = DArena::map( + ArenaConfig{ + .name_ = "x1-object-types", + .size_ = cfg.object_types_z_, + .hugepage_z_ = page_z, + .store_header_flag_ = false}); + for (uint32_t igen = 0, ngen = cfg.n_generation_; igen < ngen; ++igen) { space_storage_[0][igen] = DArena::map(cfg.arena_config_); space_storage_[1][igen] = DArena::map(cfg.arena_config_); @@ -103,7 +119,7 @@ namespace xo { accumulate_total_aux(const DX1Collector & d, size_t (DArena::* get_stat_fn)() const) noexcept { - size_t z = 0; + size_t z = (d.object_types_.*get_stat_fn)(); for (role ri : role::all()) { for (generation gj{0}; gj < d.config_.n_generation_; ++gj) { @@ -182,6 +198,23 @@ namespace xo { return config_.arena_config_.header_.is_forwarding_tseq(hdr); } + bool + DX1Collector::install_type(const AGCObject & meta) noexcept + { + typeseq tseq = meta._typeseq(); + + bool ok = object_types_.expand(sizeof(AGCObject) * (tseq.seqno() + 1)); + if (!ok) + return false; + + AGCObject * v = reinterpret_cast(object_types_.lo_); + + /* explicitly copying vtable pointer here */ + std::memcpy((void*)&(v[tseq.seqno()]), (void*)&meta, sizeof(AGCObject)); + + return true; + } + auto DX1Collector::alloc(size_type z) noexcept -> value_type { diff --git a/xo-gc/src/gc/ICollector_Any.cpp b/xo-gc/src/gc/ICollector_Any.cpp index d3ea1fb8..99563bf9 100644 --- a/xo-gc/src/gc/ICollector_Any.cpp +++ b/xo-gc/src/gc/ICollector_Any.cpp @@ -27,7 +27,7 @@ namespace xo { std::terminate(); } - int32_t + typeseq ICollector_Any::s_typeseq = typeseq::id(); bool diff --git a/xo-gc/src/gc/ICollector_DX1Collector.cpp b/xo-gc/src/gc/ICollector_DX1Collector.cpp index b4d8f24d..5428e75b 100644 --- a/xo-gc/src/gc/ICollector_DX1Collector.cpp +++ b/xo-gc/src/gc/ICollector_DX1Collector.cpp @@ -47,16 +47,11 @@ namespace xo { return stat_helper(d, &DArena::committed, g, r); } - void + bool ICollector_DX1Collector::install_type(DX1Collector & d, - std::int32_t tseq, - IGCObject_Any & iface) + const AGCObject & iface) { - (void)d; - (void)tseq; - (void)iface; - - assert(false); + return d.install_type(iface); } void diff --git a/xo-gc/src/gc/IGCObject_Any.cpp b/xo-gc/src/gc/IGCObject_Any.cpp index 0de21224..f39445c8 100644 --- a/xo-gc/src/gc/IGCObject_Any.cpp +++ b/xo-gc/src/gc/IGCObject_Any.cpp @@ -22,7 +22,7 @@ namespace xo { std::terminate(); } - int32_t + typeseq IGCObject_Any::s_typeseq = typeseq::id(); bool diff --git a/xo-object2/include/xo/object2/sequence/ASequence.hpp b/xo-object2/include/xo/object2/sequence/ASequence.hpp index 332e7cff..301d5be8 100644 --- a/xo-object2/include/xo/object2/sequence/ASequence.hpp +++ b/xo-object2/include/xo/object2/sequence/ASequence.hpp @@ -34,6 +34,8 @@ public: /** @defgroup scm-sequence-type-traits **/ ///@{ // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; /** type for length of a sequence **/ using size_type = std::size_t; /** facet for types with GC support **/ @@ -44,7 +46,7 @@ public: ///@{ // const methods /** RTTI: unique id# for actual runtime data representation **/ - virtual int32_t _typeseq() const noexcept = 0; + virtual typeseq _typeseq() const noexcept = 0; /** true iff sequence is empty **/ virtual bool is_empty(Copaque data) const noexcept = 0; /** true iff sequence is finite **/ @@ -72,4 +74,4 @@ using ISequence_ImplType = xo::facet::FacetImplType; } /*namespace scm*/ } /*namespace xo*/ -/* */ \ No newline at end of file +/* */ diff --git a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp index 18a5a616..4a679b6c 100644 --- a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp +++ b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp @@ -38,7 +38,7 @@ namespace scm { // from ASequence // const methods - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _typeseq() const noexcept override { return s_typeseq; } bool is_empty(Copaque data) const noexcept override { return I::is_empty(_dcast(data)); } @@ -61,7 +61,7 @@ namespace scm { ///@{ /** typeseq for template parameter DRepr **/ - static int32_t s_typeseq; + static typeseq s_typeseq; /** true iff satisfies facet implementation **/ static bool _valid; @@ -69,7 +69,7 @@ namespace scm { }; template - int32_t + xo::facet::typeseq ISequence_Xfer::s_typeseq = xo::facet::typeseq::id(); @@ -82,4 +82,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo*/ -/* end ISequence_Xfer.hpp */ \ No newline at end of file +/* end ISequence_Xfer.hpp */ diff --git a/xo-object2/src/object2/ISequence_Any.cpp b/xo-object2/src/object2/ISequence_Any.cpp index 9eabc9c4..a7781e97 100644 --- a/xo-object2/src/object2/ISequence_Any.cpp +++ b/xo-object2/src/object2/ISequence_Any.cpp @@ -25,7 +25,7 @@ ISequence_Any::_fatal() std::terminate(); } -int32_t +typeseq ISequence_Any::s_typeseq = typeseq::id(); bool