llvm.org GIT mirror llvm / c89d27a
ExecutionEngine::clearGlobalMappingsFromModule failed to remove reverse 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 Jeffrey Yasskin 10 years ago
3 changed file(s) with 42 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
6060 getGlobalAddressReverseMap(const MutexGuard &) {
6161 return GlobalAddressReverseMap;
6262 }
63
64 // Returns the address ToUnmap was mapped to.
65 void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap);
6366 };
6467
6568
112112 }
113113
114114
115 void *ExecutionEngineState::RemoveMapping(
116 const MutexGuard &, const GlobalValue *ToUnmap) {
117 std::map, void *>::iterator I =
118 GlobalAddressMap.find(ToUnmap);
119 void *OldVal;
120 if (I == GlobalAddressMap.end())
121 OldVal = 0;
122 else {
123 OldVal = I->second;
124 GlobalAddressMap.erase(I);
125 }
126
127 GlobalAddressReverseMap.erase(OldVal);
128 return OldVal;
129 }
130
115131 /// addGlobalMapping - Tell the execution engine that the specified global is
116132 /// at the specified location. This is used internally as functions are JIT'd
117133 /// and as global variables are laid out in memory. It can and should also be
150166 MutexGuard locked(lock);
151167
152168 for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
153 state.getGlobalAddressMap(locked).erase(&*FI);
154 state.getGlobalAddressReverseMap(locked).erase(&*FI);
169 state.RemoveMapping(locked, FI);
155170 }
156171 for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
157172 GI != GE; ++GI) {
158 state.getGlobalAddressMap(locked).erase(&*GI);
159 state.getGlobalAddressReverseMap(locked).erase(&*GI);
173 state.RemoveMapping(locked, GI);
160174 }
161175 }
162176
171185
172186 // Deleting from the mapping?
173187 if (Addr == 0) {
174 std::map, void *>::iterator I = Map.find(GV);
175 void *OldVal;
176 if (I == Map.end())
177 OldVal = 0;
178 else {
179 OldVal = I->second;
180 Map.erase(I);
181 }
182
183 if (!state.getGlobalAddressReverseMap(locked).empty())
184 state.getGlobalAddressReverseMap(locked).erase(OldVal);
185 return OldVal;
188 return state.RemoveMapping(locked, GV);
186189 }
187190
188191 void *&CurVal = Map[GV];
9292 << " now-free address.";
9393 }
9494
95 TEST_F(ExecutionEngineTest, ClearModuleMappings) {
96 GlobalVariable *G1 =
97 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
98
99 int32_t Mem1 = 3;
100 Engine->addGlobalMapping(G1, &Mem1);
101 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
102
103 Engine->clearGlobalMappingsFromModule(M);
104
105 EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
106
107 GlobalVariable *G2 =
108 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
109 // After clearing the module mappings, we can assign a new GV to the
110 // same address.
111 Engine->addGlobalMapping(G2, &Mem1);
112 EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
95113 }
114
115 }