26#ifdef ACAV_ENABLE_STRING_STATS
34 : properties_(std::move(properties)), sourceRange_(sourceRange) {}
36AstViewNode::AstViewNode(AstNode *node) : node_(node) {
42AstViewNode::~AstViewNode() {
56 children_.push_back(child);
62AstContext::~AstContext() {
70 allAstViewNodes_.clear();
71 allAstViewNodes_.shrink_to_fit();
72 MemoryProfiler::checkpoint(
"AstContext dtor: After deleting ViewNodes");
75 MemoryProfiler::checkpoint(
"AstContext dtor: Before deleting AstNodes");
76 for (AstNode *node : allAstNodes_) {
80 allAstNodes_.shrink_to_fit();
81 MemoryProfiler::checkpoint(
"AstContext dtor: After deleting AstNodes");
84 typeDeduplicationMap_.clear();
87 MemoryProfiler::checkpoint(
"AstContext dtor: END");
93 allAstNodes_.push_back(node);
99 allAstViewNodes_.push_back(viewNode);
106#ifdef ACAV_ENABLE_STRING_STATS
111 auto it = typeDeduplicationMap_.find(typePtr);
112 if (it != typeDeduplicationMap_.end()) {
113#ifdef ACAV_ENABLE_STRING_STATS
123 typeDeduplicationMap_[typePtr] = node;
129 auto it = typeDeduplicationMap_.find(typePtr);
130 if (it != typeDeduplicationMap_.end()) {
138 locationIndex_.addNode(node);
143 locationIndex_.finalize();
146#ifdef ACAV_ENABLE_STRING_STATS
148TypeDeduplicationStats AstContext::getTypeDeduplicationStats()
const {
149 TypeDeduplicationStats stats{};
151 stats.totalTypeLookups = typeLookupCount_;
152 stats.cacheHits = typeCacheHits_;
153 stats.uniqueTypeNodes = typeDeduplicationMap_.size();
156 std::size_t totalRefs = 0;
157 std::size_t totalNodeBytes = 0;
158 for (
const auto &[ptr, node] : typeDeduplicationMap_) {
159 totalRefs += node->getUseCount();
161 totalNodeBytes +=
sizeof(AstNode) + node->getProperties().dump().size();
163 stats.totalTypeReferences = totalRefs;
166 std::size_t avgNodeBytes = stats.uniqueTypeNodes > 0
167 ? totalNodeBytes / stats.uniqueTypeNodes
173 stats.estimatedSavedNodes = (totalRefs > stats.uniqueTypeNodes)
174 ? (totalRefs - stats.uniqueTypeNodes)
178 stats.estimatedSavedBytes = stats.estimatedSavedNodes * avgNodeBytes;
181 stats.deduplicationRatio = stats.uniqueTypeNodes > 0
182 ?
static_cast<double>(stats.totalTypeReferences) / stats.uniqueTypeNodes
186 std::size_t wouldHaveUsed = totalRefs * avgNodeBytes;
187 std::size_t actuallyUsed = totalNodeBytes;
188 stats.savingsPercent = wouldHaveUsed > 0
189 ? 100.0 *
static_cast<double>(wouldHaveUsed - actuallyUsed) / wouldHaveUsed
195void AstContext::printTypeDeduplicationStats(
const char *label)
const {
196 auto stats = getTypeDeduplicationStats();
199 std::cerr <<
"========== Type Node Sharing Statistics";
201 std::cerr <<
" [" << label <<
"]";
203 std::cerr <<
" ==========\n";
204 std::cerr << std::fixed << std::setprecision(2);
205 std::cerr <<
" Unique type AstNodes: " << stats.uniqueTypeNodes <<
"\n";
206 std::cerr <<
" AstViewNode references: " << stats.totalTypeReferences <<
"\n";
207 std::cerr <<
" Nodes avoided by sharing: " << stats.estimatedSavedNodes <<
"\n";
208 std::cerr <<
" Estimated memory saved: " << stats.estimatedSavedBytes / 1024.0 <<
" KB\n";
209 std::cerr <<
" Sharing ratio: " << stats.deduplicationRatio <<
"x\n";
210 std::cerr <<
" Savings percentage: " << stats.savingsPercent <<
"%\n";
211 std::cerr <<
"=======================================================\n\n";
AST data structures and memory management.
nlohmann::basic_json< std::map, std::vector, InternedString, bool, int64_t, uint64_t, double, std::allocator, nlohmann::adl_serializer, std::vector< uint8_t > > AcavJson
Custom JSON type using InternedString for automatic string deduplication.
Cross-platform memory profiling utility.
AstNode * findTypeNode(const void *typePtr) const
Find existing deduplicated Type node (or nullptr).
AstViewNode * createAstViewNode(AstNode *node)
Create a new AST view node wrapping data.
void finalizeLocationIndex()
Finalize location index (call after all nodes indexed).
void indexNode(AstViewNode *node)
Add node to location index.
AstNode * getOrCreateTypeNode(const void *typePtr, AcavJson properties, const SourceRange &range)
Get or create deduplicated Type node.
AstNode * createAstNode(AcavJson properties, const SourceRange &range)
Create a new AST data node.
Pure data container for AST node properties.
Represents node in AST tree hierarchy.
void setParent(AstViewNode *parent)
Set parent node.
void addChild(AstViewNode *child)
Add child node.
static void checkpoint(const QString &label)
Log current memory usage with a label.
Represents a span of source code (begin to end).