Fix http://llvm.org/PR4822: allow module deletion after a function has been
compiled.

When functions are compiled, they accumulate references in the JITResolver's
stub maps. This patch removes those references when the functions are
destroyed.  It's illegal to destroy a Function when any thread may still try to
call its machine code.

This patch also updates r83987 to use ValueMap instead of explicit CallbackVHs
and fixes a couple "do stuff inside assert()" bugs from r84522.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84975 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 053d960..16808a7 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -117,8 +117,7 @@
 
 void *ExecutionEngineState::RemoveMapping(
   const MutexGuard &, const GlobalValue *ToUnmap) {
-  std::map<MapUpdatingCVH, void *>::iterator I =
-    GlobalAddressMap.find(getVH(ToUnmap));
+  GlobalAddressMapTy::iterator I = GlobalAddressMap.find(ToUnmap);
   void *OldVal;
   if (I == GlobalAddressMap.end())
     OldVal = 0;
@@ -141,7 +140,7 @@
 
   DEBUG(errs() << "JIT: Map \'" << GV->getName() 
         << "\' to [" << Addr << "]\n";);
-  void *&CurVal = EEState.getGlobalAddressMap(locked)[EEState.getVH(GV)];
+  void *&CurVal = EEState.getGlobalAddressMap(locked)[GV];
   assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
   CurVal = Addr;
   
@@ -183,7 +182,7 @@
 void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
   MutexGuard locked(lock);
 
-  std::map<ExecutionEngineState::MapUpdatingCVH, void *> &Map =
+  ExecutionEngineState::GlobalAddressMapTy &Map =
     EEState.getGlobalAddressMap(locked);
 
   // Deleting from the mapping?
@@ -191,7 +190,7 @@
     return EEState.RemoveMapping(locked, GV);
   }
   
-  void *&CurVal = Map[EEState.getVH(GV)];
+  void *&CurVal = Map[GV];
   void *OldVal = CurVal;
 
   if (CurVal && !EEState.getGlobalAddressReverseMap(locked).empty())
@@ -214,8 +213,8 @@
 void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
   MutexGuard locked(lock);
   
-  std::map<ExecutionEngineState::MapUpdatingCVH, void*>::iterator I =
-    EEState.getGlobalAddressMap(locked).find(EEState.getVH(GV));
+  ExecutionEngineState::GlobalAddressMapTy::iterator I =
+    EEState.getGlobalAddressMap(locked).find(GV);
   return I != EEState.getGlobalAddressMap(locked).end() ? I->second : 0;
 }
 
@@ -227,7 +226,7 @@
 
   // If we haven't computed the reverse mapping yet, do so first.
   if (EEState.getGlobalAddressReverseMap(locked).empty()) {
-    for (std::map<ExecutionEngineState::MapUpdatingCVH, void *>::iterator
+    for (ExecutionEngineState::GlobalAddressMapTy::iterator
          I = EEState.getGlobalAddressMap(locked).begin(),
          E = EEState.getGlobalAddressMap(locked).end(); I != E; ++I)
       EEState.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second,
@@ -476,7 +475,7 @@
     return getPointerToFunction(F);
 
   MutexGuard locked(lock);
-  void *p = EEState.getGlobalAddressMap(locked)[EEState.getVH(GV)];
+  void *p = EEState.getGlobalAddressMap(locked)[GV];
   if (p)
     return p;
 
@@ -486,7 +485,7 @@
     EmitGlobalVariable(GVar);
   else
     llvm_unreachable("Global hasn't had an address allocated yet!");
-  return EEState.getGlobalAddressMap(locked)[EEState.getVH(GV)];
+  return EEState.getGlobalAddressMap(locked)[GV];
 }
 
 /// This function converts a Constant* into a GenericValue. The interesting 
@@ -1072,17 +1071,22 @@
   ++NumGlobals;
 }
 
-ExecutionEngineState::MapUpdatingCVH::MapUpdatingCVH(
-  ExecutionEngineState &EES, const GlobalValue *GV)
-  : CallbackVH(const_cast<GlobalValue*>(GV)), EES(EES) {}
-
-void ExecutionEngineState::MapUpdatingCVH::deleted() {
-  MutexGuard locked(EES.EE.lock);
-  EES.RemoveMapping(locked, *this);  // Destroys *this.
+ExecutionEngineState::ExecutionEngineState(ExecutionEngine &EE)
+  : EE(EE), GlobalAddressMap(this) {
 }
 
-void ExecutionEngineState::MapUpdatingCVH::allUsesReplacedWith(
-  Value *new_value) {
+sys::Mutex *ExecutionEngineState::AddressMapConfig::getMutex(
+  ExecutionEngineState *EES) {
+  return &EES->EE.lock;
+}
+void ExecutionEngineState::AddressMapConfig::onDelete(
+  ExecutionEngineState *EES, const GlobalValue *Old) {
+  void *OldVal = EES->GlobalAddressMap.lookup(Old);
+  EES->GlobalAddressReverseMap.erase(OldVal);
+}
+
+void ExecutionEngineState::AddressMapConfig::onRAUW(
+  ExecutionEngineState *, const GlobalValue *, const GlobalValue *) {
   assert(false && "The ExecutionEngine doesn't know how to handle a"
          " RAUW on a value it has a global mapping for.");
 }