xo-interpreter2 .. xo-arena. memory pool introspection
This commit is contained in:
parent
f6aae4190e
commit
c931fca242
32 changed files with 157 additions and 172 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <xo/arena/MemorySizeInfo.hpp>
|
||||||
#include <xo/arena/AllocError.hpp>
|
#include <xo/arena/AllocError.hpp>
|
||||||
#include "AllocInfo.hpp"
|
#include "AllocInfo.hpp"
|
||||||
//#include "AllocIterator.hpp"
|
//#include "AllocIterator.hpp"
|
||||||
|
|
@ -33,9 +34,11 @@ namespace xo {
|
||||||
struct AAllocator {
|
struct AAllocator {
|
||||||
/** @defgroup mm-allocator-type-traits allocator type traits **/
|
/** @defgroup mm-allocator-type-traits allocator type traits **/
|
||||||
///@{
|
///@{
|
||||||
/** @brief type used for allocation amounts **/
|
/** memory size report **/
|
||||||
|
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
||||||
|
/** type used for allocation amounts **/
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
/** @brief type used for allocation responses **/
|
/** type used for allocation responses **/
|
||||||
using value_type = std::byte *;
|
using value_type = std::byte *;
|
||||||
/** object header, if configured **/
|
/** object header, if configured **/
|
||||||
using header_type = std::uint64_t;
|
using header_type = std::uint64_t;
|
||||||
|
|
@ -95,6 +98,12 @@ namespace xo {
|
||||||
* Includes alloc headers and guard regions
|
* Includes alloc headers and guard regions
|
||||||
**/
|
**/
|
||||||
virtual size_type allocated(Copaque d) const noexcept = 0;
|
virtual size_type allocated(Copaque d) const noexcept = 0;
|
||||||
|
/** call @p fn(i,n,info) for each memory pool owned by this allocator.
|
||||||
|
* Note: using std::function instead of obj<> to avoid leveling trouble
|
||||||
|
* with DArena
|
||||||
|
**/
|
||||||
|
virtual void visit_pools(Copaque d,
|
||||||
|
const MemorySizeVisitor & fn) const = 0;
|
||||||
/** true iff allocator @p d is responsible for memory at address @p p.
|
/** true iff allocator @p d is responsible for memory at address @p p.
|
||||||
**/
|
**/
|
||||||
virtual bool contains(Copaque d, const void * p) const noexcept = 0;
|
virtual bool contains(Copaque d, const void * p) const noexcept = 0;
|
||||||
|
|
@ -146,12 +155,6 @@ namespace xo {
|
||||||
virtual value_type alloc_copy(Opaque d, value_type src) const = 0;
|
virtual value_type alloc_copy(Opaque d, value_type src) const = 0;
|
||||||
/** reset allocator @p d to empty state. **/
|
/** reset allocator @p d to empty state. **/
|
||||||
virtual void clear(Opaque d) const = 0;
|
virtual void clear(Opaque d) const = 0;
|
||||||
#ifdef OBSOLETE
|
|
||||||
/** Destruct allocator @p d.
|
|
||||||
* Releases allocator memory to operating system.
|
|
||||||
**/
|
|
||||||
virtual void destruct_data(Opaque d) const = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
}; /*AAllocator*/
|
}; /*AAllocator*/
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ namespace xo {
|
||||||
[[noreturn]] size_type available(Copaque) const noexcept override { _fatal(); }
|
[[noreturn]] size_type available(Copaque) const noexcept override { _fatal(); }
|
||||||
[[noreturn]] size_type allocated(Copaque) const noexcept override { _fatal(); }
|
[[noreturn]] size_type allocated(Copaque) const noexcept override { _fatal(); }
|
||||||
[[noreturn]] bool contains(Copaque, const void *) const noexcept override { _fatal(); }
|
[[noreturn]] bool contains(Copaque, const void *) const noexcept override { _fatal(); }
|
||||||
|
[[noreturn]] void visit_pools(Copaque,
|
||||||
|
const MemorySizeVisitor &) const override { _fatal(); }
|
||||||
[[noreturn]] AllocError last_error(Copaque) const noexcept override { _fatal(); }
|
[[noreturn]] AllocError last_error(Copaque) const noexcept override { _fatal(); }
|
||||||
[[noreturn]] AllocInfo alloc_info(Copaque, value_type) const noexcept override { _fatal(); }
|
[[noreturn]] AllocInfo alloc_info(Copaque, value_type) const noexcept override { _fatal(); }
|
||||||
// defn in .cpp - problematic to require compiler know vt<AAllocIterator> defn here
|
// defn in .cpp - problematic to require compiler know vt<AAllocIterator> defn here
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ namespace xo {
|
||||||
typeseq _typeseq() const noexcept override { return s_typeseq; }
|
typeseq _typeseq() const noexcept override { return s_typeseq; }
|
||||||
/** invoke native c++ dtor **/
|
/** invoke native c++ dtor **/
|
||||||
void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); }
|
void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); }
|
||||||
|
|
||||||
// const methods
|
// const methods
|
||||||
|
|
||||||
std::string_view name(Copaque d) const noexcept override { return I::name(_dcast(d)); }
|
std::string_view name(Copaque d) const noexcept override { return I::name(_dcast(d)); }
|
||||||
|
|
@ -53,6 +53,7 @@ namespace xo {
|
||||||
bool contains(Copaque d, const void * p) const noexcept override {
|
bool contains(Copaque d, const void * p) const noexcept override {
|
||||||
return I::contains(_dcast(d), p);
|
return I::contains(_dcast(d), p);
|
||||||
}
|
}
|
||||||
|
void visit_pools(Copaque d, const MemorySizeVisitor & fn) const override { I::visit_pools(_dcast(d), fn); }
|
||||||
AllocError last_error(Copaque d) const noexcept override { return I::last_error(_dcast(d)); }
|
AllocError last_error(Copaque d) const noexcept override { return I::last_error(_dcast(d)); }
|
||||||
AllocInfo alloc_info(Copaque d, value_type mem) const noexcept override {
|
AllocInfo alloc_info(Copaque d, value_type mem) const noexcept override {
|
||||||
return I::alloc_info(_dcast(d), mem);
|
return I::alloc_info(_dcast(d), mem);
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ namespace xo {
|
||||||
size_type committed() const noexcept { return O::iface()->committed(O::data()); }
|
size_type committed() const noexcept { return O::iface()->committed(O::data()); }
|
||||||
size_type available() const noexcept { return O::iface()->available(O::data()); }
|
size_type available() const noexcept { return O::iface()->available(O::data()); }
|
||||||
size_type allocated() const noexcept { return O::iface()->allocated(O::data()); }
|
size_type allocated() const noexcept { return O::iface()->allocated(O::data()); }
|
||||||
|
void visit_pools(const MemorySizeVisitor & fn) const { O::iface()->visit_pools(O::data(), fn); }
|
||||||
bool contains(const void * p) const noexcept { return O::iface()->contains(O::data(), p); }
|
bool contains(const void * p) const noexcept { return O::iface()->contains(O::data(), p); }
|
||||||
AllocError last_error() const noexcept { return O::iface()->last_error(O::data()); }
|
AllocError last_error() const noexcept { return O::iface()->last_error(O::data()); }
|
||||||
AllocInfo alloc_info(value_type mem) const noexcept { return O::iface()->alloc_info(O::data(), mem); }
|
AllocInfo alloc_info(value_type mem) const noexcept { return O::iface()->alloc_info(O::data(), mem); }
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ namespace xo {
|
||||||
static size_type committed(const DArena &) noexcept;
|
static size_type committed(const DArena &) noexcept;
|
||||||
static size_type available(const DArena &) noexcept;
|
static size_type available(const DArena &) noexcept;
|
||||||
static size_type allocated(const DArena &) noexcept;
|
static size_type allocated(const DArena &) noexcept;
|
||||||
|
static void visit_pools(const DArena &,
|
||||||
|
const MemorySizeVisitor & visitor);
|
||||||
static bool contains(const DArena &, const void * p) noexcept;
|
static bool contains(const DArena &, const void * p) noexcept;
|
||||||
static AllocError last_error(const DArena &) noexcept;
|
static AllocError last_error(const DArena &) noexcept;
|
||||||
/** retrieve allocation bookkeeping info for @p mem from arena @p d **/
|
/** retrieve allocation bookkeeping info for @p mem from arena @p d **/
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,13 @@ namespace xo {
|
||||||
return s.allocated();
|
return s.allocated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IAllocator_DArena::visit_pools(const DArena & s,
|
||||||
|
const MemorySizeVisitor & visitor)
|
||||||
|
{
|
||||||
|
s.visit_pools(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IAllocator_DArena::contains(const DArena & s,
|
IAllocator_DArena::contains(const DArena & s,
|
||||||
const void * p) noexcept
|
const void * p) noexcept
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ namespace xo {
|
||||||
struct ArenaConfig {
|
struct ArenaConfig {
|
||||||
/** @defgroup mm-arenaconfig-ctors **/
|
/** @defgroup mm-arenaconfig-ctors **/
|
||||||
|
|
||||||
ArenaConfig with_name(std::string name) {
|
ArenaConfig with_name(std::string name) const {
|
||||||
ArenaConfig copy(*this);
|
ArenaConfig copy(*this);
|
||||||
copy.name_ = name;
|
copy.name_ = name;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArenaConfig with_size(std::size_t z) {
|
ArenaConfig with_size(std::size_t z) const {
|
||||||
ArenaConfig copy(*this);
|
ArenaConfig copy(*this);
|
||||||
copy.size_ = z;
|
copy.size_ = z;
|
||||||
return copy;
|
return copy;
|
||||||
|
|
|
||||||
|
|
@ -138,12 +138,14 @@ namespace xo {
|
||||||
**/
|
**/
|
||||||
AllocHeader * end_header() const noexcept;
|
AllocHeader * end_header() const noexcept;
|
||||||
|
|
||||||
|
/** report memory use for this arena to @p fn.
|
||||||
|
* For DArena reporting just one pool = arena's memory range
|
||||||
|
**/
|
||||||
|
void visit_pools(const MemorySizeVisitor & fn) const;
|
||||||
|
|
||||||
/** get header from allocated object address **/
|
/** get header from allocated object address **/
|
||||||
header_type * obj2hdr(void * obj) noexcept;
|
header_type * obj2hdr(void * obj) noexcept;
|
||||||
|
|
||||||
/** resource ocnsumption in normal form **/
|
|
||||||
MemorySizeInfo _store_info() const noexcept;
|
|
||||||
|
|
||||||
/** report alloc book-keeping info for allocation at @p mem
|
/** report alloc book-keeping info for allocation at @p mem
|
||||||
*
|
*
|
||||||
* Require:
|
* Require:
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ namespace xo {
|
||||||
using value_type = std::pair<const Key, Value>;
|
using value_type = std::pair<const Key, Value>;
|
||||||
using key_hash = Hash;
|
using key_hash = Hash;
|
||||||
using key_equal = Equal;
|
using key_equal = Equal;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
using byte = std::byte;
|
using byte = std::byte;
|
||||||
using group_type = detail::ControlGroup;
|
using group_type = detail::ControlGroup;
|
||||||
using store_type = detail::HashMapStore<Key, Value>;
|
using store_type = detail::HashMapStore<Key, Value>;
|
||||||
|
|
@ -77,9 +77,8 @@ namespace xo {
|
||||||
iterator begin() { return _promote_iterator(_begin_aux()); }
|
iterator begin() { return _promote_iterator(_begin_aux()); }
|
||||||
iterator end() { return _promote_iterator(_end_aux()); }
|
iterator end() { return _promote_iterator(_end_aux()); }
|
||||||
|
|
||||||
std::size_t _n_store() const noexcept { return store_._n_store(); }
|
void visit_pools(const MemorySizeVisitor & visitor) const {
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept {
|
return store_.visit_pools(visitor);
|
||||||
return store_._store_info(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** insert @p kv_pair into hash map.
|
/** insert @p kv_pair into hash map.
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ namespace xo {
|
||||||
/** arena used for element storage
|
/** arena used for element storage
|
||||||
* (Might prefer obj<AResourceVisitor> here; refrain to avoid leveling violation)
|
* (Might prefer obj<AResourceVisitor> here; refrain to avoid leveling violation)
|
||||||
**/
|
**/
|
||||||
MemorySizeInfo _store_info() const { return store_._store_info(); }
|
void visit_pools(const MemorySizeVisitor & fn) const { store_.visit_pools(fn); }
|
||||||
|
|
||||||
/** reserve space, if possible, for at least @p z elements.
|
/** reserve space, if possible, for at least @p z elements.
|
||||||
* Always limited by ArenaConfig.size_
|
* Always limited by ArenaConfig.size_
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,8 @@ namespace xo {
|
||||||
const_span_type occupied_range() const noexcept { return occupied_range_; }
|
const_span_type occupied_range() const noexcept { return occupied_range_; }
|
||||||
const_span_type input_range() const noexcept { return input_range_; }
|
const_span_type input_range() const noexcept { return input_range_; }
|
||||||
|
|
||||||
std::size_t _n_store() const noexcept;
|
/** report memory-size info for this buffer to @p fn **/
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
void visit_pools(const MemorySizeVisitor & fn) const;
|
||||||
|
|
||||||
/** verify DCircularBuffer invariants.
|
/** verify DCircularBuffer invariants.
|
||||||
* Act on failure according to policy @p p
|
* Act on failure according to policy @p p
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <string_view>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
namespace mm {
|
namespace mm {
|
||||||
|
|
@ -31,7 +32,12 @@ namespace xo {
|
||||||
std::size_t reserved_ = 0;
|
std::size_t reserved_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
/** function that visits MemorySizeInfo for a collection of @p n memory pools.
|
||||||
|
* Each pool reported with index @p i in [0, n), with associated
|
||||||
|
* size record @p info.
|
||||||
|
**/
|
||||||
|
using MemorySizeVisitor = std::function<void (const MemorySizeInfo & info)>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end MemorySizeInfo.hpp */
|
/* end MemorySizeInfo.hpp */
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace xo {
|
||||||
using group_type = detail::ControlGroup;
|
using group_type = detail::ControlGroup;
|
||||||
using control_vector_type = xo::mm::DArenaVector<uint8_t>;
|
using control_vector_type = xo::mm::DArenaVector<uint8_t>;
|
||||||
using slot_vector_type = xo::mm::DArenaVector<value_type>;
|
using slot_vector_type = xo::mm::DArenaVector<value_type>;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** group_exp2: number of groups {x, 2^x} **/
|
/** group_exp2: number of groups {x, 2^x} **/
|
||||||
|
|
@ -48,16 +48,9 @@ namespace xo {
|
||||||
size_type capacity() const noexcept { return n_group_ * c_group_size; }
|
size_type capacity() const noexcept { return n_group_ * c_group_size; }
|
||||||
float load_factor() const noexcept { return size_ / static_cast<float>(n_slot_); }
|
float load_factor() const noexcept { return size_ / static_cast<float>(n_slot_); }
|
||||||
|
|
||||||
std::size_t _n_store() const noexcept { return 2; }
|
void visit_pools(const MemorySizeVisitor & visitor) const {
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept {
|
control_.visit_pools(visitor);
|
||||||
switch (i) {
|
slots_.visit_pools(visitor);
|
||||||
case 0:
|
|
||||||
return control_._store_info();
|
|
||||||
case 1:
|
|
||||||
return slots_._store_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
return MemorySizeInfo::sentinel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize_from_empty(const std::pair<size_type,
|
void resize_from_empty(const std::pair<size_type,
|
||||||
|
|
|
||||||
|
|
@ -165,13 +165,12 @@ namespace xo {
|
||||||
return (header_type *)((byte *)obj - sizeof(header_type));
|
return (header_type *)((byte *)obj - sizeof(header_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
MemorySizeInfo
|
void
|
||||||
DArena::_store_info() const noexcept
|
DArena::visit_pools(const MemorySizeVisitor & fn) const {
|
||||||
{
|
fn(MemorySizeInfo(config_.name_,
|
||||||
return MemorySizeInfo(config_.name_,
|
this->allocated(),
|
||||||
this->allocated(),
|
this->committed(),
|
||||||
this->committed(),
|
this->reserved()));
|
||||||
this->reserved());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocInfo
|
AllocInfo
|
||||||
|
|
|
||||||
|
|
@ -79,30 +79,16 @@ namespace xo {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
void
|
||||||
DCircularBuffer::_n_store() const noexcept
|
DCircularBuffer::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
{
|
{
|
||||||
return 2;
|
visitor(MemorySizeInfo(config_.name_,
|
||||||
}
|
occupied_range_.size(),
|
||||||
|
mapped_range_.size(),
|
||||||
|
reserved_range_.size()));
|
||||||
|
|
||||||
MemorySizeInfo
|
pinned_spans_.visit_pools(visitor);
|
||||||
DCircularBuffer::_store_info(std::size_t i) const noexcept
|
|
||||||
{
|
|
||||||
switch (i) {
|
|
||||||
case 0:
|
|
||||||
return MemorySizeInfo(config_.name_,
|
|
||||||
occupied_range_.size(),
|
|
||||||
mapped_range_.size(),
|
|
||||||
reserved_range_.size());
|
|
||||||
case 1:
|
|
||||||
return pinned_spans_._store_info();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MemorySizeInfo::sentinel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DCircularBuffer::verify_ok(verify_policy policy) const
|
DCircularBuffer::verify_ok(verify_policy policy) const
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace xo {
|
||||||
class StringTable {
|
class StringTable {
|
||||||
public:
|
public:
|
||||||
using DArena = xo::mm::DArena;
|
using DArena = xo::mm::DArena;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
using StringMap = xo::map::DArenaHashMap<std::string_view,
|
using StringMap = xo::map::DArenaHashMap<std::string_view,
|
||||||
DUniqueString*>;
|
DUniqueString*>;
|
||||||
using size_type = StringMap::size_type;
|
using size_type = StringMap::size_type;
|
||||||
|
|
@ -46,8 +46,8 @@ namespace xo {
|
||||||
**/
|
**/
|
||||||
bool verify_ok(verify_policy p = verify_policy::throw_only()) const;
|
bool verify_ok(verify_policy p = verify_policy::throw_only()) const;
|
||||||
|
|
||||||
std::size_t _n_store() const noexcept;
|
/** visit string-table memory pools, call visitor(info) for each **/
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** allocate string storage in this arena; use DString to represent each string.
|
/** allocate string storage in this arena; use DString to represent each string.
|
||||||
|
|
|
||||||
|
|
@ -160,22 +160,11 @@ namespace xo {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
void
|
||||||
StringTable::_n_store() const noexcept
|
StringTable::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
{
|
{
|
||||||
return 1 + map_._n_store();
|
strings_.visit_pools(visitor);
|
||||||
}
|
map_.visit_pools(visitor);
|
||||||
|
|
||||||
MemorySizeInfo
|
|
||||||
StringTable::_store_info(std::size_t i) const noexcept
|
|
||||||
{
|
|
||||||
if (i == 0)
|
|
||||||
return strings_._store_info();
|
|
||||||
|
|
||||||
if (i+1 < map_._n_store())
|
|
||||||
return map_._store_info(i-1);
|
|
||||||
|
|
||||||
return MemorySizeInfo::sentinel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /*namespace scm*/
|
} /*namespace scm*/
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ namespace xo {
|
||||||
/** faceted object pointer to this instance */
|
/** faceted object pointer to this instance */
|
||||||
template <typename AFacet = AAllocator>
|
template <typename AFacet = AAllocator>
|
||||||
obj<AFacet,DX1Collector> ref() { return obj<AFacet,DX1Collector>(this); }
|
obj<AFacet,DX1Collector> ref() { return obj<AFacet,DX1Collector>(this); }
|
||||||
|
|
||||||
#ifdef NOT_YET
|
#ifdef NOT_YET
|
||||||
/** create instance with default configuration,
|
/** create instance with default configuration,
|
||||||
* generation size @p gen_z
|
* generation size @p gen_z
|
||||||
|
|
@ -110,6 +110,11 @@ namespace xo {
|
||||||
/** total allocated memory in bytes, across all {role, generation} **/
|
/** total allocated memory in bytes, across all {role, generation} **/
|
||||||
size_type allocated_total() const noexcept;
|
size_type allocated_total() const noexcept;
|
||||||
|
|
||||||
|
/** introspection for memory use.
|
||||||
|
* Call @p visitor(info) for each pool owned by this allocator
|
||||||
|
**/
|
||||||
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
|
|
||||||
/** true iff address @p addr allocated from this collector
|
/** true iff address @p addr allocated from this collector
|
||||||
* in role @p r (according to current GC state)
|
* in role @p r (according to current GC state)
|
||||||
**/
|
**/
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ namespace xo {
|
||||||
static size_type available(const DX1Collector &) noexcept;
|
static size_type available(const DX1Collector &) noexcept;
|
||||||
/** space used by @p d across all {roles, generations}. **/
|
/** space used by @p d across all {roles, generations}. **/
|
||||||
static size_type allocated(const DX1Collector &) noexcept;
|
static size_type allocated(const DX1Collector &) noexcept;
|
||||||
|
/** visit memory pools owned by this allocator; call fn(info) for each pool **/
|
||||||
|
static void visit_pools(const DX1Collector & d, const MemorySizeVisitor & fn);
|
||||||
/** true iff address @p p comes from collector @p d **/
|
/** true iff address @p p comes from collector @p d **/
|
||||||
static bool contains(const DX1Collector & d, const void * p) noexcept;
|
static bool contains(const DX1Collector & d, const void * p) noexcept;
|
||||||
/** report last error, if any, for collector @p d **/
|
/** report last error, if any, for collector @p d **/
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,18 @@ namespace xo {
|
||||||
.store_header_flag_ = false});
|
.store_header_flag_ = false});
|
||||||
|
|
||||||
for (uint32_t igen = 0, ngen = cfg.n_generation_; igen < ngen; ++igen) {
|
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_);
|
char buf[40];
|
||||||
|
snprintf(buf, sizeof(buf), "x1-space-G%u-a", igen);
|
||||||
|
|
||||||
|
space_storage_[0][igen] = DArena::map(cfg.arena_config_.with_name(std::string(buf)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
char buf[40];
|
||||||
|
snprintf(buf, sizeof(buf), "x1-space-G%u-b", igen);
|
||||||
|
|
||||||
|
space_storage_[1][igen] = DArena::map(cfg.arena_config_.with_name(std::string(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
space_[role::to_space()][igen] = &space_storage_[0][igen];
|
space_[role::to_space()][igen] = &space_storage_[0][igen];
|
||||||
space_[role::from_space()][igen] = &space_storage_[1][igen];
|
space_[role::from_space()][igen] = &space_storage_[1][igen];
|
||||||
|
|
@ -109,6 +119,19 @@ namespace xo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DX1Collector::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
|
{
|
||||||
|
object_types_.visit_pools(visitor);
|
||||||
|
roots_.visit_pools(visitor);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < c_n_role; ++i) {
|
||||||
|
for (uint32_t j = 0; j < config_.n_generation_; ++j) {
|
||||||
|
space_storage_[i][j].visit_pools(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DX1Collector::contains(role r, const void * addr) const noexcept
|
DX1Collector::contains(role r, const void * addr) const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,12 @@ namespace xo {
|
||||||
return d.allocated_total();
|
return d.allocated_total();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IAllocator_DX1Collector::visit_pools(const DX1Collector & d, const MemorySizeVisitor & visitor)
|
||||||
|
{
|
||||||
|
d.visit_pools(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IAllocator_DX1Collector::contains(const DX1Collector & d, const void * addr) noexcept
|
IAllocator_DX1Collector::contains(const DX1Collector & d, const void * addr) noexcept
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -61,14 +61,14 @@ namespace xo {
|
||||||
using Stack = void *;
|
using Stack = void *;
|
||||||
using AAllocator = xo::mm::AAllocator;
|
using AAllocator = xo::mm::AAllocator;
|
||||||
using AGCObject = xo::mm::AGCObject;
|
using AGCObject = xo::mm::AGCObject;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
using span_type = xo::mm::span<const char>;
|
using span_type = xo::mm::span<const char>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VirtualSchematikaMachine(const VsmConfig & config);
|
VirtualSchematikaMachine(const VsmConfig & config);
|
||||||
|
|
||||||
size_t _n_store() const noexcept;
|
/** visit vsm-owned memory pools; call visitor(info) for each **/
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
|
|
||||||
/** begin interactive session. **/
|
/** begin interactive session. **/
|
||||||
void begin_interactive_session();
|
void begin_interactive_session();
|
||||||
|
|
|
||||||
|
|
@ -30,20 +30,11 @@ namespace xo {
|
||||||
reader_{config.rdr_config_, mm_.to_op()}
|
reader_{config.rdr_config_, mm_.to_op()}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::size_t
|
void
|
||||||
VirtualSchematikaMachine::_n_store() const noexcept
|
VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
{
|
{
|
||||||
// oops. need something that goes through AAllocator api
|
mm_.visit_pools(visitor);
|
||||||
|
reader_.visit_pools(visitor);
|
||||||
return reader_._n_store();
|
|
||||||
}
|
|
||||||
|
|
||||||
MemorySizeInfo
|
|
||||||
VirtualSchematikaMachine::_store_info(std::size_t i) const noexcept
|
|
||||||
{
|
|
||||||
// oops. need something poly that goes through AAllocator api
|
|
||||||
|
|
||||||
return reader_._store_info(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ namespace xo {
|
||||||
using xo::scm::VsmResultExt;
|
using xo::scm::VsmResultExt;
|
||||||
using xo::scm::DFloat;
|
using xo::scm::DFloat;
|
||||||
using xo::mm::AGCObject;
|
using xo::mm::AGCObject;
|
||||||
|
using xo::mm::MemorySizeInfo;
|
||||||
using span_type = xo::scm::VirtualSchematikaMachine::span_type;
|
using span_type = xo::scm::VirtualSchematikaMachine::span_type;
|
||||||
using Catch::Matchers::WithinAbs;
|
using Catch::Matchers::WithinAbs;
|
||||||
|
|
||||||
|
|
@ -55,6 +56,8 @@ namespace xo {
|
||||||
namespace ut {
|
namespace ut {
|
||||||
TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]")
|
TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]")
|
||||||
{
|
{
|
||||||
|
scope log(XO_DEBUG(true));
|
||||||
|
|
||||||
VsmConfig cfg;
|
VsmConfig cfg;
|
||||||
VirtualSchematikaMachine vsm(cfg);
|
VirtualSchematikaMachine vsm(cfg);
|
||||||
|
|
||||||
|
|
@ -73,6 +76,15 @@ namespace xo {
|
||||||
|
|
||||||
REQUIRE(res.remaining_.size() == 1);
|
REQUIRE(res.remaining_.size() == 1);
|
||||||
REQUIRE(*res.remaining_.lo() == '\n');
|
REQUIRE(*res.remaining_.lo() == '\n');
|
||||||
|
|
||||||
|
auto visitor = [&log](const MemorySizeInfo & info) {
|
||||||
|
log && log(xtag("resource", info.resource_name_),
|
||||||
|
xtag("alloc", info.allocated_),
|
||||||
|
xtag("commit", info.committed_),
|
||||||
|
xtag("resv", info.reserved_));
|
||||||
|
};
|
||||||
|
|
||||||
|
vsm.visit_pools(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /*namespace ut*/
|
} /*namespace ut*/
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ namespace xo {
|
||||||
using AAllocator = xo::mm::AAllocator;
|
using AAllocator = xo::mm::AAllocator;
|
||||||
using ArenaConfig = xo::mm::ArenaConfig;
|
using ArenaConfig = xo::mm::ArenaConfig;
|
||||||
using DArena = xo::mm::DArena;
|
using DArena = xo::mm::DArena;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -62,10 +62,8 @@ namespace xo {
|
||||||
/** top of parser stack **/
|
/** top of parser stack **/
|
||||||
obj<ASyntaxStateMachine> top_ssm() const;
|
obj<ASyntaxStateMachine> top_ssm() const;
|
||||||
|
|
||||||
/** number of distinct memory pools owned by PS **/
|
/** visit psm-owned memory pools; call visitor(info) for each **/
|
||||||
std::size_t _n_store() const noexcept;
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
/** memory consumption for i'th memory pool **/
|
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ namespace xo {
|
||||||
using token_type = Token;
|
using token_type = Token;
|
||||||
using ArenaConfig = xo::mm::ArenaConfig;
|
using ArenaConfig = xo::mm::ArenaConfig;
|
||||||
using AAllocator = xo::mm::AAllocator;
|
using AAllocator = xo::mm::AAllocator;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
using ppindentinfo = xo::print::ppindentinfo;
|
using ppindentinfo = xo::print::ppindentinfo;
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
|
|
||||||
|
|
@ -193,10 +193,8 @@ namespace xo {
|
||||||
/** top of parser stack **/
|
/** top of parser stack **/
|
||||||
obj<ASyntaxStateMachine> top_ssm() const;
|
obj<ASyntaxStateMachine> top_ssm() const;
|
||||||
|
|
||||||
/** number of distinct memory pools owned by PS **/
|
/** visit parser-owned memory pools; invoke visitor(info) for each **/
|
||||||
std::size_t _n_store() const noexcept;
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
/** memory consumption for i'th memory pool **/
|
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
/** scm-schematikaparser-general-methods **/
|
/** scm-schematikaparser-general-methods **/
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ namespace xo {
|
||||||
class SchematikaReader {
|
class SchematikaReader {
|
||||||
public:
|
public:
|
||||||
using AAllocator = xo::mm::AAllocator;
|
using AAllocator = xo::mm::AAllocator;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
using span_type = xo::mm::span<const char>;
|
using span_type = xo::mm::span<const char>;
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
|
|
||||||
|
|
@ -44,8 +44,11 @@ namespace xo {
|
||||||
SchematikaReader(const ReaderConfig & config,
|
SchematikaReader(const ReaderConfig & config,
|
||||||
obj<AAllocator> expr_alloc);
|
obj<AAllocator> expr_alloc);
|
||||||
|
|
||||||
std::size_t _n_store() const noexcept;
|
/** visit reader-owned memory pools; call visitor(info) for each.
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
* Specifically exclude expr_alloc, since we don't consider
|
||||||
|
* that reader-owned
|
||||||
|
**/
|
||||||
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
|
|
||||||
/** true iff parser is at top-level.
|
/** true iff parser is at top-level.
|
||||||
* false iff parser is working on incomplete expression
|
* false iff parser is working on incomplete expression
|
||||||
|
|
|
||||||
|
|
@ -54,27 +54,14 @@ namespace xo {
|
||||||
return this->stack_->top();
|
return this->stack_->top();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
void
|
||||||
ParserStateMachine::_n_store() const noexcept
|
ParserStateMachine::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
{
|
{
|
||||||
return stringtable_._n_store() + 1;
|
stringtable_.visit_pools(visitor);
|
||||||
}
|
parser_alloc_.visit_pools(visitor);
|
||||||
|
|
||||||
MemorySizeInfo
|
|
||||||
ParserStateMachine::_store_info(std::size_t i) const noexcept
|
|
||||||
{
|
|
||||||
size_t n0 = stringtable_._n_store();
|
|
||||||
|
|
||||||
if (i < n0)
|
|
||||||
return stringtable_._store_info(i);
|
|
||||||
|
|
||||||
if (i == n0)
|
|
||||||
return parser_alloc_._store_info();
|
|
||||||
|
|
||||||
// not counting expr_alloc_. We don't consider
|
// not counting expr_alloc_. We don't consider
|
||||||
// that to be owned by ParserStateMachine
|
// that to be owned by ParserStateMachine
|
||||||
|
|
||||||
return MemorySizeInfo::sentinel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -47,16 +47,10 @@ namespace xo {
|
||||||
return psm_.top_ssm();
|
return psm_.top_ssm();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
void
|
||||||
SchematikaParser::_n_store() const noexcept
|
SchematikaParser::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
{
|
{
|
||||||
return psm_._n_store();
|
return psm_.visit_pools(visitor);
|
||||||
}
|
|
||||||
|
|
||||||
MemorySizeInfo
|
|
||||||
SchematikaParser::_store_info(std::size_t i) const noexcept
|
|
||||||
{
|
|
||||||
return psm_._store_info(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -21,27 +21,11 @@ namespace xo {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
void
|
||||||
SchematikaReader::_n_store() const noexcept
|
SchematikaReader::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
{
|
{
|
||||||
return tokenizer_._n_store() + parser_._n_store();
|
tokenizer_.visit_pools(visitor);
|
||||||
}
|
parser_.visit_pools(visitor);
|
||||||
|
|
||||||
MemorySizeInfo
|
|
||||||
SchematikaReader::_store_info(std::size_t i) const noexcept
|
|
||||||
{
|
|
||||||
size_t n_tk = tokenizer_._n_store();
|
|
||||||
|
|
||||||
if (i < n_tk) {
|
|
||||||
return tokenizer_._store_info(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t n_pr = parser_._n_store();
|
|
||||||
|
|
||||||
if (i < n_tk + n_pr)
|
|
||||||
return parser_._store_info(i - n_tk);
|
|
||||||
|
|
||||||
return MemorySizeInfo::sentinel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ namespace xo {
|
||||||
using error_type = TokenizerError;
|
using error_type = TokenizerError;
|
||||||
using DCircularBuffer = xo::mm::DCircularBuffer;
|
using DCircularBuffer = xo::mm::DCircularBuffer;
|
||||||
using CircularBufferConfig = xo::mm::CircularBufferConfig;
|
using CircularBufferConfig = xo::mm::CircularBufferConfig;
|
||||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
using span_type = xo::mm::span<const CharT>;
|
using span_type = xo::mm::span<const CharT>;
|
||||||
//using input_state_type = TkInputState;
|
//using input_state_type = TkInputState;
|
||||||
using result_type = scan_result;
|
using result_type = scan_result;
|
||||||
|
|
@ -91,10 +91,8 @@ namespace xo {
|
||||||
const TkInputState & input_state() const { return input_state_; }
|
const TkInputState & input_state() const { return input_state_; }
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
/** number of distinct memory pools owned by tokenizer **/
|
/** visit tokenizer-owned memory pools; invoke visitor(info) for each one **/
|
||||||
std::size_t _n_store() const noexcept;
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
/** memory consumption for i'th memory pool **/
|
|
||||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,10 @@ namespace xo {
|
||||||
this->input_state_.discard_current_line();
|
this->input_state_.discard_current_line();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
void
|
||||||
Tokenizer::_n_store() const noexcept
|
Tokenizer::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
{
|
{
|
||||||
return input_buffer_._n_store();
|
input_buffer_.visit_pools(visitor);
|
||||||
}
|
|
||||||
|
|
||||||
MemorySizeInfo
|
|
||||||
Tokenizer::_store_info(std::size_t i) const noexcept
|
|
||||||
{
|
|
||||||
return input_buffer_._store_info(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue