llvm.org GIT mirror llvm / 4c5b23b
Make the ExecutionEngine automatically remove global mappings on when their GlobalValue is destroyed. Function destruction still leaks machine code and can crash on leaked stubs, but this is some progress. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83987 91177308-0d34-0410-b5e6-96231b3b80d8 Jeffrey Yasskin 10 years ago
3 changed file(s) with 106 addition(s) and 53 deletion(s). Raw diff Collapse all Expand all
1818 #include
1919 #include
2020 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/Support/ValueHandle.h"
2122 #include "llvm/System/Mutex.h"
2223 #include "llvm/Target/TargetMachine.h"
2324
2526
2627 struct GenericValue;
2728 class Constant;
29 class ExecutionEngine;
2830 class Function;
2931 class GlobalVariable;
3032 class GlobalValue;
3638 class MutexGuard;
3739 class TargetData;
3840 class Type;
39 template class AssertingVH;
4041
4142 class ExecutionEngineState {
43 public:
44 class MapUpdatingCVH : public CallbackVH {
45 ExecutionEngineState &EES;
46
47 public:
48 MapUpdatingCVH(ExecutionEngineState &EES, const GlobalValue *GV);
49
50 operator const GlobalValue*() const {
51 return cast(getValPtr());
52 }
53
54 virtual void deleted();
55 virtual void allUsesReplacedWith(Value *new_value);
56 };
57
4258 private:
59 ExecutionEngine ⅇ
60
4361 /// GlobalAddressMap - A mapping between LLVM global values and their
4462 /// actualized version...
45 std::map<AssertingVH, void *> GlobalAddressMap;
63 std::map<MapUpdatingCVH, void *> GlobalAddressMap;
4664
4765 /// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap,
4866 /// used to convert raw addresses into the LLVM global value that is emitted
5169 std::map > GlobalAddressReverseMap;
5270
5371 public:
54 std::map, void *> &
72 ExecutionEngineState(ExecutionEngine &EE) : EE(EE) {}
73
74 MapUpdatingCVH getVH(const GlobalValue *GV) {
75 return MapUpdatingCVH(*this, GV);
76 }
77
78 std::map &
5579 getGlobalAddressMap(const MutexGuard &) {
5680 return GlobalAddressMap;
5781 }
6892
6993 class ExecutionEngine {
7094 const TargetData *TD;
71 ExecutionEngineState state;
95 ExecutionEngineState EEState;
7296 bool LazyCompilationDisabled;
7397 bool GVCompilationDisabled;
7498 bool SymbolSearchingDisabled;
212236 /// at the specified location. This is used internally as functions are JIT'd
213237 /// and as global variables are laid out in memory. It can and should also be
214238 /// used by clients of the EE that want to have an LLVM global overlay
215 /// existing data in memory. After adding a mapping for GV, you must not
216 /// destroy it until you've removed the mapping.
239 /// existing data in memory. Mappings are automatically removed when their
240 /// GlobalValue is destroyed.
217241 void addGlobalMapping(const GlobalValue *GV, void *Addr);
218242
219243 /// clearAllGlobalMappings - Clear all global mappings and start over again
237261 void *getPointerToGlobalIfAvailable(const GlobalValue *GV);
238262
239263 /// getPointerToGlobal - This returns the address of the specified global
240 /// value. This may involve code generation if it's a function. After
241 /// getting a pointer to GV, it and all globals it transitively refers to have
242 /// been passed to addGlobalMapping. You must clear the mapping for each
243 /// referred-to global before destroying it. If a referred-to global RTG is a
244 /// function and this ExecutionEngine is a JIT compiler, calling
245 /// updateGlobalMapping(RTG, 0) will leak the function's machine code, so you
246 /// should call freeMachineCodeForFunction(RTG) instead. Note that
247 /// optimizations can move and delete non-external GlobalValues without
248 /// notifying the ExecutionEngine.
264 /// value. This may involve code generation if it's a function.
249265 ///
250266 void *getPointerToGlobal(const GlobalValue *GV);
251267
252268 /// getPointerToFunction - The different EE's represent function bodies in
253269 /// different ways. They should each implement this to say what a function
254 /// pointer should look like. See getPointerToGlobal for the requirements on
255 /// destroying F and any GlobalValues it refers to.
270 /// pointer should look like. When F is destroyed, the ExecutionEngine will
271 /// remove its global mapping but will not yet free its machine code. Call
272 /// freeMachineCodeForFunction(F) explicitly to do that. Note that global
273 /// optimizations can destroy Functions without notifying the ExecutionEngine.
256274 ///
257275 virtual void *getPointerToFunction(Function *F) = 0;
258276
259277 /// getPointerToFunctionOrStub - If the specified function has been
260278 /// code-gen'd, return a pointer to the function. If not, compile it, or use
261 /// a stub to implement lazy compilation if available. See getPointerToGlobal
262 /// for the requirements on destroying F and any GlobalValues it refers to.
279 /// a stub to implement lazy compilation if available. See
280 /// getPointerToFunction for the requirements on destroying F.
263281 ///
264282 virtual void *getPointerToFunctionOrStub(Function *F) {
265283 // Default implementation, just codegen the function.
295313
296314 /// getOrEmitGlobalVariable - Return the address of the specified global
297315 /// variable, possibly emitting it to memory if needed. This is used by the
298 /// Emitter. See getPointerToGlobal for the requirements on destroying GV and
299 /// any GlobalValues it refers to.
316 /// Emitter.
300317 virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) {
301318 return getPointerToGlobal((GlobalValue*)GV);
302319 }
470487
471488 };
472489
490 inline bool operator<(const ExecutionEngineState::MapUpdatingCVH& lhs,
491 const ExecutionEngineState::MapUpdatingCVH& rhs) {
492 return static_cast(lhs) <
493 static_cast(rhs);
494 }
495
473496 } // End llvm namespace
474497
475498 #endif
4545 ExecutionEngine::EERegisterFn ExecutionEngine::ExceptionTableRegister = 0;
4646
4747
48 ExecutionEngine::ExecutionEngine(ModuleProvider *P) : LazyFunctionCreator(0) {
48 ExecutionEngine::ExecutionEngine(ModuleProvider *P)
49 : EEState(*this),
50 LazyFunctionCreator(0) {
4951 LazyCompilationDisabled = false;
5052 GVCompilationDisabled = false;
5153 SymbolSearchingDisabled = false;
114116
115117 void *ExecutionEngineState::RemoveMapping(
116118 const MutexGuard &, const GlobalValue *ToUnmap) {
117 std::map, void *>::iterator I =
118 GlobalAddressMap.find(ToUnmap);
119 std::map::iterator I =
120 GlobalAddressMap.find(getVH(ToUnmap));
119121 void *OldVal;
120122 if (I == GlobalAddressMap.end())
121123 OldVal = 0;
138140
139141 DEBUG(errs() << "JIT: Map \'" << GV->getName()
140142 << "\' to [" << Addr << "]\n";);
141 void *&CurVal = state.getGlobalAddressMap(locked)[GV];
143 void *&CurVal = EEState.getGlobalAddressMap(locked)[EEState.getVH(GV)];
142144 assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
143145 CurVal = Addr;
144146
145147 // If we are using the reverse mapping, add it too
146 if (!state.getGlobalAddressReverseMap(locked).empty()) {
148 if (!EEState.getGlobalAddressReverseMap(locked).empty()) {
147149 AssertingVH &V =
148 state.getGlobalAddressReverseMap(locked)[Addr];
150 EEState.getGlobalAddressReverseMap(locked)[Addr];
149151 assert((V == 0 || GV == 0) && "GlobalMapping already established!");
150152 V = GV;
151153 }
156158 void ExecutionEngine::clearAllGlobalMappings() {
157159 MutexGuard locked(lock);
158160
159 state.getGlobalAddressMap(locked).clear();
160 state.getGlobalAddressReverseMap(locked).clear();
161 EEState.getGlobalAddressMap(locked).clear();
162 EEState.getGlobalAddressReverseMap(locked).clear();
161163 }
162164
163165 /// clearGlobalMappingsFromModule - Clear all global mappings that came from a
166168 MutexGuard locked(lock);
167169
168170 for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
169 state.RemoveMapping(locked, FI);
171 EEState.RemoveMapping(locked, FI);
170172 }
171173 for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
172174 GI != GE; ++GI) {
173 state.RemoveMapping(locked, GI);
175 EEState.RemoveMapping(locked, GI);
174176 }
175177 }
176178
180182 void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
181183 MutexGuard locked(lock);
182184
183 std::map, void *> &Map =
184 state.getGlobalAddressMap(locked);
185 std::map &Map =
186 EEState.getGlobalAddressMap(locked);
185187
186188 // Deleting from the mapping?
187189 if (Addr == 0) {
188 return state.RemoveMapping(locked, GV);
189 }
190
191 void *&CurVal = Map[GV];
190 return EEState.RemoveMapping(locked, GV);
191 }
192
193 void *&CurVal = Map[EEState.getVH(GV)];
192194 void *OldVal = CurVal;
193195
194 if (CurVal && !state.getGlobalAddressReverseMap(locked).empty())
195 state.getGlobalAddressReverseMap(locked).erase(CurVal);
196 if (CurVal && !EEState.getGlobalAddressReverseMap(locked).empty())
197 EEState.getGlobalAddressReverseMap(locked).erase(CurVal);
196198 CurVal = Addr;
197199
198200 // If we are using the reverse mapping, add it too
199 if (!state.getGlobalAddressReverseMap(locked).empty()) {
201 if (!EEState.getGlobalAddressReverseMap(locked).empty()) {
200202 AssertingVH &V =
201 state.getGlobalAddressReverseMap(locked)[Addr];
203 EEState.getGlobalAddressReverseMap(locked)[Addr];
202204 assert((V == 0 || GV == 0) && "GlobalMapping already established!");
203205 V = GV;
204206 }
211213 void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
212214 MutexGuard locked(lock);
213215
214 std::map, void*>::iterator I =
215 state.getGlobalAddressMap(locked).find(GV);
216 return I != state.getGlobalAddressMap(locked).end() ? I->second : 0;
216 std::map::iterator I =
217 EEState.getGlobalAddressMap(locked).find(EEState.getVH(GV));
218 return I != EEState.getGlobalAddressMap(locked).end() ? I->second : 0;
217219 }
218220
219221 /// getGlobalValueAtAddress - Return the LLVM global value object that starts
223225 MutexGuard locked(lock);
224226
225227 // If we haven't computed the reverse mapping yet, do so first.
226 if (state.getGlobalAddressReverseMap(locked).empty()) {
227 for (std::map, void *>::iterator
228 I = state.getGlobalAddressMap(locked).begin(),
229 E = state.getGlobalAddressMap(locked).end(); I != E; ++I)
230 state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second,
228 if (EEState.getGlobalAddressReverseMap(locked).empty()) {
229 for (std::map::iterator
230 I = EEState.getGlobalAddressMap(locked).begin(),
231 E = EEState.getGlobalAddressMap(locked).end(); I != E; ++I)
232 EEState.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second,
231233 I->first));
232234 }
233235
234236 std::map >::iterator I =
235 state.getGlobalAddressReverseMap(locked).find(Addr);
236 return I != state.getGlobalAddressReverseMap(locked).end() ? I->second : 0;
237 EEState.getGlobalAddressReverseMap(locked).find(Addr);
238 return I != EEState.getGlobalAddressReverseMap(locked).end() ? I->second : 0;
237239 }
238240
239241 // CreateArgv - Turn a vector of strings into a nice argv style array of
473475 return getPointerToFunction(F);
474476
475477 MutexGuard locked(lock);
476 void *p = state.getGlobalAddressMap(locked)[GV];
478 void *p = EEState.getGlobalAddressMap(locked)[EEState.getVH(GV)];
477479 if (p)
478480 return p;
479481
483485 EmitGlobalVariable(GVar);
484486 else
485487 llvm_unreachable("Global hasn't had an address allocated yet!");
486 return state.getGlobalAddressMap(locked)[GV];
488 return EEState.getGlobalAddressMap(locked)[EEState.getVH(GV)];
487489 }
488490
489491 /// This function converts a Constant* into a GenericValue. The interesting
10681070 NumInitBytes += (unsigned)GVSize;
10691071 ++NumGlobals;
10701072 }
1073
1074 ExecutionEngineState::MapUpdatingCVH::MapUpdatingCVH(
1075 ExecutionEngineState &EES, const GlobalValue *GV)
1076 : CallbackVH(const_cast(GV)), EES(EES) {}
1077
1078 void ExecutionEngineState::MapUpdatingCVH::deleted() {
1079 MutexGuard locked(EES.EE.lock);
1080 EES.RemoveMapping(locked, *this); // Destroys *this.
1081 }
1082
1083 void ExecutionEngineState::MapUpdatingCVH::allUsesReplacedWith(
1084 Value *new_value) {
1085 assert(false && "The ExecutionEngine doesn't know how to handle a"
1086 " RAUW on a value it has a global mapping for.");
1087 }
112112 EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
113113 }
114114
115 TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
116 GlobalVariable *G1 =
117 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
118 int32_t Mem1 = 3;
119 Engine->addGlobalMapping(G1, &Mem1);
120 // Make sure the reverse mapping is enabled.
121 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
122 // When the GV goes away, the ExecutionEngine should remove any
123 // mappings that refer to it.
124 G1->eraseFromParent();
125 EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
115126 }
127
128 }