xo-expression2 stack: expand MemorySizeInfo w/ per-type detail
This commit is contained in:
parent
0023831e4c
commit
16309dfff6
8 changed files with 138 additions and 24 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <xo/reflectutil/typeseq.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
@ -12,14 +13,27 @@
|
||||||
namespace xo {
|
namespace xo {
|
||||||
namespace mm {
|
namespace mm {
|
||||||
|
|
||||||
|
struct MemorySizeDetail {
|
||||||
|
using typeseq = xo::reflect::typeseq;
|
||||||
|
|
||||||
|
/** identifies a c++ type T. See xo/facet/TypeRegistry **/
|
||||||
|
typeseq tseq_;
|
||||||
|
/** number of T-instances **/
|
||||||
|
uint32_t n_alloc_ = 0;
|
||||||
|
/** bytes used by T-instances **/
|
||||||
|
uint32_t z_alloc_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct MemorySizeInfo {
|
struct MemorySizeInfo {
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
|
using DetailArrayType = std::array<MemorySizeDetail, 32>;
|
||||||
|
|
||||||
MemorySizeInfo() = default;
|
MemorySizeInfo() = default;
|
||||||
MemorySizeInfo(std::string_view name,
|
MemorySizeInfo(std::string_view name,
|
||||||
std::size_t u, std::size_t a, std::size_t c, std::size_t r)
|
std::size_t u, std::size_t a, std::size_t c, std::size_t r,
|
||||||
|
DetailArrayType * detail)
|
||||||
: resource_name_{name},
|
: resource_name_{name},
|
||||||
used_{u}, allocated_{a}, committed_{c}, reserved_{r}
|
used_{u}, allocated_{a}, committed_{c}, reserved_{r}, detail_{detail}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static MemorySizeInfo sentinel() { return MemorySizeInfo(); }
|
static MemorySizeInfo sentinel() { return MemorySizeInfo(); }
|
||||||
|
|
@ -36,6 +50,9 @@ namespace xo {
|
||||||
* virtual memory addresses range obtained, whether or not committed
|
* virtual memory addresses range obtained, whether or not committed
|
||||||
**/
|
**/
|
||||||
std::size_t reserved_ = 0;
|
std::size_t reserved_ = 0;
|
||||||
|
|
||||||
|
/** optional histogram with per-data-type counts **/
|
||||||
|
DetailArrayType * detail_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** function that visits MemorySizeInfo for a collection of @p n memory pools.
|
/** function that visits MemorySizeInfo for a collection of @p n memory pools.
|
||||||
|
|
|
||||||
|
|
@ -176,11 +176,43 @@ namespace xo {
|
||||||
* must assume it's all used
|
* must assume it's all used
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
// assemble histogram
|
||||||
|
MemorySizeInfo::DetailArrayType detail_v;
|
||||||
|
MemorySizeInfo::DetailArrayType * p_detail = nullptr;
|
||||||
|
|
||||||
|
if (config_.store_header_flag_) {
|
||||||
|
p_detail = &detail_v;
|
||||||
|
|
||||||
|
for (const auto & ix : *this) {
|
||||||
|
typeseq ix_tseq(ix.tseq());
|
||||||
|
|
||||||
|
// totals in detail_v[0]
|
||||||
|
MemorySizeDetail & d = detail_v[0];
|
||||||
|
++d.n_alloc_;
|
||||||
|
d.z_alloc_ += ix.size();
|
||||||
|
|
||||||
|
// O(n) insertion here
|
||||||
|
for (size_t i = 1; i < detail_v.size(); ++i) {
|
||||||
|
if (detail_v[i].tseq_.is_sentinel()
|
||||||
|
|| (detail_v[i].tseq_ == ix_tseq))
|
||||||
|
{
|
||||||
|
MemorySizeDetail & d = detail_v[i];
|
||||||
|
|
||||||
|
d.tseq_ = ix_tseq;
|
||||||
|
++d.n_alloc_;
|
||||||
|
d.z_alloc_ += ix.size();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn(MemorySizeInfo(config_.name_,
|
fn(MemorySizeInfo(config_.name_,
|
||||||
this->allocated() /*used*/,
|
this->allocated() /*used*/,
|
||||||
this->allocated(),
|
this->allocated(),
|
||||||
this->committed(),
|
this->committed(),
|
||||||
this->reserved()));
|
this->reserved(),
|
||||||
|
p_detail));
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocInfo
|
AllocInfo
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,8 @@ namespace xo {
|
||||||
occupied_range_.size() /*used*/,
|
occupied_range_.size() /*used*/,
|
||||||
occupied_range_.size(),
|
occupied_range_.size(),
|
||||||
mapped_range_.size(),
|
mapped_range_.size(),
|
||||||
reserved_range_.size()));
|
reserved_range_.size(),
|
||||||
|
nullptr /*detail*/));
|
||||||
|
|
||||||
pinned_spans_.visit_pools(visitor);
|
pinned_spans_.visit_pools(visitor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
xo-expression2/include/xo/expression2/GlobalSymtab.hpp
Normal file
13
xo-expression2/include/xo/expression2/GlobalSymtab.hpp
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/** @file GlobalSymtab.hpp
|
||||||
|
*
|
||||||
|
* @author Roland Conybeare, Feb 2026
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DGlobalSymtab.hpp"
|
||||||
|
//#include "symtab/ISymbolTable_DGlobalSymtab.hpp"
|
||||||
|
//#include "symtab/IGCObject_DGlobalSymtab.hpp"
|
||||||
|
//#include "symtab/IPrintable_DGlobalSymtab.hpp"
|
||||||
|
|
||||||
|
/* end GlobalSymtab.hpp */
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <xo/expression2/detail/IGCObject_DSequenceExpr.hpp>
|
#include <xo/expression2/detail/IGCObject_DSequenceExpr.hpp>
|
||||||
#include <xo/expression2/detail/IPrintable_DSequenceExpr.hpp>
|
#include <xo/expression2/detail/IPrintable_DSequenceExpr.hpp>
|
||||||
|
|
||||||
|
#include <xo/expression2/GlobalSymtab.hpp>
|
||||||
#include <xo/expression2/LocalSymtab.hpp>
|
#include <xo/expression2/LocalSymtab.hpp>
|
||||||
|
|
||||||
#include <xo/gc/detail/AGCObject.hpp>
|
#include <xo/gc/detail/AGCObject.hpp>
|
||||||
|
|
@ -37,6 +38,7 @@ namespace xo {
|
||||||
using xo::mm::AGCObject;
|
using xo::mm::AGCObject;
|
||||||
using xo::print::APrintable;
|
using xo::print::APrintable;
|
||||||
using xo::facet::FacetRegistry;
|
using xo::facet::FacetRegistry;
|
||||||
|
using xo::facet::TypeRegistry;
|
||||||
using xo::facet::typeseq;
|
using xo::facet::typeseq;
|
||||||
|
|
||||||
namespace scm {
|
namespace scm {
|
||||||
|
|
@ -45,6 +47,8 @@ namespace xo {
|
||||||
{
|
{
|
||||||
scope log(XO_DEBUG(true));
|
scope log(XO_DEBUG(true));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FacetRegistry::register_impl<AGCObject, DUniqueString>();
|
FacetRegistry::register_impl<AGCObject, DUniqueString>();
|
||||||
FacetRegistry::register_impl<APrintable, DUniqueString>();
|
FacetRegistry::register_impl<APrintable, DUniqueString>();
|
||||||
|
|
||||||
|
|
@ -58,10 +62,6 @@ namespace xo {
|
||||||
// +- IfElseExpr
|
// +- IfElseExpr
|
||||||
// \- SequenceExpr
|
// \- SequenceExpr
|
||||||
|
|
||||||
// SymbolTable
|
|
||||||
// +- LocalSymtab
|
|
||||||
// \- GlobalSymtab
|
|
||||||
|
|
||||||
FacetRegistry::register_impl<AExpression, DConstant>();
|
FacetRegistry::register_impl<AExpression, DConstant>();
|
||||||
FacetRegistry::register_impl<AGCObject, DConstant>();
|
FacetRegistry::register_impl<AGCObject, DConstant>();
|
||||||
FacetRegistry::register_impl<APrintable, DConstant>();
|
FacetRegistry::register_impl<APrintable, DConstant>();
|
||||||
|
|
@ -94,10 +94,17 @@ namespace xo {
|
||||||
FacetRegistry::register_impl<AGCObject, DSequenceExpr>();
|
FacetRegistry::register_impl<AGCObject, DSequenceExpr>();
|
||||||
FacetRegistry::register_impl<APrintable, DSequenceExpr>();
|
FacetRegistry::register_impl<APrintable, DSequenceExpr>();
|
||||||
|
|
||||||
|
// SymbolTable
|
||||||
|
// +- LocalSymtab
|
||||||
|
// \- GlobalSymtab
|
||||||
|
|
||||||
FacetRegistry::register_impl<ASymbolTable, DLocalSymtab>();
|
FacetRegistry::register_impl<ASymbolTable, DLocalSymtab>();
|
||||||
FacetRegistry::register_impl<AGCObject, DLocalSymtab>();
|
FacetRegistry::register_impl<AGCObject, DLocalSymtab>();
|
||||||
FacetRegistry::register_impl<APrintable, DLocalSymtab>();
|
FacetRegistry::register_impl<APrintable, DLocalSymtab>();
|
||||||
|
|
||||||
|
// until we register facets
|
||||||
|
TypeRegistry::register_type<DGlobalSymtab>();
|
||||||
|
|
||||||
log && log(xtag("DUniqueString.tseq", typeseq::id<DUniqueString>()));
|
log && log(xtag("DUniqueString.tseq", typeseq::id<DUniqueString>()));
|
||||||
log && log(xtag("DDefineExpr.tseq", typeseq::id<DDefineExpr>()));
|
log && log(xtag("DDefineExpr.tseq", typeseq::id<DDefineExpr>()));
|
||||||
log && log(xtag("DVariable.tseq", typeseq::id<DVariable>()));
|
log && log(xtag("DVariable.tseq", typeseq::id<DVariable>()));
|
||||||
|
|
@ -108,6 +115,7 @@ namespace xo {
|
||||||
log && log(xtag("DIfElseExpr.tseq", typeseq::id<DIfElseExpr>()));
|
log && log(xtag("DIfElseExpr.tseq", typeseq::id<DIfElseExpr>()));
|
||||||
log && log(xtag("DSequenceExpr.tseq", typeseq::id<DSequenceExpr>()));
|
log && log(xtag("DSequenceExpr.tseq", typeseq::id<DSequenceExpr>()));
|
||||||
|
|
||||||
|
log && log(xtag("DGlobalSymtab.tseq", typeseq::id<DGlobalSymtab>()));
|
||||||
log && log(xtag("DLocalSymtab.tseq", typeseq::id<DLocalSymtab>()));
|
log && log(xtag("DLocalSymtab.tseq", typeseq::id<DLocalSymtab>()));
|
||||||
|
|
||||||
log && log(xtag("AExpression.tseq", typeseq::id<AExpression>()));
|
log && log(xtag("AExpression.tseq", typeseq::id<AExpression>()));
|
||||||
|
|
|
||||||
|
|
@ -53,13 +53,13 @@ namespace xo {
|
||||||
instance()._register_type(r);
|
instance()._register_type(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Number of registered (facet, repr) pairs **/
|
static std::string_view id2name(typeseq id) noexcept {
|
||||||
std::size_t size() const { return registry_.size(); }
|
|
||||||
|
|
||||||
std::string_view id2name(typeseq id) const noexcept {
|
|
||||||
return instance()._id2name(id);
|
return instance()._id2name(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Number of registered (facet, repr) pairs **/
|
||||||
|
std::size_t size() const { return registry_.size(); }
|
||||||
|
|
||||||
/** visit memory pools owned by facet registry **/
|
/** visit memory pools owned by facet registry **/
|
||||||
void visit_pools(const MemorySizeVisitor & visitor) {
|
void visit_pools(const MemorySizeVisitor & visitor) {
|
||||||
registry_.visit_pools(visitor);
|
registry_.visit_pools(visitor);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include <xo/object2/Integer.hpp>
|
#include <xo/object2/Integer.hpp>
|
||||||
#include <xo/object2/String.hpp>
|
#include <xo/object2/String.hpp>
|
||||||
#include <xo/alloc2/arena/IAllocator_DArena.hpp>
|
#include <xo/alloc2/arena/IAllocator_DArena.hpp>
|
||||||
|
#include <xo/facet/TypeRegistry.hpp>
|
||||||
#include <catch2/catch.hpp>
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
|
|
@ -55,17 +56,23 @@ namespace xo {
|
||||||
ParserFixture(const std::string & testname, bool debug_flag)
|
ParserFixture(const std::string & testname, bool debug_flag)
|
||||||
{
|
{
|
||||||
this->aux_arena_
|
this->aux_arena_
|
||||||
= std::move(DArena(ArenaConfig().with_name(testname).with_size(4 * 1024)));
|
= std::move(DArena(ArenaConfig()
|
||||||
|
.with_name(testname)
|
||||||
|
.with_size(4 * 1024)));
|
||||||
obj<AAllocator,DArena> aux_mm(&aux_arena_);
|
obj<AAllocator,DArena> aux_mm(&aux_arena_);
|
||||||
|
|
||||||
this->expr_arena_
|
this->expr_arena_
|
||||||
= dp<DArena>::make(aux_mm,
|
= dp<DArena>::make(aux_mm,
|
||||||
ArenaConfig().with_name("expr").with_size(16 * 1024));
|
(ArenaConfig()
|
||||||
|
.with_name("expr")
|
||||||
|
.with_size(16 * 1024)
|
||||||
|
.with_store_header_flag(true)));
|
||||||
obj<AAllocator,DArena> expr_mm(expr_arena_.data());
|
obj<AAllocator,DArena> expr_mm(expr_arena_.data());
|
||||||
|
|
||||||
ParserConfig cfg;
|
ParserConfig cfg;
|
||||||
cfg.parser_arena_config_.size_ = 16 * 1024;
|
cfg.parser_arena_config_.size_ = 16 * 1024;
|
||||||
cfg.symtab_config_.hint_max_capacity_ = 512;
|
/* editor bait: symbol table */
|
||||||
|
cfg.symtab_config_.hint_max_capacity_ = 128;
|
||||||
cfg.max_stringtable_capacity_ = 512;
|
cfg.max_stringtable_capacity_ = 512;
|
||||||
cfg.debug_flag_ = false;
|
cfg.debug_flag_ = false;
|
||||||
|
|
||||||
|
|
@ -77,12 +84,32 @@ namespace xo {
|
||||||
ParserFixture(const ParserFixture && other) = delete;
|
ParserFixture(const ParserFixture && other) = delete;
|
||||||
|
|
||||||
bool log_memory_layout(scope * p_log) {
|
bool log_memory_layout(scope * p_log) {
|
||||||
|
using xo::facet::TypeRegistry;
|
||||||
|
using xo::mm::MemorySizeDetail;
|
||||||
|
|
||||||
auto visitor = [p_log](const MemorySizeInfo & info) {
|
auto visitor = [p_log](const MemorySizeInfo & info) {
|
||||||
*p_log && (*p_log)(xtag("name", info.resource_name_),
|
*p_log && (*p_log)(xtag("name", info.resource_name_),
|
||||||
xtag("used", info.used_),
|
xtag("used", info.used_),
|
||||||
xtag("alloc", info.allocated_),
|
xtag("alloc", info.allocated_),
|
||||||
xtag("commit", info.committed_),
|
xtag("commit", info.committed_),
|
||||||
xtag("resv", info.reserved_));
|
xtag("resv", info.reserved_));
|
||||||
|
if (*p_log && info.detail_) {
|
||||||
|
(*p_log)("detail",
|
||||||
|
xtag("n", (*info.detail_)[0].n_alloc_),
|
||||||
|
xtag("z", (*info.detail_)[0].z_alloc_));
|
||||||
|
for (size_t i = 1; i < info.detail_->size(); ++i) {
|
||||||
|
const MemorySizeDetail & d = (*info.detail_)[i];
|
||||||
|
|
||||||
|
if (d.tseq_.is_sentinel())
|
||||||
|
break;
|
||||||
|
|
||||||
|
(*p_log)("[",i,"]",
|
||||||
|
xtag("tseq",d.tseq_),
|
||||||
|
xtag("type", TypeRegistry::id2name(d.tseq_)),
|
||||||
|
xtag("n", d.n_alloc_),
|
||||||
|
xtag("z", d.z_alloc_));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
aux_arena_.visit_pools(visitor);
|
aux_arena_.visit_pools(visitor);
|
||||||
|
|
@ -144,14 +171,29 @@ namespace xo {
|
||||||
REQUIRE(parser.debug_flag() == false);
|
REQUIRE(parser.debug_flag() == false);
|
||||||
REQUIRE(parser.is_at_toplevel() == true);
|
REQUIRE(parser.is_at_toplevel() == true);
|
||||||
|
|
||||||
|
// baseline:
|
||||||
|
// SchematikaParser-ctor :used 1408
|
||||||
|
// facets-ctl :used 73 // facet hashtable
|
||||||
|
// facets-slots :used 1168 // facet hashtable
|
||||||
|
// expr :used 2056
|
||||||
|
// [1] :type xo::scm::DArray :n 1 :z 2056 // DArray of DUniqueString*
|
||||||
|
// [2] :type ? :n 1 : z 16
|
||||||
|
// strings :used 0
|
||||||
|
// stringkeys-ctl :used 0
|
||||||
|
// strinkeys-slots :used 0
|
||||||
|
// parser-arena :used 0
|
||||||
|
// global-symtab-ctl :used 0
|
||||||
|
// global-symtab-slots :used 0
|
||||||
|
|
||||||
log && fixture.log_memory_layout(&log);
|
log && fixture.log_memory_layout(&log);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("SchematikaParser-begin-interactive", "[reader2][SchematikaParser]")
|
TEST_CASE("SchematikaParser-begin-interactive",
|
||||||
|
"[reader2][SchematikaParser]")
|
||||||
{
|
{
|
||||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||||
|
|
||||||
constexpr bool c_debug_flag = false;
|
constexpr bool c_debug_flag = true;
|
||||||
scope log(XO_DEBUG(c_debug_flag), xtag("test", testname));
|
scope log(XO_DEBUG(c_debug_flag), xtag("test", testname));
|
||||||
|
|
||||||
ParserFixture fixture(testname, c_debug_flag);
|
ParserFixture fixture(testname, c_debug_flag);
|
||||||
|
|
@ -697,7 +739,7 @@ namespace xo {
|
||||||
|
|
||||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||||
|
|
||||||
constexpr bool c_debug_flag = true;
|
constexpr bool c_debug_flag = false;
|
||||||
scope log(XO_DEBUG(c_debug_flag), xtag("test", testname));
|
scope log(XO_DEBUG(c_debug_flag), xtag("test", testname));
|
||||||
|
|
||||||
ParserFixture fixture(testname, c_debug_flag);
|
ParserFixture fixture(testname, c_debug_flag);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ namespace xo {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32_t seqno_ = 0;
|
int32_t seqno_ = -1;
|
||||||
std::string_view name_;
|
std::string_view name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -91,10 +91,11 @@ namespace xo {
|
||||||
return typeseq(xo::reflect::typerecd::recd<T>().seqno());
|
return typeseq(xo::reflect::typerecd::recd<T>().seqno());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_sentinel() const { return seqno_ == -1; }
|
||||||
int32_t seqno() const { return seqno_; }
|
int32_t seqno() const { return seqno_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32_t seqno_ = 0;
|
int32_t seqno_ = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
//template <typename Tag>
|
//template <typename Tag>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue