[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().
This commit is contained in:
Timm Baeder 2025-09-02 17:57:18 +02:00 committed by GitHub
parent bde2abd3a6
commit e96ff4530f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 5 deletions

View File

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

View File

@ -115,7 +115,13 @@ public:
void setEvalLocation(SourceLocation SL) { this->EvalLocation = SL; }
DynamicAllocator &getAllocator() { return Alloc; }
DynamicAllocator &getAllocator() {
if (!Alloc) {
Alloc = std::make_unique<DynamicAllocator>();
}
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<DynamicAllocator> Alloc;
public:
/// Reference to the module containing all bytecode.