[ORC] Pass object buffer ownership back in NotifyEmitted.
Clients who want to regain ownership of object buffers after they have been
linked may now use the NotifyEmitted callback for this purpose.
Note: Currently NotifyEmitted is only called if linking succeeds. If linking
fails the buffer is always discarded.
llvm-svn: 359735
diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
index 29c5445..97f69eb 100644
--- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
@@ -77,11 +77,8 @@
namespace orc {
RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
- ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
- NotifyLoadedFunction NotifyLoaded, NotifyEmittedFunction NotifyEmitted)
- : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
- NotifyLoaded(std::move(NotifyLoaded)),
- NotifyEmitted(std::move(NotifyEmitted)) {}
+ ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager)
+ : ObjectLayer(ES), GetMemoryManager(GetMemoryManager) {}
void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
std::unique_ptr<MemoryBuffer> O) {
@@ -95,7 +92,13 @@
auto &ES = getExecutionSession();
- auto Obj = object::ObjectFile::createObjectFile(*O);
+ // Create a MemoryBufferRef backed MemoryBuffer (i.e. shallow) copy of the
+ // the underlying buffer to pass into RuntimeDyld. This allows us to hold
+ // ownership of the real underlying buffer and return it to the user once
+ // the object has been emitted.
+ auto ObjBuffer = MemoryBuffer::getMemBuffer(O->getMemBufferRef(), false);
+
+ auto Obj = object::ObjectFile::createObjectFile(*ObjBuffer);
if (!Obj) {
getExecutionSession().reportError(Obj.takeError());
@@ -133,13 +136,8 @@
JITDylibSearchOrderResolver Resolver(*SharedR);
- /* Thoughts on proper cross-dylib weak symbol handling:
- *
- * Change selection of canonical defs to be a manually triggered process, and
- * add a 'canonical' bit to symbol definitions. When canonical def selection
- * is triggered, sweep the JITDylibs to mark defs as canonical, discard
- * duplicate defs.
- */
+ // FIXME: Switch to move-capture for the 'O' buffer once we have c++14.
+ MemoryBuffer *UnownedObjBuffer = O.release();
jitLinkForORC(
**Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections,
[this, K, SharedR, &Obj, InternalSymbols](
@@ -148,8 +146,9 @@
return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo),
ResolvedSymbols, *InternalSymbols);
},
- [this, K, SharedR](Error Err) {
- onObjEmit(K, *SharedR, std::move(Err));
+ [this, K, SharedR, UnownedObjBuffer](Error Err) {
+ std::unique_ptr<MemoryBuffer> ObjBuffer(UnownedObjBuffer);
+ onObjEmit(K, std::move(ObjBuffer), *SharedR, std::move(Err));
});
}
@@ -196,9 +195,9 @@
return Error::success();
}
-void RTDyldObjectLinkingLayer::onObjEmit(VModuleKey K,
- MaterializationResponsibility &R,
- Error Err) {
+void RTDyldObjectLinkingLayer::onObjEmit(
+ VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer,
+ MaterializationResponsibility &R, Error Err) {
if (Err) {
getExecutionSession().reportError(std::move(Err));
R.failMaterialization();
@@ -208,7 +207,7 @@
R.emit();
if (NotifyEmitted)
- NotifyEmitted(K);
+ NotifyEmitted(K, std::move(ObjBuffer));
}
} // End namespace orc.