From c931fca242b76f6f6c7d73c9ee80be17b8e757fc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 01:05:36 -0500 Subject: [PATCH] xo-interpreter2 .. xo-arena. memory pool introspection --- .../include/xo/alloc2/alloc/AAllocator.hpp | 19 +++++++------ .../xo/alloc2/alloc/IAllocator_Any.hpp | 2 ++ .../xo/alloc2/alloc/IAllocator_Xfer.hpp | 3 +- .../include/xo/alloc2/alloc/RAllocator.hpp | 1 + .../xo/alloc2/arena/IAllocator_DArena.hpp | 2 ++ xo-alloc2/src/alloc2/IAllocator_DArena.cpp | 7 +++++ xo-arena/include/xo/arena/ArenaConfig.hpp | 4 +-- xo-arena/include/xo/arena/DArena.hpp | 8 ++++-- xo-arena/include/xo/arena/DArenaHashMap.hpp | 7 ++--- xo-arena/include/xo/arena/DArenaVector.hpp | 2 +- xo-arena/include/xo/arena/DCircularBuffer.hpp | 4 +-- xo-arena/include/xo/arena/MemorySizeInfo.hpp | 10 +++++-- .../include/xo/arena/hashmap/HashMapStore.hpp | 15 +++------- xo-arena/src/arena/DArena.cpp | 13 ++++----- xo-arena/src/arena/DCircularBuffer.cpp | 28 +++++-------------- .../include/xo/expression2/StringTable.hpp | 6 ++-- .../src/expression2/StringTable.cpp | 19 +++---------- xo-gc/include/xo/gc/DX1Collector.hpp | 7 ++++- .../xo/gc/detail/IAllocator_DX1Collector.hpp | 2 ++ xo-gc/src/gc/DX1Collector.cpp | 27 ++++++++++++++++-- xo-gc/src/gc/IAllocator_DX1Collector.cpp | 6 ++++ .../interpreter2/VirtualSchematikaMachine.hpp | 6 ++-- .../interpreter2/VirtualSchematikaMachine.cpp | 17 +++-------- .../utest/VirtualSchematikaMachine.test.cpp | 12 ++++++++ .../include/xo/reader2/ParserStateMachine.hpp | 8 ++---- .../include/xo/reader2/SchematikaParser.hpp | 8 ++---- .../include/xo/reader2/SchematikaReader.hpp | 9 ++++-- xo-reader2/src/reader2/ParserStateMachine.cpp | 21 +++----------- xo-reader2/src/reader2/SchematikaParser.cpp | 12 ++------ xo-reader2/src/reader2/SchematikaReader.cpp | 24 +++------------- .../include/xo/tokenizer2/Tokenizer.hpp | 8 ++---- xo-tokenizer2/src/tokenizer2/Tokenizer.cpp | 12 ++------ 32 files changed, 157 insertions(+), 172 deletions(-) diff --git a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp index 4639d47e..ecc52862 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include #include "AllocInfo.hpp" //#include "AllocIterator.hpp" @@ -33,9 +34,11 @@ namespace xo { struct AAllocator { /** @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; - /** @brief type used for allocation responses **/ + /** type used for allocation responses **/ using value_type = std::byte *; /** object header, if configured **/ using header_type = std::uint64_t; @@ -95,6 +98,12 @@ namespace xo { * Includes alloc headers and guard regions **/ 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. **/ 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; /** reset allocator @p d to empty state. **/ 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*/ diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp index aac80bca..fa8c14ab 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp @@ -45,6 +45,8 @@ namespace xo { [[noreturn]] size_type available(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]] void visit_pools(Copaque, + const MemorySizeVisitor &) const override { _fatal(); } [[noreturn]] AllocError last_error(Copaque) const noexcept override { _fatal(); } [[noreturn]] AllocInfo alloc_info(Copaque, value_type) const noexcept override { _fatal(); } // defn in .cpp - problematic to require compiler know vt defn here diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp index e23d1470..e5b539a1 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp @@ -41,7 +41,7 @@ namespace xo { typeseq _typeseq() const noexcept override { return s_typeseq; } /** invoke native c++ dtor **/ void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } - + // const methods 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 { 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)); } AllocInfo alloc_info(Copaque d, value_type mem) const noexcept override { return I::alloc_info(_dcast(d), mem); diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index bbd35d5c..ad528ba5 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -39,6 +39,7 @@ namespace xo { size_type committed() const noexcept { return O::iface()->committed(O::data()); } size_type available() const noexcept { return O::iface()->available(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); } 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); } diff --git a/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp b/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp index 4a871822..81e92211 100644 --- a/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp +++ b/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp @@ -40,6 +40,8 @@ namespace xo { static size_type committed(const DArena &) noexcept; static size_type available(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 AllocError last_error(const DArena &) noexcept; /** retrieve allocation bookkeeping info for @p mem from arena @p d **/ diff --git a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp index a3bd9613..2a3a2d58 100644 --- a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp +++ b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp @@ -52,6 +52,13 @@ namespace xo { return s.allocated(); } + void + IAllocator_DArena::visit_pools(const DArena & s, + const MemorySizeVisitor & visitor) + { + s.visit_pools(visitor); + } + bool IAllocator_DArena::contains(const DArena & s, const void * p) noexcept diff --git a/xo-arena/include/xo/arena/ArenaConfig.hpp b/xo-arena/include/xo/arena/ArenaConfig.hpp index 4d72b912..9ca2a387 100644 --- a/xo-arena/include/xo/arena/ArenaConfig.hpp +++ b/xo-arena/include/xo/arena/ArenaConfig.hpp @@ -19,13 +19,13 @@ namespace xo { struct ArenaConfig { /** @defgroup mm-arenaconfig-ctors **/ - ArenaConfig with_name(std::string name) { + ArenaConfig with_name(std::string name) const { ArenaConfig copy(*this); copy.name_ = name; return copy; } - ArenaConfig with_size(std::size_t z) { + ArenaConfig with_size(std::size_t z) const { ArenaConfig copy(*this); copy.size_ = z; return copy; diff --git a/xo-arena/include/xo/arena/DArena.hpp b/xo-arena/include/xo/arena/DArena.hpp index 8c7203d6..4c12c8cb 100644 --- a/xo-arena/include/xo/arena/DArena.hpp +++ b/xo-arena/include/xo/arena/DArena.hpp @@ -138,12 +138,14 @@ namespace xo { **/ 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 **/ 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 * * Require: diff --git a/xo-arena/include/xo/arena/DArenaHashMap.hpp b/xo-arena/include/xo/arena/DArenaHashMap.hpp index 042dc900..da0e742a 100644 --- a/xo-arena/include/xo/arena/DArenaHashMap.hpp +++ b/xo-arena/include/xo/arena/DArenaHashMap.hpp @@ -45,7 +45,7 @@ namespace xo { using value_type = std::pair; using key_hash = Hash; using key_equal = Equal; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using byte = std::byte; using group_type = detail::ControlGroup; using store_type = detail::HashMapStore; @@ -77,9 +77,8 @@ namespace xo { iterator begin() { return _promote_iterator(_begin_aux()); } iterator end() { return _promote_iterator(_end_aux()); } - std::size_t _n_store() const noexcept { return store_._n_store(); } - MemorySizeInfo _store_info(std::size_t i) const noexcept { - return store_._store_info(i); + void visit_pools(const MemorySizeVisitor & visitor) const { + return store_.visit_pools(visitor); } /** insert @p kv_pair into hash map. diff --git a/xo-arena/include/xo/arena/DArenaVector.hpp b/xo-arena/include/xo/arena/DArenaVector.hpp index b7a0b2aa..33230b0c 100644 --- a/xo-arena/include/xo/arena/DArenaVector.hpp +++ b/xo-arena/include/xo/arena/DArenaVector.hpp @@ -82,7 +82,7 @@ namespace xo { /** arena used for element storage * (Might prefer obj 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. * Always limited by ArenaConfig.size_ diff --git a/xo-arena/include/xo/arena/DCircularBuffer.hpp b/xo-arena/include/xo/arena/DCircularBuffer.hpp index 538d272d..ba744531 100644 --- a/xo-arena/include/xo/arena/DCircularBuffer.hpp +++ b/xo-arena/include/xo/arena/DCircularBuffer.hpp @@ -83,8 +83,8 @@ namespace xo { const_span_type occupied_range() const noexcept { return occupied_range_; } const_span_type input_range() const noexcept { return input_range_; } - std::size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** report memory-size info for this buffer to @p fn **/ + void visit_pools(const MemorySizeVisitor & fn) const; /** verify DCircularBuffer invariants. * Act on failure according to policy @p p diff --git a/xo-arena/include/xo/arena/MemorySizeInfo.hpp b/xo-arena/include/xo/arena/MemorySizeInfo.hpp index 7cba082c..f12dcce5 100644 --- a/xo-arena/include/xo/arena/MemorySizeInfo.hpp +++ b/xo-arena/include/xo/arena/MemorySizeInfo.hpp @@ -5,7 +5,8 @@ #pragma once -#include +#include +#include namespace xo { namespace mm { @@ -31,7 +32,12 @@ namespace xo { 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; + } } /* end MemorySizeInfo.hpp */ diff --git a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp index 74f2f4e7..22bfb120 100644 --- a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp +++ b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp @@ -19,7 +19,7 @@ namespace xo { using group_type = detail::ControlGroup; using control_vector_type = xo::mm::DArenaVector; using slot_vector_type = xo::mm::DArenaVector; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; public: /** 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; } float load_factor() const noexcept { return size_ / static_cast(n_slot_); } - std::size_t _n_store() const noexcept { return 2; } - MemorySizeInfo _store_info(std::size_t i) const noexcept { - switch (i) { - case 0: - return control_._store_info(); - case 1: - return slots_._store_info(); - } - - return MemorySizeInfo::sentinel(); + void visit_pools(const MemorySizeVisitor & visitor) const { + control_.visit_pools(visitor); + slots_.visit_pools(visitor); } void resize_from_empty(const std::pairallocated(), - this->committed(), - this->reserved()); + void + DArena::visit_pools(const MemorySizeVisitor & fn) const { + fn(MemorySizeInfo(config_.name_, + this->allocated(), + this->committed(), + this->reserved())); } AllocInfo diff --git a/xo-arena/src/arena/DCircularBuffer.cpp b/xo-arena/src/arena/DCircularBuffer.cpp index 2a5fb486..667126af 100644 --- a/xo-arena/src/arena/DCircularBuffer.cpp +++ b/xo-arena/src/arena/DCircularBuffer.cpp @@ -79,30 +79,16 @@ namespace xo { { } - std::size_t - DCircularBuffer::_n_store() const noexcept + void + DCircularBuffer::visit_pools(const MemorySizeVisitor & visitor) const { - return 2; - } + visitor(MemorySizeInfo(config_.name_, + occupied_range_.size(), + mapped_range_.size(), + reserved_range_.size())); - MemorySizeInfo - 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(); + pinned_spans_.visit_pools(visitor); } - bool DCircularBuffer::verify_ok(verify_policy policy) const diff --git a/xo-expression2/include/xo/expression2/StringTable.hpp b/xo-expression2/include/xo/expression2/StringTable.hpp index b55c48ee..8d0354c8 100644 --- a/xo-expression2/include/xo/expression2/StringTable.hpp +++ b/xo-expression2/include/xo/expression2/StringTable.hpp @@ -21,7 +21,7 @@ namespace xo { class StringTable { public: using DArena = xo::mm::DArena; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using StringMap = xo::map::DArenaHashMap; using size_type = StringMap::size_type; @@ -46,8 +46,8 @@ namespace xo { **/ bool verify_ok(verify_policy p = verify_policy::throw_only()) const; - std::size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit string-table memory pools, call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; private: /** allocate string storage in this arena; use DString to represent each string. diff --git a/xo-expression2/src/expression2/StringTable.cpp b/xo-expression2/src/expression2/StringTable.cpp index 79a17067..174c9e9f 100644 --- a/xo-expression2/src/expression2/StringTable.cpp +++ b/xo-expression2/src/expression2/StringTable.cpp @@ -160,22 +160,11 @@ namespace xo { return true; } - std::size_t - StringTable::_n_store() const noexcept + void + StringTable::visit_pools(const MemorySizeVisitor & visitor) const { - return 1 + map_._n_store(); - } - - 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(); + strings_.visit_pools(visitor); + map_.visit_pools(visitor); } } /*namespace scm*/ diff --git a/xo-gc/include/xo/gc/DX1Collector.hpp b/xo-gc/include/xo/gc/DX1Collector.hpp index af41ae0d..2ef7148a 100644 --- a/xo-gc/include/xo/gc/DX1Collector.hpp +++ b/xo-gc/include/xo/gc/DX1Collector.hpp @@ -81,7 +81,7 @@ namespace xo { /** faceted object pointer to this instance */ template obj ref() { return obj(this); } - + #ifdef NOT_YET /** create instance with default configuration, * generation size @p gen_z @@ -110,6 +110,11 @@ namespace xo { /** total allocated memory in bytes, across all {role, generation} **/ 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 * in role @p r (according to current GC state) **/ diff --git a/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp b/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp index 424f24ff..ca529990 100644 --- a/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp +++ b/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp @@ -48,6 +48,8 @@ namespace xo { static size_type available(const DX1Collector &) noexcept; /** space used by @p d across all {roles, generations}. **/ 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 **/ static bool contains(const DX1Collector & d, const void * p) noexcept; /** report last error, if any, for collector @p d **/ diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index 16bdedc3..a4375da5 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -96,8 +96,18 @@ namespace xo { .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_); + { + 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::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 DX1Collector::contains(role r, const void * addr) const noexcept { diff --git a/xo-gc/src/gc/IAllocator_DX1Collector.cpp b/xo-gc/src/gc/IAllocator_DX1Collector.cpp index 58e89941..039e84df 100644 --- a/xo-gc/src/gc/IAllocator_DX1Collector.cpp +++ b/xo-gc/src/gc/IAllocator_DX1Collector.cpp @@ -56,6 +56,12 @@ namespace xo { return d.allocated_total(); } + void + IAllocator_DX1Collector::visit_pools(const DX1Collector & d, const MemorySizeVisitor & visitor) + { + d.visit_pools(visitor); + } + bool IAllocator_DX1Collector::contains(const DX1Collector & d, const void * addr) noexcept { diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 5165c9a8..5aecbc55 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -61,14 +61,14 @@ namespace xo { using Stack = void *; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using span_type = xo::mm::span; public: VirtualSchematikaMachine(const VsmConfig & config); - size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit vsm-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; /** begin interactive session. **/ void begin_interactive_session(); diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index d40b85c6..7c4873fb 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -30,20 +30,11 @@ namespace xo { reader_{config.rdr_config_, mm_.to_op()} {} - std::size_t - VirtualSchematikaMachine::_n_store() const noexcept + void + VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const { - // oops. need something that goes through AAllocator api - - 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); + mm_.visit_pools(visitor); + reader_.visit_pools(visitor); } void diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index a0554f87..2ad7122d 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -28,6 +28,7 @@ namespace xo { using xo::scm::VsmResultExt; using xo::scm::DFloat; using xo::mm::AGCObject; + using xo::mm::MemorySizeInfo; using span_type = xo::scm::VirtualSchematikaMachine::span_type; using Catch::Matchers::WithinAbs; @@ -55,6 +56,8 @@ namespace xo { namespace ut { TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") { + scope log(XO_DEBUG(true)); + VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -73,6 +76,15 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); 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*/ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 89569695..3fae8903 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -36,7 +36,7 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using ArenaConfig = xo::mm::ArenaConfig; using DArena = xo::mm::DArena; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using size_type = std::size_t; public: @@ -62,10 +62,8 @@ namespace xo { /** top of parser stack **/ obj top_ssm() const; - /** number of distinct memory pools owned by PS **/ - std::size_t _n_store() const noexcept; - /** memory consumption for i'th memory pool **/ - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit psm-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; ///@} diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 83e9230b..8c3f51b1 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -156,7 +156,7 @@ namespace xo { using token_type = Token; using ArenaConfig = xo::mm::ArenaConfig; using AAllocator = xo::mm::AAllocator; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using ppindentinfo = xo::print::ppindentinfo; using size_type = std::size_t; @@ -193,10 +193,8 @@ namespace xo { /** top of parser stack **/ obj top_ssm() const; - /** number of distinct memory pools owned by PS **/ - std::size_t _n_store() const noexcept; - /** memory consumption for i'th memory pool **/ - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit parser-owned memory pools; invoke visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; ///@} /** scm-schematikaparser-general-methods **/ diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 3c2b5312..ee3de91f 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -36,7 +36,7 @@ namespace xo { class SchematikaReader { public: using AAllocator = xo::mm::AAllocator; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using span_type = xo::mm::span; using size_type = std::size_t; @@ -44,8 +44,11 @@ namespace xo { SchematikaReader(const ReaderConfig & config, obj expr_alloc); - std::size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit reader-owned memory pools; call visitor(info) for each. + * 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. * false iff parser is working on incomplete expression diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index ff845762..38f7ff4a 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -54,27 +54,14 @@ namespace xo { return this->stack_->top(); } - std::size_t - ParserStateMachine::_n_store() const noexcept + void + ParserStateMachine::visit_pools(const MemorySizeVisitor & visitor) const { - return stringtable_._n_store() + 1; - } - - 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(); + stringtable_.visit_pools(visitor); + parser_alloc_.visit_pools(visitor); // not counting expr_alloc_. We don't consider // that to be owned by ParserStateMachine - - return MemorySizeInfo::sentinel(); } void diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 07c74d17..c53acc16 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -47,16 +47,10 @@ namespace xo { return psm_.top_ssm(); } - std::size_t - SchematikaParser::_n_store() const noexcept + void + SchematikaParser::visit_pools(const MemorySizeVisitor & visitor) const { - return psm_._n_store(); - } - - MemorySizeInfo - SchematikaParser::_store_info(std::size_t i) const noexcept - { - return psm_._store_info(i); + return psm_.visit_pools(visitor); } void diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index 097c68df..47140d63 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -21,27 +21,11 @@ namespace xo { { } - std::size_t - SchematikaReader::_n_store() const noexcept + void + SchematikaReader::visit_pools(const MemorySizeVisitor & visitor) const { - return tokenizer_._n_store() + parser_._n_store(); - } - - 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(); + tokenizer_.visit_pools(visitor); + parser_.visit_pools(visitor); } bool diff --git a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp index 83015c03..0a212a8f 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp @@ -61,7 +61,7 @@ namespace xo { using error_type = TokenizerError; using DCircularBuffer = xo::mm::DCircularBuffer; using CircularBufferConfig = xo::mm::CircularBufferConfig; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using span_type = xo::mm::span; //using input_state_type = TkInputState; using result_type = scan_result; @@ -91,10 +91,8 @@ namespace xo { const TkInputState & input_state() const { return input_state_; } #pragma GCC diagnostic pop - /** number of distinct memory pools owned by tokenizer **/ - std::size_t _n_store() const noexcept; - /** memory consumption for i'th memory pool **/ - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit tokenizer-owned memory pools; invoke visitor(info) for each one **/ + void visit_pools(const MemorySizeVisitor & visitor) const; ///@} diff --git a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp index c36d85a5..f176a88f 100644 --- a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp +++ b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp @@ -22,16 +22,10 @@ namespace xo { this->input_state_.discard_current_line(); } - std::size_t - Tokenizer::_n_store() const noexcept + void + Tokenizer::visit_pools(const MemorySizeVisitor & visitor) const { - return input_buffer_._n_store(); - } - - MemorySizeInfo - Tokenizer::_store_info(std::size_t i) const noexcept - { - return input_buffer_._store_info(i); + input_buffer_.visit_pools(visitor); } bool