diff options
author | Lang Hames <lhames@gmail.com> | 2018-09-25 22:57:44 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2018-09-25 22:57:44 +0000 |
commit | abeedf1812eeb33578b97bb975ddbf5da4ae933c (patch) | |
tree | b83d194aa60258feb5e21c38c4fcfcd296fb5776 /llvm/lib/ExecutionEngine/RuntimeDyld | |
parent | b794aec290269484481b0ce915f3c5f854a5783f (diff) | |
download | bcm5719-llvm-abeedf1812eeb33578b97bb975ddbf5da4ae933c.tar.gz bcm5719-llvm-abeedf1812eeb33578b97bb975ddbf5da4ae933c.zip |
[ORC] Add an asynchronous jit-link function, jitLinkForORC, to RuntimeDyld and
switch RTDyldObjectLinkingLayer2 to use it.
RuntimeDyld::loadObject is currently a blocking operation. This means that any
JIT'd code whose call-graph contains an embedded complete K graph will require
at least K threads to link, which precludes the use of a fixed sized thread
pool for concurrent JITing of arbitrary code (whatever K the thread-pool is set
at, any code with a K+1 complete subgraph will deadlock at JIT-link time).
To address this issue, this commmit introduces a function called jitLinkForORC
that uses continuation-passing style to pass the fix-up and finalization steps
to the asynchronous symbol resolver interface so that linking can be performed
without blocking.
llvm-svn: 343043
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp | 92 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h | 6 |
2 files changed, 94 insertions, 4 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 563a9725142..53cb782c55c 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -134,6 +134,14 @@ void RuntimeDyldImpl::resolveRelocations() { ErrorStr = toString(std::move(Err)); } + resolveLocalRelocations(); + + // Print out sections after relocation. + LLVM_DEBUG(for (int i = 0, e = Sections.size(); i != e; ++i) + dumpSectionMemory(Sections[i], "after relocations");); +} + +void RuntimeDyldImpl::resolveLocalRelocations() { // Iterate over all outstanding relocations for (auto it = Relocations.begin(), e = Relocations.end(); it != e; ++it) { // The Section here (Sections[i]) refers to the section in which the @@ -146,10 +154,6 @@ void RuntimeDyldImpl::resolveRelocations() { resolveRelocationList(it->second, Addr); } Relocations.clear(); - - // Print out sections after relocation. - LLVM_DEBUG(for (int i = 0, e = Sections.size(); i != e; ++i) - dumpSectionMemory(Sections[i], "after relocations");); } void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress, @@ -1120,6 +1124,56 @@ Error RuntimeDyldImpl::resolveExternalSymbols() { return Error::success(); } +void RuntimeDyldImpl::finalizeAsync( + std::unique_ptr<RuntimeDyldImpl> This, std::function<void(Error)> OnEmitted, + std::unique_ptr<MemoryBuffer> UnderlyingBuffer) { + + // FIXME: Move-capture OnRelocsApplied and UnderlyingBuffer once we have + // c++14. + auto SharedUnderlyingBuffer = + std::shared_ptr<MemoryBuffer>(std::move(UnderlyingBuffer)); + auto SharedThis = std::shared_ptr<RuntimeDyldImpl>(std::move(This)); + auto PostResolveContinuation = + [SharedThis, OnEmitted, SharedUnderlyingBuffer]( + Expected<JITSymbolResolver::LookupResult> Result) { + if (!Result) { + OnEmitted(Result.takeError()); + return; + } + + /// Copy the result into a StringMap, where the keys are held by value. + StringMap<JITEvaluatedSymbol> Resolved; + for (auto &KV : *Result) + Resolved[KV.first] = KV.second; + + SharedThis->applyExternalSymbolRelocations(Resolved); + SharedThis->resolveLocalRelocations(); + SharedThis->registerEHFrames(); + std::string ErrMsg; + if (SharedThis->MemMgr.finalizeMemory(&ErrMsg)) + OnEmitted(make_error<StringError>(std::move(ErrMsg), + inconvertibleErrorCode())); + else + OnEmitted(Error::success()); + }; + + JITSymbolResolver::LookupSet Symbols; + + for (auto &RelocKV : SharedThis->ExternalSymbolRelocations) { + StringRef Name = RelocKV.first(); + assert(!Name.empty() && "Symbol has no name?"); + assert(!SharedThis->GlobalSymbolTable.count(Name) && + "Name already processed. RuntimeDyld instances can not be re-used " + "when finalizing with finalizeAsync."); + Symbols.insert(Name); + } + + if (!Symbols.empty()) { + SharedThis->Resolver.lookup(Symbols, PostResolveContinuation); + } else + PostResolveContinuation(std::map<StringRef, JITEvaluatedSymbol>()); +} + //===----------------------------------------------------------------------===// // RuntimeDyld class implementation @@ -1267,5 +1321,35 @@ void RuntimeDyld::deregisterEHFrames() { if (Dyld) Dyld->deregisterEHFrames(); } +// FIXME: Kill this with fire once we have a new JIT linker: this is only here +// so that we can re-use RuntimeDyld's implementation without twisting the +// interface any further for ORC's purposes. +void jitLinkForORC(object::ObjectFile &Obj, + std::unique_ptr<MemoryBuffer> UnderlyingBuffer, + RuntimeDyld::MemoryManager &MemMgr, + JITSymbolResolver &Resolver, bool ProcessAllSections, + std::function<Error( + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObj, + std::map<StringRef, JITEvaluatedSymbol>)> + OnLoaded, + std::function<void(Error)> OnEmitted) { + + RuntimeDyld RTDyld(MemMgr, Resolver); + RTDyld.setProcessAllSections(ProcessAllSections); + + auto Info = RTDyld.loadObject(Obj); + + if (RTDyld.hasError()) { + OnEmitted(make_error<StringError>(RTDyld.getErrorString(), + inconvertibleErrorCode())); + return; + } + + if (auto Err = OnLoaded(std::move(Info), RTDyld.getSymbolTable())) + OnEmitted(std::move(Err)); + + RuntimeDyldImpl::finalizeAsync(std::move(RTDyld.Dyld), std::move(OnEmitted), + std::move(UnderlyingBuffer)); +} } // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index f01d3103f82..4c650e09ac1 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -539,6 +539,12 @@ public: void resolveRelocations(); + void resolveLocalRelocations(); + + static void finalizeAsync(std::unique_ptr<RuntimeDyldImpl> This, + std::function<void(Error)> OnEmitted, + std::unique_ptr<MemoryBuffer> UnderlyingBuffer); + void reassignSectionAddress(unsigned SectionID, uint64_t Addr); void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); |