+char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) {
+ const Type *ElTy = GV->getType()->getElementType();
+ size_t GVSize = (size_t)getTargetData()->getTypePaddedSize(ElTy);
+ return new char[GVSize];
+}
+
+/// removeModuleProvider - Remove a ModuleProvider from the list of modules.
+/// Relases the Module from the ModuleProvider, materializing it in the
+/// process, and returns the materialized Module.
+Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P,
+ std::string *ErrInfo) {
+ for(SmallVector<ModuleProvider *, 1>::iterator I = Modules.begin(),
+ E = Modules.end(); I != E; ++I) {
+ ModuleProvider *MP = *I;
+ if (MP == P) {
+ Modules.erase(I);
+ clearGlobalMappingsFromModule(MP->getModule());
+ return MP->releaseModule(ErrInfo);
+ }
+ }
+ return NULL;
+}
+
+/// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
+/// and deletes the ModuleProvider and owned Module. Avoids materializing
+/// the underlying module.
+void ExecutionEngine::deleteModuleProvider(ModuleProvider *P,
+ std::string *ErrInfo) {
+ for(SmallVector<ModuleProvider *, 1>::iterator I = Modules.begin(),
+ E = Modules.end(); I != E; ++I) {
+ ModuleProvider *MP = *I;
+ if (MP == P) {
+ Modules.erase(I);
+ clearGlobalMappingsFromModule(MP->getModule());
+ delete MP;
+ return;
+ }
+ }
+}
+
+/// FindFunctionNamed - Search all of the active modules to find the one that
+/// defines FnName. This is very slow operation and shouldn't be used for
+/// general code.
+Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
+ for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
+ if (Function *F = Modules[i]->getModule()->getFunction(FnName))
+ return F;
+ }
+ return 0;
+}
+
+
+/// 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
+/// used by clients of the EE that want to have an LLVM global overlay
+/// existing data in memory.
+void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) {
+ MutexGuard locked(lock);
+
+ DOUT << "JIT: Map \'" << GV->getNameStart() << "\' to [" << Addr << "]\n";
+ void *&CurVal = state.getGlobalAddressMap(locked)[GV];
+ assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
+ CurVal = Addr;
+
+ // If we are using the reverse mapping, add it too
+ if (!state.getGlobalAddressReverseMap(locked).empty()) {
+ const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr];
+ assert((V == 0 || GV == 0) && "GlobalMapping already established!");
+ V = GV;
+ }
+}
+
+/// clearAllGlobalMappings - Clear all global mappings and start over again
+/// use in dynamic compilation scenarios when you want to move globals
+void ExecutionEngine::clearAllGlobalMappings() {
+ MutexGuard locked(lock);
+
+ state.getGlobalAddressMap(locked).clear();
+ state.getGlobalAddressReverseMap(locked).clear();
+}
+
+/// clearGlobalMappingsFromModule - Clear all global mappings that came from a
+/// particular module, because it has been removed from the JIT.
+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);
+ }
+ 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);
+ }
+}
+
+/// updateGlobalMapping - Replace an existing mapping for GV with a new
+/// address. This updates both maps as required. If "Addr" is null, the
+/// entry for the global is removed from the mappings.
+void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
+ MutexGuard locked(lock);
+
+ std::map<const GlobalValue*, void *> &Map = state.getGlobalAddressMap(locked);
+
+ // Deleting from the mapping?
+ if (Addr == 0) {
+ std::map<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(Addr);
+ return OldVal;
+ }
+
+ void *&CurVal = Map[GV];
+ void *OldVal = CurVal;
+
+ if (CurVal && !state.getGlobalAddressReverseMap(locked).empty())
+ state.getGlobalAddressReverseMap(locked).erase(CurVal);
+ CurVal = Addr;
+
+ // If we are using the reverse mapping, add it too
+ if (!state.getGlobalAddressReverseMap(locked).empty()) {
+ const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr];
+ assert((V == 0 || GV == 0) && "GlobalMapping already established!");
+ V = GV;
+ }
+ return OldVal;
+}
+
+/// getPointerToGlobalIfAvailable - This returns the address of the specified
+/// global value if it is has already been codegen'd, otherwise it returns null.
+///
+void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
+ MutexGuard locked(lock);
+
+ std::map<const GlobalValue*, void*>::iterator I =
+ state.getGlobalAddressMap(locked).find(GV);
+ return I != state.getGlobalAddressMap(locked).end() ? I->second : 0;