xo-facet: typeseq strongly typed
This commit is contained in:
parent
afc44e71fa
commit
fb14fcad15
31 changed files with 151 additions and 72 deletions
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "AllocInfo.hpp"
|
||||
#include "cmpresult.hpp"
|
||||
#include "typeseq.hpp"
|
||||
#include <xo/facet/obj.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -22,11 +23,12 @@ namespace xo {
|
|||
**/
|
||||
struct AAllocIterator {
|
||||
using obj_AAllocIterator = xo::facet::obj<AAllocIterator>;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "AllocInfo.hpp"
|
||||
//#include "AllocIterator.hpp"
|
||||
#include "AllocRange.hpp"
|
||||
#include "typeseq.hpp"
|
||||
#include <xo/facet/obj.hpp>
|
||||
#include <xo/facet/facet_implementation.hpp>
|
||||
#include <xo/facet/typeseq.hpp>
|
||||
|
|
@ -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.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 <typename DRepr, typename IAllocIterator_DRepr>
|
||||
int32_t
|
||||
xo::facet::typeseq
|
||||
IAllocIterator_Xfer<DRepr, IAllocIterator_DRepr>::s_typeseq
|
||||
= facet::typeseq::id<DRepr>();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "AAllocator.hpp"
|
||||
#include "AllocIterator.hpp"
|
||||
#include "typeseq.hpp"
|
||||
#include <xo/facet/obj.hpp>
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <typename DRepr, typename IAllocator_DRepr>
|
||||
int32_t
|
||||
xo::facet::typeseq
|
||||
IAllocator_Xfer<DRepr, IAllocator_DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr, typename IAllocator_DRepr>
|
||||
|
|
|
|||
|
|
@ -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<AAllocIterator> & other) const noexcept {
|
||||
return O::iface()->compare(O::data(), other); }
|
||||
|
|
|
|||
|
|
@ -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()); }
|
||||
|
|
|
|||
|
|
@ -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 :)
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace xo {
|
|||
std::terminate();
|
||||
}
|
||||
|
||||
int32_t
|
||||
typeseq
|
||||
IAllocIterator_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace xo {
|
|||
std::terminate();
|
||||
}
|
||||
|
||||
int32_t
|
||||
typeseq
|
||||
IAllocator_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -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<std::int32_t>; },
|
||||
{ facet._typeseq().seqno() } -> std::convertible_to<std::int32_t>; },
|
||||
"Abstract facet must provide a _typeseq() method for safe downcasting");
|
||||
return true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -15,6 +16,8 @@ namespace xo {
|
|||
*/
|
||||
template<typename Tag = class typeseq_tag>
|
||||
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 <typename T>
|
||||
static int32_t id() {
|
||||
static typeseq_impl<Tag> 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 <typename Tag>
|
||||
int32_t typeseq_impl<Tag>::s_next_id = 0;
|
||||
|
||||
template <typename Tag>
|
||||
inline bool
|
||||
operator==(const typeseq_impl<Tag> & lhs, const typeseq_impl<Tag> & rhs) {
|
||||
return lhs.seqno() == rhs.seqno();
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
inline bool
|
||||
operator!=(const typeseq_impl<Tag> & lhs, const typeseq_impl<Tag> & rhs) {
|
||||
return lhs.seqno() != rhs.seqno();
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream & s, const typeseq_impl<Tag> & x) {
|
||||
s << x.seqno();
|
||||
return s;
|
||||
}
|
||||
|
||||
using typeseq = typeseq_impl<>;
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -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 <typename DRepr>
|
||||
int32_t
|
||||
typeseq
|
||||
IComplex_Xfer<DRepr>::s_typeseq = typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr>
|
||||
|
|
@ -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<DVariantPlaceholder>();
|
||||
|
||||
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()); }
|
||||
|
|
|
|||
|
|
@ -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<DFoo,AGCObject_DFoo> 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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "ACollector.hpp"
|
||||
#include "AGCObject.hpp"
|
||||
//#include <cassert>
|
||||
|
||||
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*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <typename DRepr, typename ICollector_DRepr>
|
||||
int32_t
|
||||
xo::facet::typeseq
|
||||
ICollector_Xfer<DRepr, ICollector_DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr, typename ICollector_DRepr>
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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 <typename DRepr, typename IGCObject_DRepr>
|
||||
int32_t
|
||||
xo::facet::typeseq
|
||||
IGCObject_Xfer<DRepr, IGCObject_DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr, typename IGCObject_DRepr>
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -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<AAllocator> mm) const noexcept { O::iface()->shallow_copy(O::data(), mm); }
|
||||
size_type forward_children() noexcept { O::iface()->forward_children(O::data()); }
|
||||
|
|
|
|||
|
|
@ -13,9 +13,12 @@
|
|||
#include <xo/indentlog/scope.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h> // 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<AGCObject *>(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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace xo {
|
|||
std::terminate();
|
||||
}
|
||||
|
||||
int32_t
|
||||
typeseq
|
||||
ICollector_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace xo {
|
|||
std::terminate();
|
||||
}
|
||||
|
||||
int32_t
|
||||
typeseq
|
||||
IGCObject_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -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<ASequence, DRepr>;
|
|||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* */
|
||||
/* */
|
||||
|
|
|
|||
|
|
@ -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 <typename DRepr, typename ISequence_DRepr>
|
||||
int32_t
|
||||
xo::facet::typeseq
|
||||
ISequence_Xfer<DRepr, ISequence_DRepr>::s_typeseq
|
||||
= xo::facet::typeseq::id<DRepr>();
|
||||
|
||||
|
|
@ -82,4 +82,4 @@ namespace scm {
|
|||
} /*namespace scm */
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end ISequence_Xfer.hpp */
|
||||
/* end ISequence_Xfer.hpp */
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ ISequence_Any::_fatal()
|
|||
std::terminate();
|
||||
}
|
||||
|
||||
int32_t
|
||||
typeseq
|
||||
ISequence_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
|
||||
|
||||
bool
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue