xo-interpreter2 .. xo-arena. memory pool introspection

This commit is contained in:
Roland Conybeare 2026-02-03 01:05:36 -05:00
commit c931fca242
32 changed files with 157 additions and 172 deletions

View file

@ -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*/

View file

@ -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

View file

@ -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);

View file

@ -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); }

View file

@ -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 **/

View file

@ -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

View file

@ -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;

View file

@ -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:

View file

@ -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.

View file

@ -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_

View file

@ -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

View file

@ -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 */

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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*/

View file

@ -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)
**/ **/

View file

@ -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 **/

View file

@ -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
{ {

View file

@ -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
{ {

View file

@ -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();

View file

@ -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

View file

@ -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*/

View file

@ -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;
///@} ///@}

View file

@ -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 **/

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
///@} ///@}

View file

@ -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