Most AST nodes are allocated with new (ctx) SomeNode(...)
(e.g. TupleElementExpr
, ErrorExpr
, ...), which calls SomeNode::operator new
, and then ASTContext::Allocate
, AlignedAlloc
and posix_memalign
. But when I try to find the corresponding AlignedFree
and free
, I find nothing. I feel like AST has a memory leak. What did I miss?
In the destructor ASTContext::~ASTContext()
. I don't think there is any way to deallocate individual things:
(The doc comments here are from Clang, but the same points apply,
Swiftc also has a `llvm::BumpPtrAllocator Allocator` in its implementation.)
/// The allocator used to create AST objects.
///
/// AST objects are never destructed; rather, all memory associated with the
/// AST objects will be released when the ASTContext itself is destroyed.
mutable llvm::BumpPtrAllocator BumpAlloc;
/// Placement delete companion to the new above.
///
/// This operator is just a companion to the new above. There is no way of
/// invoking it directly; see the new operator for more details. This operator
/// is called implicitly by the compiler if a placement new expression using
/// the ASTContext throws in the object constructor.
inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
C.Deallocate(Ptr);
}
void Deallocate(void *Ptr) const {}
1 Like
Oh I see, I was confused by LangOpts.UseMalloc
, I didn't realize it was actually false
by default. Thanks.
// ASTContext::Allocate
void *Allocate(unsigned long bytes, unsigned alignment,
AllocationArena arena = AllocationArena::Permanent) const {
if (bytes == 0)
return nullptr;
if (LangOpts.UseMalloc)
return AlignedAlloc(bytes, alignment);
if (arena == AllocationArena::Permanent && Stats)
Stats->getFrontendCounters().NumASTBytesAllocated += bytes;
return getAllocator(arena).Allocate(bytes, alignment);
}