Clarify the ownership model of LLVMContext and Module. Namely, contexts own
authorOwen Anderson <resistor@mac.com>
Wed, 8 Sep 2010 18:03:32 +0000 (18:03 +0000)
committerOwen Anderson <resistor@mac.com>
Wed, 8 Sep 2010 18:03:32 +0000 (18:03 +0000)
modules are instantiated in them.  If the context is deleted, all of its owned
modules are also deleted.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113374 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/LLVMContext.h
lib/VMCore/LLVMContext.cpp
lib/VMCore/LLVMContextImpl.cpp
lib/VMCore/LLVMContextImpl.h
lib/VMCore/Module.cpp

index 7cb6579aef661a4168254df8dd0f2f6329279117..76492b7102e77a8dde4b71430de2f3b3f6ce404c 100644 (file)
@@ -20,6 +20,7 @@ namespace llvm {
 class LLVMContextImpl;
 class StringRef;
 class Instruction;
+class Module;
 template <typename T> class SmallVectorImpl;
 
 /// This is an important class for using LLVM in a threaded context.  It
@@ -37,6 +38,13 @@ public:
   LLVMContext();
   ~LLVMContext();
   
+  /// addModule - Register a module as being instantiated in this context.  If
+  /// the context is deleted, the module will be deleted as well.
+  void addModule(Module*);
+  
+  /// removeModule - Unregister a module from this context.
+  void removeModule(Module*);
+  
   // Pinned metadata names, which always have the same value.  This is a
   // compile-time performance optimization, not a correctness optimization.
   enum {
index 563c651315a3370f1ea6f69b4a010c82dc8ca7ff..60fb830e9b57f3c896c32f00db1d7c5f2d89d55a 100644 (file)
@@ -34,6 +34,14 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
 }
 LLVMContext::~LLVMContext() { delete pImpl; }
 
+void LLVMContext::addModule(Module *M) {
+  pImpl->OwnedModules.insert(M);
+}
+
+void LLVMContext::removeModule(Module *M) {
+  pImpl->OwnedModules.erase(M);
+}
+
 //===----------------------------------------------------------------------===//
 // Recoverable Backend Errors
 //===----------------------------------------------------------------------===//
index 93a075f0fccbb461a38f6c6b3e2c72c35d0d35dd..610c5027c345ec3f8c82f540aefdbb65c81e87ff 100644 (file)
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "LLVMContextImpl.h"
+#include "llvm/Module.h"
 #include <algorithm>
 using namespace llvm;
 
@@ -51,6 +52,15 @@ struct DropReferences {
 }
 
 LLVMContextImpl::~LLVMContextImpl() {
+  // NOTE: We need to delete the contents of OwnedModules, but we have to
+  // duplicate it into a temporary vector, because the destructor of Module
+  // will try to remove itself from OwnedModules set.  This would cause
+  // iterator invalidation if we iterated on the set directly.
+  std::vector<Module*> Modules(OwnedModules.begin(), OwnedModules.end());
+  for (std::vector<Module*>::iterator I = Modules.begin(), E = Modules.end();
+       I != E; ++I)
+    delete *I;
+  
   std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
                 DropReferences());
   std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),
index 51b2992898c024fcc19775c10e69cfe6b3748276..6df804ab084430179698994fa96267fe55076538 100644 (file)
@@ -115,6 +115,10 @@ public:
   
 class LLVMContextImpl {
 public:
+  /// OwnedModules - The set of modules instantiated in this context, and which
+  /// will be automatically deleted if this context is deleted.
+  SmallPtrSet<Module*, 4> OwnedModules;
+  
   void *InlineAsmDiagHandler, *InlineAsmDiagContext;
   
   typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, 
index d7ddf96cb0700c3ae3764396beeddbf4da3790c1..341e527acb5b4150770ca2b59e6d223d9211cea1 100644 (file)
@@ -62,9 +62,11 @@ Module::Module(StringRef MID, LLVMContext& C)
   ValSymTab = new ValueSymbolTable();
   TypeSymTab = new TypeSymbolTable();
   NamedMDSymTab = new StringMap<NamedMDNode *>();
+  Context.addModule(this);
 }
 
 Module::~Module() {
+  Context.removeModule(this);
   dropAllReferences();
   GlobalList.clear();
   FunctionList.clear();