diff --git a/include/xo/arena/AllocHeaderConfig.hpp b/include/xo/arena/AllocHeaderConfig.hpp index ab56088..d2b6db9 100644 --- a/include/xo/arena/AllocHeaderConfig.hpp +++ b/include/xo/arena/AllocHeaderConfig.hpp @@ -11,7 +11,9 @@ namespace xo { namespace mm { - /* + /** + * @brief specifies alloc header layout + * * Each allocation is preceded by a 64-bit header. * Header is split into 3 configurable-width bit fields, * labelled (from hi to lo bit order) {tseq, age, size}. @@ -36,7 +38,7 @@ namespace xo { * 0..............01111111 gen_mask_unshifted * 0..011111110..........0 gen_mask_shifted * > < gen_shift - */ + **/ struct AllocHeaderConfig { using repr_type = AllocHeader; using span_type = std::pair; diff --git a/include/xo/arena/DArena.hpp b/include/xo/arena/DArena.hpp index 83ebd9c..73ca67d 100644 --- a/include/xo/arena/DArena.hpp +++ b/include/xo/arena/DArena.hpp @@ -103,6 +103,9 @@ namespace xo { /** @defgroup mm-arena-methods **/ ///@{ + /** false -> not eligible for GC (allocates own memory + not moveable) **/ + static constexpr bool is_gc_eligible() { return false; } + /** Reserved memory, in bytes. This is the maximum size of this arena. **/ size_type reserved() const noexcept { return hi_ - lo_; } /** Allocated memory in bytes: memory consumed by allocs from this arena, @@ -125,6 +128,9 @@ namespace xo { **/ bool contains(const void * addr) const noexcept { return (lo_ <= addr) && (addr < hi_); } + /** Truee iff address @p addr is owned by this arena and in allocated regions **/ + bool contains_allocated(const void * addr) const noexcept { return (lo_ <= addr) && (addr < free_); } + /** true if arena is mapped i.e. has a reserved address range **/ bool is_mapped() const noexcept { return (lo_ != nullptr) && (hi_ != nullptr); } @@ -147,6 +153,8 @@ namespace xo { /** get header from allocated object address **/ header_type * obj2hdr(void * obj) noexcept; + /** get header from allocated object address (const version) **/ + const header_type * obj2hdr(void * obj) const noexcept; /** report alloc book-keeping info for allocation at @p mem * diff --git a/include/xo/arena/DArenaHashMap.hpp b/include/xo/arena/DArenaHashMap.hpp index 50e6669..c97f7ba 100644 --- a/include/xo/arena/DArenaHashMap.hpp +++ b/include/xo/arena/DArenaHashMap.hpp @@ -68,6 +68,9 @@ namespace xo { size_type hint_max_capacity = 0, bool debug_flag = false); + /** true for types that support the AGCObject facet; DArenaHashMap gets its own memory! **/ + static constexpr bool is_gc_eligible() { return false; } + size_type empty() const noexcept { return store_.empty(); } size_type groups() const noexcept { return store_.n_group_; } size_type size() const noexcept { return store_.size_; } diff --git a/include/xo/arena/DArenaVector.hpp b/include/xo/arena/DArenaVector.hpp index 79653fe..0ac5d68 100644 --- a/include/xo/arena/DArenaVector.hpp +++ b/include/xo/arena/DArenaVector.hpp @@ -76,6 +76,7 @@ namespace xo { const_iterator cend() const noexcept { return this->_address_of(size_); } const_iterator end() const noexcept { return this->cend(); } + constexpr const DArena * store() const { return &store_; } constexpr T * data() { return reinterpret_cast(store_.lo_); } constexpr const T * data() const { return reinterpret_cast(store_.lo_); } @@ -223,7 +224,7 @@ namespace xo { // store_.restore(zero_ckp_); store_.alloc(xo::reflect::typeseq::id(), req_z); - + this->size_ = z; } diff --git a/src/arena/DArena.cpp b/src/arena/DArena.cpp index 2cd36dc..e5bbb11 100644 --- a/src/arena/DArena.cpp +++ b/src/arena/DArena.cpp @@ -170,8 +170,17 @@ namespace xo { return (header_type *)((byte *)obj - sizeof(header_type)); } + auto + DArena::obj2hdr(void * obj) const noexcept -> const header_type * + { + assert(config_.store_header_flag_); + + return (const header_type *)((byte *)obj - sizeof(header_type)); + } + void - DArena::visit_pools(const MemorySizeVisitor & fn) const { + DArena::visit_pools(const MemorySizeVisitor & fn) const + { /** arena can't tell purpose of allocated memory; * must assume it's all used **/