From e96ff4530fa0111fccf2687a4e2a55bbe0f73554 Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Tue, 2 Sep 2025 17:57:18 +0200 Subject: [PATCH] [clang][bytecode] Lazily create DynamicAllocator (#155831) Due to all the tracking via map(s) and a BumpPtrAllocator, the creating and destroying the DynamicAllocator is rather expensive. Try to do it lazily and only create it when first calling InterpState::getAllocator(). --- clang/lib/AST/ByteCode/InterpState.cpp | 10 +++++++--- clang/lib/AST/ByteCode/InterpState.h | 10 ++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp index a2a1e5826d7c..4bafb8974185 100644 --- a/clang/lib/AST/ByteCode/InterpState.cpp +++ b/clang/lib/AST/ByteCode/InterpState.cpp @@ -59,7 +59,8 @@ InterpState::~InterpState() { void InterpState::cleanup() { // As a last resort, make sure all pointers still pointing to a dead block // don't point to it anymore. - Alloc.cleanup(); + if (Alloc) + Alloc->cleanup(); } Frame *InterpState::getCurrentFrame() { return Current; } @@ -99,10 +100,13 @@ void InterpState::deallocate(Block *B) { } bool InterpState::maybeDiagnoseDanglingAllocations() { - bool NoAllocationsLeft = !Alloc.hasAllocations(); + if (!Alloc) + return true; + + bool NoAllocationsLeft = !Alloc->hasAllocations(); if (!checkingPotentialConstantExpression()) { - for (const auto &[Source, Site] : Alloc.allocation_sites()) { + for (const auto &[Source, Site] : Alloc->allocation_sites()) { assert(!Site.empty()); CCEDiag(Source->getExprLoc(), diag::note_constexpr_memory_leak) diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h index f123a1f169c0..1e4c0701723c 100644 --- a/clang/lib/AST/ByteCode/InterpState.h +++ b/clang/lib/AST/ByteCode/InterpState.h @@ -115,7 +115,13 @@ public: void setEvalLocation(SourceLocation SL) { this->EvalLocation = SL; } - DynamicAllocator &getAllocator() { return Alloc; } + DynamicAllocator &getAllocator() { + if (!Alloc) { + Alloc = std::make_unique(); + } + + return *Alloc.get(); + } /// Diagnose any dynamic allocations that haven't been freed yet. /// Will return \c false if there were any allocations to diagnose, @@ -161,7 +167,7 @@ private: /// Reference to the offset-source mapping. SourceMapper *M; /// Allocator used for dynamic allocations performed via the program. - DynamicAllocator Alloc; + std::unique_ptr Alloc; public: /// Reference to the module containing all bytecode.