ExecutionEngine::clearGlobalMappingsFromModule failed to remove reverse
authorJeffrey Yasskin <jyasskin@google.com>
Fri, 9 Oct 2009 22:10:27 +0000 (22:10 +0000)
committerJeffrey Yasskin <jyasskin@google.com>
Fri, 9 Oct 2009 22:10:27 +0000 (22:10 +0000)
mappings, which could cause errors and assert-failures.  This patch fixes that,
adds a test, and refactors the global-mapping-removal code into a single place.

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

include/llvm/ExecutionEngine/ExecutionEngine.h
lib/ExecutionEngine/ExecutionEngine.cpp
unittests/ExecutionEngine/ExecutionEngineTest.cpp

index 6a3a9144d574db939da72fe690bd7d5adfe292e4..cf2df6b8326b50a1f8090b81bf3c253c49376a20 100644 (file)
@@ -61,6 +61,9 @@ public:
   getGlobalAddressReverseMap(const MutexGuard &) {
     return GlobalAddressReverseMap;
   }
+
+  // Returns the address ToUnmap was mapped to.
+  void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap);
 };
 
 
index 52718ebb875be96ecef805d71bfc1c21461e27d5..700ae5ea9c41964bac1e6b16fce2d760d4bb70eb 100644 (file)
@@ -113,6 +113,22 @@ Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
 }
 
 
+void *ExecutionEngineState::RemoveMapping(
+  const MutexGuard &, const GlobalValue *ToUnmap) {
+  std::map<AssertingVH<const GlobalValue>, void *>::iterator I =
+    GlobalAddressMap.find(ToUnmap);
+  void *OldVal;
+  if (I == GlobalAddressMap.end())
+    OldVal = 0;
+  else {
+    OldVal = I->second;
+    GlobalAddressMap.erase(I);
+  }
+
+  GlobalAddressReverseMap.erase(OldVal);
+  return OldVal;
+}
+
 /// addGlobalMapping - Tell the execution engine that the specified global is
 /// at the specified location.  This is used internally as functions are JIT'd
 /// and as global variables are laid out in memory.  It can and should also be
@@ -151,13 +167,11 @@ void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) {
   MutexGuard locked(lock);
   
   for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
-    state.getGlobalAddressMap(locked).erase(&*FI);
-    state.getGlobalAddressReverseMap(locked).erase(&*FI);
+    state.RemoveMapping(locked, FI);
   }
   for (Module::global_iterator GI = M->global_begin(), GE = M->global_end(); 
        GI != GE; ++GI) {
-    state.getGlobalAddressMap(locked).erase(&*GI);
-    state.getGlobalAddressReverseMap(locked).erase(&*GI);
+    state.RemoveMapping(locked, GI);
   }
 }
 
@@ -172,18 +186,7 @@ void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
 
   // Deleting from the mapping?
   if (Addr == 0) {
-    std::map<AssertingVH<const GlobalValue>, void *>::iterator I = Map.find(GV);
-    void *OldVal;
-    if (I == Map.end())
-      OldVal = 0;
-    else {
-      OldVal = I->second;
-      Map.erase(I); 
-    }
-    
-    if (!state.getGlobalAddressReverseMap(locked).empty())
-      state.getGlobalAddressReverseMap(locked).erase(OldVal);
-    return OldVal;
+    return state.RemoveMapping(locked, GV);
   }
   
   void *&CurVal = Map[GV];
index 2106e86b59232f21d371c63af75f3f89bcf4818f..97a8478311400bb130cdbfe6338b2f58cffd4786 100644 (file)
@@ -93,4 +93,24 @@ TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
     << " now-free address.";
 }
 
+TEST_F(ExecutionEngineTest, ClearModuleMappings) {
+  GlobalVariable *G1 =
+      NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
+
+  int32_t Mem1 = 3;
+  Engine->addGlobalMapping(G1, &Mem1);
+  EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
+
+  Engine->clearGlobalMappingsFromModule(M);
+
+  EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+
+  GlobalVariable *G2 =
+      NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
+  // After clearing the module mappings, we can assign a new GV to the
+  // same address.
+  Engine->addGlobalMapping(G2, &Mem1);
+  EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
+}
+
 }