summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine/RuntimeDyld
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2018-09-25 22:57:44 +0000
committerLang Hames <lhames@gmail.com>2018-09-25 22:57:44 +0000
commitabeedf1812eeb33578b97bb975ddbf5da4ae933c (patch)
treeb83d194aa60258feb5e21c38c4fcfcd296fb5776 /llvm/lib/ExecutionEngine/RuntimeDyld
parentb794aec290269484481b0ce915f3c5f854a5783f (diff)
downloadbcm5719-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.cpp92
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h6
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);
OpenPOWER on IntegriCloud