X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FExecutionEngine%2FMCJIT%2FMCJIT.cpp;h=58cf4e5e6dd8c23c88cc4de678c24079ba4ff4f0;hp=f6c3c18a4fd7d5d33afa9283fdce8f414458de50;hb=31862ae54168899c009193ed63f6837b81a51845;hpb=96a8ccfab758dc18a5ca4b65817b38616925ea00 diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index f6c3c18a4fd..58cf4e5e6dd 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -10,10 +10,7 @@ #include "MCJIT.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITEventListener.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" -#include "llvm/ExecutionEngine/ObjectBuffer.h" -#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -22,6 +19,7 @@ #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/PassManager.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" @@ -32,6 +30,8 @@ using namespace llvm; +void ObjectCache::anchor() {} + namespace { static struct RegisterJIT { @@ -75,6 +75,7 @@ MCJIT::MCJIT(std::unique_ptr M, std::unique_ptr tm, OwnedModules.addModule(std::move(First)); setDataLayout(TM->getSubtargetImpl()->getDataLayout()); + RegisterJITEventListener(JITEventListener::createGDBRegistrationListener()); } MCJIT::~MCJIT() { @@ -100,18 +101,21 @@ bool MCJIT::removeModule(Module *M) { } void MCJIT::addObjectFile(std::unique_ptr Obj) { - std::unique_ptr LoadedObject = Dyld.loadObject(std::move(Obj)); - if (!LoadedObject || Dyld.hasError()) + std::unique_ptr L = Dyld.loadObject(*Obj); + if (Dyld.hasError()) report_fatal_error(Dyld.getErrorString()); - LoadedObjects.push_back(std::move(LoadedObject)); + NotifyObjectEmitted(*Obj, *L); - NotifyObjectEmitted(*LoadedObject); + LoadedObjects.push_back(std::move(Obj)); } void MCJIT::addObjectFile(object::OwningBinary Obj) { - addObjectFile(std::move(Obj.getBinary())); - Buffers.push_back(std::move(Obj.getBuffer())); + std::unique_ptr ObjFile; + std::unique_ptr MemBuf; + std::tie(ObjFile, MemBuf) = Obj.takeBinary(); + addObjectFile(std::move(ObjFile)); + Buffers.push_back(std::move(MemBuf)); } void MCJIT::addArchive(object::OwningBinary A) { @@ -123,7 +127,7 @@ void MCJIT::setObjectCache(ObjectCache* NewCache) { ObjCache = NewCache; } -ObjectBufferStream* MCJIT::emitObject(Module *M) { +std::unique_ptr MCJIT::emitObject(Module *M) { MutexGuard locked(lock); // This must be a module which has already been added but not loaded to this @@ -133,33 +137,35 @@ ObjectBufferStream* MCJIT::emitObject(Module *M) { PassManager PM; M->setDataLayout(TM->getSubtargetImpl()->getDataLayout()); - PM.add(new DataLayoutPass(M)); + PM.add(new DataLayoutPass()); // The RuntimeDyld will take ownership of this shortly - std::unique_ptr CompiledObject(new ObjectBufferStream()); + SmallVector ObjBufferSV; + raw_svector_ostream ObjStream(ObjBufferSV); // Turn the machine code intermediate representation into bytes in memory // that may be executed. - if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), - !getVerifyModules())) { + if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules())) report_fatal_error("Target does not support MC emission!"); - } // Initialize passes. PM.run(*M); // Flush the output buffer to get the generated code into memory - CompiledObject->flush(); + ObjStream.flush(); + + std::unique_ptr CompiledObjBuffer( + new ObjectMemoryBuffer(std::move(ObjBufferSV))); // If we have an object cache, tell it about the new object. // Note that we're using the compiled image, not the loaded image (as below). if (ObjCache) { // MemoryBuffer is a thin wrapper around the actual memory, so it's OK // to create a temporary object here and delete it after the call. - MemoryBufferRef MB = CompiledObject->getMemBuffer(); + MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef(); ObjCache->notifyObjectCompiled(M, MB); } - return CompiledObject.release(); + return CompiledObjBuffer; } void MCJIT::generateCodeForModule(Module *M) { @@ -174,34 +180,31 @@ void MCJIT::generateCodeForModule(Module *M) { if (OwnedModules.hasModuleBeenLoaded(M)) return; - std::unique_ptr ObjectToLoad; + std::unique_ptr ObjectToLoad; // Try to load the pre-compiled object from cache if possible - if (ObjCache) { - if (std::unique_ptr PreCompiledObject = - ObjCache->getObject(M)) - ObjectToLoad = - llvm::make_unique(std::move(PreCompiledObject)); - } + if (ObjCache) + ObjectToLoad = ObjCache->getObject(M); // If the cache did not contain a suitable object, compile the object if (!ObjectToLoad) { - ObjectToLoad.reset(emitObject(M)); - assert(ObjectToLoad.get() && "Compilation did not produce an object."); + ObjectToLoad = emitObject(M); + assert(ObjectToLoad && "Compilation did not produce an object."); } // Load the object into the dynamic linker. // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list). - std::unique_ptr LoadedObject = - Dyld.loadObject(std::move(ObjectToLoad)); - if (!LoadedObject) - report_fatal_error(Dyld.getErrorString()); + ErrorOr> LoadedObject = + object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef()); + std::unique_ptr L = + Dyld.loadObject(*LoadedObject.get()); - // FIXME: Make this optional, maybe even move it to a JIT event listener - LoadedObject->registerWithDebugger(); + if (Dyld.hasError()) + report_fatal_error(Dyld.getErrorString()); - NotifyObjectEmitted(*LoadedObject); + NotifyObjectEmitted(*LoadedObject.get(), *L); - LoadedObjects.push_back(std::move(LoadedObject)); + Buffers.push_back(std::move(ObjectToLoad)); + LoadedObjects.push_back(std::move(*LoadedObject)); OwnedModules.markModuleAsLoaded(M); } @@ -225,12 +228,14 @@ void MCJIT::finalizeLoadedModules() { void MCJIT::finalizeObject() { MutexGuard locked(lock); - for (ModulePtrSet::iterator I = OwnedModules.begin_added(), - E = OwnedModules.end_added(); - I != E; ++I) { - Module *M = *I; + // Generate code for module is going to move objects out of the 'added' list, + // so we need to copy that out before using it: + SmallVector ModsToAdd; + for (auto M : OwnedModules.added()) + ModsToAdd.push_back(M); + + for (auto M : ModsToAdd) generateCodeForModule(M); - } finalizeLoadedModules(); } @@ -289,7 +294,7 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name, return Addr; for (object::OwningBinary &OB : Archives) { - object::Archive *A = OB.getBinary().get(); + object::Archive *A = OB.getBinary(); // Look for our symbols in each Archive object::Archive::child_iterator ChildIt = A->findSym(Name); if (ChildIt != A->child_end()) { @@ -349,10 +354,14 @@ uint64_t MCJIT::getFunctionAddress(const std::string &Name) { void *MCJIT::getPointerToFunction(Function *F) { MutexGuard locked(lock); + Mangler Mang(TM->getSubtargetImpl()->getDataLayout()); + SmallString<128> Name; + TM->getNameWithPrefix(Name, F, Mang); + if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { bool AbortOnFailure = !F->hasExternalWeakLinkage(); - void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); - addGlobalMapping(F, Addr); + void *Addr = getPointerToNamedFunction(Name, AbortOnFailure); + updateGlobalMapping(F, Addr); return Addr; } @@ -362,17 +371,18 @@ void *MCJIT::getPointerToFunction(Function *F) { // Make sure the relevant module has been compiled and loaded. if (HasBeenAddedButNotLoaded) generateCodeForModule(M); - else if (!OwnedModules.hasModuleBeenLoaded(M)) + else if (!OwnedModules.hasModuleBeenLoaded(M)) { // If this function doesn't belong to one of our modules, we're done. + // FIXME: Asking for the pointer to a function that hasn't been registered, + // and isn't a declaration (which is handled above) should probably + // be an assertion. return nullptr; + } // FIXME: Should the Dyld be retaining module information? Probably not. // // This is the accessor for the target address, so make sure to check the // load address of the symbol, not the local address. - Mangler Mang(TM->getSubtargetImpl()->getDataLayout()); - SmallString<128> Name; - TM->getNameWithPrefix(Name, F, Mang); return (void*)Dyld.getSymbolLoadAddress(Name); } @@ -515,8 +525,7 @@ GenericValue MCJIT::runFunction(Function *F, llvm_unreachable("Full-featured argument passing not supported yet!"); } -void *MCJIT::getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure) { +void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) { if (!isSymbolSearchingDisabled()) { void *ptr = MemMgr.getPointerToNamedFunction(Name, false); if (ptr) @@ -541,6 +550,7 @@ void MCJIT::RegisterJITEventListener(JITEventListener *L) { MutexGuard locked(lock); EventListeners.push_back(L); } + void MCJIT::UnregisterJITEventListener(JITEventListener *L) { if (!L) return; @@ -551,14 +561,17 @@ void MCJIT::UnregisterJITEventListener(JITEventListener *L) { EventListeners.pop_back(); } } -void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) { + +void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj, + const RuntimeDyld::LoadedObjectInfo &L) { MutexGuard locked(lock); - MemMgr.notifyObjectLoaded(this, &Obj); + MemMgr.notifyObjectLoaded(this, Obj); for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { - EventListeners[I]->NotifyObjectEmitted(Obj); + EventListeners[I]->NotifyObjectEmitted(Obj, L); } } -void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) { + +void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) { MutexGuard locked(lock); for (JITEventListener *L : EventListeners) L->NotifyFreeingObject(Obj);