aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/include/llvm/ExecutionEngine
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/include/llvm/ExecutionEngine')
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h21
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITEventListener.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h33
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h91
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h19
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h639
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h611
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h110
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h111
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h100
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h80
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h55
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h49
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h84
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h267
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h211
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h43
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h57
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h84
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h415
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h263
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h280
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h21
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h387
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h564
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h79
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h (renamed from contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h)0
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h (renamed from contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h)252
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h (renamed from contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h)25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h (renamed from contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h)367
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h165
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h66
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h54
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h222
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h620
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h41
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h38
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h218
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h11
52 files changed, 3473 insertions, 3459 deletions
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
index 2562da7cf60b..2e386518f0bf 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -142,11 +142,6 @@ protected:
std::shared_ptr<LegacyJITSymbolResolver> SR,
std::unique_ptr<TargetMachine> TM);
- static ExecutionEngine *(*OrcMCJITReplacementCtor)(
- std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MM,
- std::shared_ptr<LegacyJITSymbolResolver> SR,
- std::unique_ptr<TargetMachine> TM);
-
static ExecutionEngine *(*InterpCtor)(std::unique_ptr<Module> M,
std::string *ErrorStr);
@@ -552,7 +547,6 @@ private:
std::string MCPU;
SmallVector<std::string, 4> MAttrs;
bool VerifyModules;
- bool UseOrcMCJITReplacement;
bool EmulatedTLS = true;
public:
@@ -648,17 +642,6 @@ public:
return *this;
}
- // Use OrcMCJITReplacement instead of MCJIT. Off by default.
- LLVM_ATTRIBUTE_DEPRECATED(
- inline void setUseOrcMCJITReplacement(bool UseOrcMCJITReplacement),
- "ORCv1 utilities (including OrcMCJITReplacement) are deprecated. Please "
- "use ORCv2/LLJIT instead (see docs/ORCv2.rst)");
-
- void setUseOrcMCJITReplacement(ORCv1DeprecationAcknowledgement,
- bool UseOrcMCJITReplacement) {
- this->UseOrcMCJITReplacement = UseOrcMCJITReplacement;
- }
-
void setEmulatedTLS(bool EmulatedTLS) {
this->EmulatedTLS = EmulatedTLS;
}
@@ -679,10 +662,6 @@ public:
ExecutionEngine *create(TargetMachine *TM);
};
-void EngineBuilder::setUseOrcMCJITReplacement(bool UseOrcMCJITReplacement) {
- this->UseOrcMCJITReplacement = UseOrcMCJITReplacement;
-}
-
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITEventListener.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITEventListener.h
index 606b6f7cc128..4eefd993de2b 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITEventListener.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITEventListener.h
@@ -20,7 +20,6 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/CBindingWrapping.h"
#include <cstdint>
-#include <vector>
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
index 72687682f606..ec78d9db40b6 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
@@ -21,14 +21,6 @@
namespace llvm {
namespace jitlink {
-/// Registers all FDEs in the given eh-frame section with the current process.
-Error registerEHFrameSection(const void *EHFrameSectionAddr,
- size_t EHFrameSectionSize);
-
-/// Deregisters all FDEs in the given eh-frame section with the current process.
-Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
- size_t EHFrameSectionSize);
-
/// Supports registration/deregistration of EH-frames in a target process.
class EHFrameRegistrar {
public:
@@ -42,32 +34,11 @@ public:
/// Registers / Deregisters EH-frames in the current process.
class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
public:
- /// Get a reference to the InProcessEHFrameRegistrar singleton.
- static InProcessEHFrameRegistrar &getInstance();
-
- InProcessEHFrameRegistrar(const InProcessEHFrameRegistrar &) = delete;
- InProcessEHFrameRegistrar &
- operator=(const InProcessEHFrameRegistrar &) = delete;
-
- InProcessEHFrameRegistrar(InProcessEHFrameRegistrar &&) = delete;
- InProcessEHFrameRegistrar &operator=(InProcessEHFrameRegistrar &&) = delete;
-
Error registerEHFrames(JITTargetAddress EHFrameSectionAddr,
- size_t EHFrameSectionSize) override {
- return registerEHFrameSection(
- jitTargetAddressToPointer<void *>(EHFrameSectionAddr),
- EHFrameSectionSize);
- }
+ size_t EHFrameSectionSize) override;
Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr,
- size_t EHFrameSectionSize) override {
- return deregisterEHFrameSection(
- jitTargetAddressToPointer<void *>(EHFrameSectionAddr),
- EHFrameSectionSize);
- }
-
-private:
- InProcessEHFrameRegistrar();
+ size_t EHFrameSectionSize) override;
};
using StoreFrameRangeFunction =
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
index 9f6ea5271f4b..8912f3a2db45 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
@@ -19,11 +19,20 @@
namespace llvm {
namespace jitlink {
-/// jit-link the given ObjBuffer, which must be a ELF object file.
+/// Create a LinkGraph from an ELF relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer);
+
+/// Link the given graph.
///
/// Uses conservative defaults for GOT and stub handling based on the target
/// platform.
-void jitLink_ELF(std::unique_ptr<JITLinkContext> Ctx);
+void link_ELF(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
index 7860088f3569..1423b0c30b2a 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
@@ -44,8 +44,20 @@ enum ELFX86RelocationKind : Edge::Kind {
} // end namespace ELF_x86_64_Edges
+/// Create a LinkGraph from an ELF/x86-64 relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer);
+
/// jit-link the given object buffer, which must be a ELF x86-64 object file.
-void jitLink_ELF_x86_64(std::unique_ptr<JITLinkContext> Ctx);
+void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
+
+/// Return the string name of the given ELF x86-64 edge kind.
+StringRef getELFX86RelocationKindName(Edge::Kind R);
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index 76f9dea4160f..e8c0e28b83aa 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -395,6 +395,10 @@ public:
return Name;
}
+ /// Rename this symbol. The client is responsible for updating scope and
+ /// linkage if this name-change requires it.
+ void setName(StringRef Name) { this->Name = Name; }
+
/// Returns true if this Symbol has content (potentially) defined within this
/// object file (i.e. is anything but an external or absolute symbol).
bool isDefined() const {
@@ -782,21 +786,48 @@ public:
Section::const_block_iterator, const Block *,
getSectionConstBlocks>;
- LinkGraph(std::string Name, unsigned PointerSize,
+ LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize,
support::endianness Endianness)
- : Name(std::move(Name)), PointerSize(PointerSize),
+ : Name(std::move(Name)), TT(TT), PointerSize(PointerSize),
Endianness(Endianness) {}
/// Returns the name of this graph (usually the name of the original
/// underlying MemoryBuffer).
const std::string &getName() { return Name; }
+ /// Returns the target triple for this Graph.
+ const Triple &getTargetTriple() const { return TT; }
+
/// Returns the pointer size for use in this graph.
unsigned getPointerSize() const { return PointerSize; }
/// Returns the endianness of content in this graph.
support::endianness getEndianness() const { return Endianness; }
+ /// Allocate a copy of the given string using the LinkGraph's allocator.
+ /// This can be useful when renaming symbols or adding new content to the
+ /// graph.
+ StringRef allocateString(StringRef Source) {
+ auto *AllocatedBuffer = Allocator.Allocate<char>(Source.size());
+ llvm::copy(Source, AllocatedBuffer);
+ return StringRef(AllocatedBuffer, Source.size());
+ }
+
+ /// Allocate a copy of the given string using the LinkGraph's allocator.
+ /// This can be useful when renaming symbols or adding new content to the
+ /// graph.
+ ///
+ /// Note: This Twine-based overload requires an extra string copy and an
+ /// extra heap allocation for large strings. The StringRef overload should
+ /// be preferred where possible.
+ StringRef allocateString(Twine Source) {
+ SmallString<256> TmpBuffer;
+ auto SourceStr = Source.toStringRef(TmpBuffer);
+ auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size());
+ llvm::copy(SourceStr, AllocatedBuffer);
+ return StringRef(AllocatedBuffer, SourceStr.size());
+ }
+
/// Create a section with the given name, protection flags, and alignment.
Section &createSection(StringRef Name, sys::Memory::ProtectionFlags Prot) {
std::unique_ptr<Section> Sec(new Section(Name, Prot, Sections.size()));
@@ -959,7 +990,7 @@ public:
Section &Sec = Sym.getBlock().getSection();
Sec.removeSymbol(Sym);
}
- Sym.makeExternal(createAddressable(false));
+ Sym.makeExternal(createAddressable(0, false));
ExternalSymbols.insert(&Sym);
}
@@ -1019,6 +1050,7 @@ private:
BumpPtrAllocator Allocator;
std::string Name;
+ Triple TT;
unsigned PointerSize;
support::endianness Endianness;
SectionList Sections;
@@ -1191,15 +1223,31 @@ struct PassConfiguration {
/// Notable use cases: Building GOT, stub, and TLV symbols.
LinkGraphPassList PostPrunePasses;
+ /// Post-allocation passes.
+ ///
+ /// These passes are called on the graph after memory has been allocated and
+ /// defined nodes have been assigned their final addresses, but before the
+ /// context has been notified of these addresses. At this point externals
+ /// have not been resolved, and symbol content has not yet been copied into
+ /// working memory.
+ ///
+ /// Notable use cases: Setting up data structures associated with addresses
+ /// of defined symbols (e.g. a mapping of __dso_handle to JITDylib* for the
+ /// JIT runtime) -- using a PostAllocationPass for this ensures that the
+ /// data structures are in-place before any query for resolved symbols
+ /// can complete.
+ LinkGraphPassList PostAllocationPasses;
+
/// Pre-fixup passes.
///
/// These passes are called on the graph after memory has been allocated,
- /// content copied into working memory, and nodes have been assigned their
- /// final addresses.
+ /// content copied into working memory, and all nodes (including externals)
+ /// have been assigned their final addresses, but before any fixups have been
+ /// applied.
///
/// Notable use cases: Late link-time optimizations like GOT and stub
/// elimination.
- LinkGraphPassList PostAllocationPasses;
+ LinkGraphPassList PreFixupPasses;
/// Post-fixup passes.
///
@@ -1255,16 +1303,18 @@ class JITLinkContext {
public:
using LookupMap = DenseMap<StringRef, SymbolLookupFlags>;
+ /// Create a JITLinkContext.
+ JITLinkContext(const JITLinkDylib *JD) : JD(JD) {}
+
/// Destroy a JITLinkContext.
virtual ~JITLinkContext();
+ /// Return the JITLinkDylib that this link is targeting, if any.
+ const JITLinkDylib *getJITLinkDylib() const { return JD; }
+
/// Return the MemoryManager to be used for this link.
virtual JITLinkMemoryManager &getMemoryManager() = 0;
- /// Returns a StringRef for the object buffer.
- /// This method can not be called once takeObjectBuffer has been called.
- virtual MemoryBufferRef getObjectBuffer() const = 0;
-
/// Notify this context that linking failed.
/// Called by JITLink if linking cannot be completed.
virtual void notifyFailed(Error Err) = 0;
@@ -1279,7 +1329,11 @@ public:
/// their final memory locations in the target process. At this point the
/// LinkGraph can be inspected to build a symbol table, however the block
/// content will not generally have been copied to the target location yet.
- virtual void notifyResolved(LinkGraph &G) = 0;
+ ///
+ /// If the client detects an error in the LinkGraph state (e.g. unexpected or
+ /// missing symbols) they may return an error here. The error will be
+ /// propagated to notifyFailed and the linker will bail out.
+ virtual Error notifyResolved(LinkGraph &G) = 0;
/// Called by JITLink to notify the context that the object has been
/// finalized (i.e. emitted to memory and memory permissions set). If all of
@@ -1305,16 +1359,25 @@ public:
/// Called by JITLink to modify the pass pipeline prior to linking.
/// The default version performs no modification.
virtual Error modifyPassConfig(const Triple &TT, PassConfiguration &Config);
+
+private:
+ const JITLinkDylib *JD = nullptr;
};
/// Marks all symbols in a graph live. This can be used as a default,
/// conservative mark-live implementation.
Error markAllSymbolsLive(LinkGraph &G);
-/// Basic JITLink implementation.
+/// Create a LinkGraph from the given object buffer.
///
-/// This function will use sensible defaults for GOT and Stub handling.
-void jitLink(std::unique_ptr<JITLinkContext> Ctx);
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromObject(MemoryBufferRef ObjectBuffer);
+
+/// Link the given graph.
+void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx);
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h
new file mode 100644
index 000000000000..2aa88cb50074
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h
@@ -0,0 +1,24 @@
+//===-- JITLinkDylib.h - JITLink Dylib type ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the JITLinkDylib API.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
+#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
+
+namespace llvm {
+namespace jitlink {
+
+class JITLinkDylib {};
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
index 0c8514a60a50..cee7d6b09c48 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
@@ -14,10 +14,11 @@
#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/Memory.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
+#include "llvm/Support/Memory.h"
#include <cstdint>
#include <future>
@@ -93,18 +94,28 @@ public:
virtual ~JITLinkMemoryManager();
/// Create an Allocation object.
+ ///
+ /// The JD argument represents the target JITLinkDylib, and can be used by
+ /// JITLinkMemoryManager implementers to manage per-dylib allocation pools
+ /// (e.g. one pre-reserved address space slab per dylib to ensure that all
+ /// allocations for the dylib are within a certain range). The JD argument
+ /// may be null (representing an allocation not associated with any
+ /// JITDylib.
+ ///
+ /// The request argument describes the segment sizes and permisssions being
+ /// requested.
virtual Expected<std::unique_ptr<Allocation>>
- allocate(const SegmentsRequestMap &Request) = 0;
+ allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) = 0;
};
/// A JITLinkMemoryManager that allocates in-process memory.
class InProcessMemoryManager : public JITLinkMemoryManager {
public:
Expected<std::unique_ptr<Allocation>>
- allocate(const SegmentsRequestMap &Request) override;
+ allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) override;
};
} // end namespace jitlink
} // end namespace llvm
-#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
+#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h
index 7facb657a51c..b8432c4d26c6 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h
@@ -18,11 +18,20 @@
namespace llvm {
namespace jitlink {
+/// Create a LinkGraph from a MachO relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer);
+
/// jit-link the given ObjBuffer, which must be a MachO object file.
///
/// Uses conservative defaults for GOT and stub handling based on the target
/// platform.
-void jitLink_MachO(std::unique_ptr<JITLinkContext> Ctx);
+void link_MachO(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
index d70b545fff86..c6aed2b60eac 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
@@ -40,6 +40,14 @@ enum MachOARM64RelocationKind : Edge::Kind {
} // namespace MachO_arm64_Edges
+/// Create a LinkGraph from a MachO/arm64 relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer);
+
/// jit-link the given object buffer, which must be a MachO arm64 object file.
///
/// If PrePrunePasses is empty then a default mark-live pass will be inserted
@@ -49,7 +57,8 @@ enum MachOARM64RelocationKind : Edge::Kind {
/// If PostPrunePasses is empty then a default GOT-and-stubs insertion pass will
/// be inserted. If PostPrunePasses is not empty then the caller is responsible
/// for including a pass to insert GOT and stub edges.
-void jitLink_MachO_arm64(std::unique_ptr<JITLinkContext> Ctx);
+void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
/// Return the string name of the given MachO arm64 edge kind.
StringRef getMachOARM64RelocationKindName(Edge::Kind R);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
index 27fcdf4fa990..66c53d8c8291 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
@@ -45,7 +45,15 @@ enum MachOX86RelocationKind : Edge::Kind {
} // namespace MachO_x86_64_Edges
-/// jit-link the given object buffer, which must be a MachO x86-64 object file.
+/// Create a LinkGraph from a MachO/x86-64 relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer);
+
+/// jit-link the given LinkGraph.
///
/// If PrePrunePasses is empty then a default mark-live pass will be inserted
/// that will mark all exported atoms live. If PrePrunePasses is not empty, the
@@ -54,7 +62,8 @@ enum MachOX86RelocationKind : Edge::Kind {
/// If PostPrunePasses is empty then a default GOT-and-stubs insertion pass will
/// be inserted. If PostPrunePasses is not empty then the caller is responsible
/// for including a pass to insert GOT and stub edges.
-void jitLink_MachO_x86_64(std::unique_ptr<JITLinkContext> Ctx);
+void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
/// Return the string name of the given MachO x86-64 edge kind.
StringRef getMachOX86RelocationKindName(Edge::Kind R);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h
index 6f0030a18f47..9bbdd21f77de 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h
@@ -429,7 +429,7 @@ public:
virtual JITSymbol findSymbol(const std::string &Name) = 0;
private:
- virtual void anchor();
+ void anchor() override;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 9ecc0464dec1..91b12fd2277a 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -20,12 +20,10 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
-#include "llvm/ExecutionEngine/Orc/Legacy.h"
-#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/Orc/Speculation.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
@@ -96,7 +94,8 @@ public:
/// Emits the given module. This should not be called by clients: it will be
/// called by the JIT when a definition added via the add method is requested.
- void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
private:
struct PerDylibResources {
@@ -120,7 +119,8 @@ private:
void expandPartition(GlobalValueSet &Partition);
- void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
+ void emitPartition(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM,
IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
mutable std::mutex CODLayerMutex;
@@ -134,635 +134,6 @@ private:
ImplSymbolMap *AliaseeImpls = nullptr;
};
-/// Compile-on-demand layer.
-///
-/// When a module is added to this layer a stub is created for each of its
-/// function definitions. The stubs and other global values are immediately
-/// added to the layer below. When a stub is called it triggers the extraction
-/// of the function body from the original module. The extracted body is then
-/// compiled and executed.
-template <typename BaseLayerT,
- typename CompileCallbackMgrT = JITCompileCallbackManager,
- typename IndirectStubsMgrT = IndirectStubsManager>
-class LegacyCompileOnDemandLayer {
-private:
- template <typename MaterializerFtor>
- class LambdaMaterializer final : public ValueMaterializer {
- public:
- LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
-
- Value *materialize(Value *V) final { return M(V); }
-
- private:
- MaterializerFtor M;
- };
-
- template <typename MaterializerFtor>
- LambdaMaterializer<MaterializerFtor>
- createLambdaMaterializer(MaterializerFtor M) {
- return LambdaMaterializer<MaterializerFtor>(std::move(M));
- }
-
- // Provide type-erasure for the Modules and MemoryManagers.
- template <typename ResourceT>
- class ResourceOwner {
- public:
- ResourceOwner() = default;
- ResourceOwner(const ResourceOwner &) = delete;
- ResourceOwner &operator=(const ResourceOwner &) = delete;
- virtual ~ResourceOwner() = default;
-
- virtual ResourceT& getResource() const = 0;
- };
-
- template <typename ResourceT, typename ResourcePtrT>
- class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
- public:
- ResourceOwnerImpl(ResourcePtrT ResourcePtr)
- : ResourcePtr(std::move(ResourcePtr)) {}
-
- ResourceT& getResource() const override { return *ResourcePtr; }
-
- private:
- ResourcePtrT ResourcePtr;
- };
-
- template <typename ResourceT, typename ResourcePtrT>
- std::unique_ptr<ResourceOwner<ResourceT>>
- wrapOwnership(ResourcePtrT ResourcePtr) {
- using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
- return std::make_unique<RO>(std::move(ResourcePtr));
- }
-
- struct LogicalDylib {
- struct SourceModuleEntry {
- std::unique_ptr<Module> SourceMod;
- std::set<Function*> StubsToClone;
- };
-
- using SourceModulesList = std::vector<SourceModuleEntry>;
- using SourceModuleHandle = typename SourceModulesList::size_type;
-
- LogicalDylib() = default;
-
- LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
- std::unique_ptr<IndirectStubsMgrT> StubsMgr)
- : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
- StubsMgr(std::move(StubsMgr)) {}
-
- SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
- SourceModuleHandle H = SourceModules.size();
- SourceModules.push_back(SourceModuleEntry());
- SourceModules.back().SourceMod = std::move(M);
- return H;
- }
-
- Module& getSourceModule(SourceModuleHandle H) {
- return *SourceModules[H].SourceMod;
- }
-
- std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
- return SourceModules[H].StubsToClone;
- }
-
- JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
- bool ExportedSymbolsOnly) {
- if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
- return Sym;
- for (auto BLK : BaseLayerVModuleKeys)
- if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
- return Sym;
- else if (auto Err = Sym.takeError())
- return std::move(Err);
- return nullptr;
- }
-
- Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
- for (auto &BLK : BaseLayerVModuleKeys)
- if (auto Err = BaseLayer.removeModule(BLK))
- return Err;
- return Error::success();
- }
-
- VModuleKey K;
- std::shared_ptr<SymbolResolver> BackingResolver;
- std::unique_ptr<IndirectStubsMgrT> StubsMgr;
- SymbolLinkagePromoter PromoteSymbols;
- SourceModulesList SourceModules;
- std::vector<VModuleKey> BaseLayerVModuleKeys;
- };
-
-public:
-
- /// Module partitioning functor.
- using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
-
- /// Builder for IndirectStubsManagers.
- using IndirectStubsManagerBuilderT =
- std::function<std::unique_ptr<IndirectStubsMgrT>()>;
-
- using SymbolResolverGetter =
- std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
-
- using SymbolResolverSetter =
- std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
-
- /// Construct a compile-on-demand layer instance.
- LLVM_ATTRIBUTE_DEPRECATED(
- LegacyCompileOnDemandLayer(
- ExecutionSession &ES, BaseLayerT &BaseLayer,
- SymbolResolverGetter GetSymbolResolver,
- SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition,
- CompileCallbackMgrT &CallbackMgr,
- IndirectStubsManagerBuilderT CreateIndirectStubsManager,
- bool CloneStubsIntoPartitions = true),
- "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
- "use "
- "the ORCv2 LegacyCompileOnDemandLayer instead");
-
- /// Legacy layer constructor with deprecation acknowledgement.
- LegacyCompileOnDemandLayer(
- ORCv1DeprecationAcknowledgement, ExecutionSession &ES,
- BaseLayerT &BaseLayer, SymbolResolverGetter GetSymbolResolver,
- SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition,
- CompileCallbackMgrT &CallbackMgr,
- IndirectStubsManagerBuilderT CreateIndirectStubsManager,
- bool CloneStubsIntoPartitions = true)
- : ES(ES), BaseLayer(BaseLayer),
- GetSymbolResolver(std::move(GetSymbolResolver)),
- SetSymbolResolver(std::move(SetSymbolResolver)),
- Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
- CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
- CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
-
- ~LegacyCompileOnDemandLayer() {
- // FIXME: Report error on log.
- while (!LogicalDylibs.empty())
- consumeError(removeModule(LogicalDylibs.begin()->first));
- }
-
- /// Add a module to the compile-on-demand layer.
- Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
-
- assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
- auto I = LogicalDylibs.insert(
- LogicalDylibs.end(),
- std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
- CreateIndirectStubsManager())));
-
- return addLogicalModule(I->second, std::move(M));
- }
-
- /// Add extra modules to an existing logical module.
- Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
- return addLogicalModule(LogicalDylibs[K], std::move(M));
- }
-
- /// Remove the module represented by the given key.
- ///
- /// This will remove all modules in the layers below that were derived from
- /// the module represented by K.
- Error removeModule(VModuleKey K) {
- auto I = LogicalDylibs.find(K);
- assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
- auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
- LogicalDylibs.erase(I);
- return Err;
- }
-
- /// Search for the given named symbol.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it exists.
- JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- for (auto &KV : LogicalDylibs) {
- if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
- return Sym;
- if (auto Sym =
- findSymbolIn(KV.first, std::string(Name), ExportedSymbolsOnly))
- return Sym;
- else if (auto Err = Sym.takeError())
- return std::move(Err);
- }
- return BaseLayer.findSymbol(std::string(Name), ExportedSymbolsOnly);
- }
-
- /// Get the address of a symbol provided by this layer, or some layer
- /// below this one.
- JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
- bool ExportedSymbolsOnly) {
- assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
- return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
- }
-
- /// Update the stub for the given function to point at FnBodyAddr.
- /// This can be used to support re-optimization.
- /// @return true if the function exists and the stub is updated, false
- /// otherwise.
- //
- // FIXME: We should track and free associated resources (unused compile
- // callbacks, uncompiled IR, and no-longer-needed/reachable function
- // implementations).
- Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
- //Find out which logical dylib contains our symbol
- auto LDI = LogicalDylibs.begin();
- for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
- if (auto LMResources =
- LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
- Module &SrcM = LMResources->SourceModule->getResource();
- std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
- if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
- FnBodyAddr))
- return Err;
- return Error::success();
- }
- }
- return make_error<JITSymbolNotFound>(FuncName);
- }
-
-private:
- Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
-
- // Rename anonymous globals and promote linkage to ensure that everything
- // will resolve properly after we partition SrcM.
- LD.PromoteSymbols(*SrcMPtr);
-
- // Create a logical module handle for SrcM within the logical dylib.
- Module &SrcM = *SrcMPtr;
- auto LMId = LD.addSourceModule(std::move(SrcMPtr));
-
- // Create stub functions.
- const DataLayout &DL = SrcM.getDataLayout();
-
- typename IndirectStubsMgrT::StubInitsMap StubInits;
- for (auto &F : SrcM) {
- // Skip declarations.
- if (F.isDeclaration())
- continue;
-
- // Skip weak functions for which we already have definitions.
- auto MangledName = mangle(F.getName(), DL);
- if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
- if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
- continue;
- else if (auto Err = Sym.takeError())
- return Err;
- }
-
- // Record all functions defined by this module.
- if (CloneStubsIntoPartitions)
- LD.getStubsToClone(LMId).insert(&F);
-
- // Create a callback, associate it with the stub for the function,
- // and set the compile action to compile the partition containing the
- // function.
- auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
- if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
- return *FnImplAddrOrErr;
- else {
- // FIXME: Report error, return to 'abort' or something similar.
- consumeError(FnImplAddrOrErr.takeError());
- return 0;
- }
- };
- if (auto CCAddr =
- CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
- StubInits[MangledName] =
- std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
- else
- return CCAddr.takeError();
- }
-
- if (auto Err = LD.StubsMgr->createStubs(StubInits))
- return Err;
-
- // If this module doesn't contain any globals, aliases, or module flags then
- // we can bail out early and avoid the overhead of creating and managing an
- // empty globals module.
- if (SrcM.global_empty() && SrcM.alias_empty() &&
- !SrcM.getModuleFlagsMetadata())
- return Error::success();
-
- // Create the GlobalValues module.
- auto GVsM = std::make_unique<Module>((SrcM.getName() + ".globals").str(),
- SrcM.getContext());
- GVsM->setDataLayout(DL);
-
- ValueToValueMapTy VMap;
-
- // Clone global variable decls.
- for (auto &GV : SrcM.globals())
- if (!GV.isDeclaration() && !VMap.count(&GV))
- cloneGlobalVariableDecl(*GVsM, GV, &VMap);
-
- // And the aliases.
- for (auto &A : SrcM.aliases())
- if (!VMap.count(&A))
- cloneGlobalAliasDecl(*GVsM, A, VMap);
-
- // Clone the module flags.
- cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
-
- // Now we need to clone the GV and alias initializers.
-
- // Initializers may refer to functions declared (but not defined) in this
- // module. Build a materializer to clone decls on demand.
- auto Materializer = createLambdaMaterializer(
- [&LD, &GVsM](Value *V) -> Value* {
- if (auto *F = dyn_cast<Function>(V)) {
- // Decls in the original module just get cloned.
- if (F->isDeclaration())
- return cloneFunctionDecl(*GVsM, *F);
-
- // Definitions in the original module (which we have emitted stubs
- // for at this point) get turned into a constant alias to the stub
- // instead.
- const DataLayout &DL = GVsM->getDataLayout();
- std::string FName = mangle(F->getName(), DL);
- unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
- JITTargetAddress StubAddr =
- LD.StubsMgr->findStub(FName, false).getAddress();
-
- ConstantInt *StubAddrCI =
- ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
- Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
- StubAddrCI, F->getType());
- return GlobalAlias::create(F->getFunctionType(),
- F->getType()->getAddressSpace(),
- F->getLinkage(), F->getName(),
- Init, GVsM.get());
- }
- // else....
- return nullptr;
- });
-
- // Clone the global variable initializers.
- for (auto &GV : SrcM.globals())
- if (!GV.isDeclaration())
- moveGlobalVariableInitializer(GV, VMap, &Materializer);
-
- // Clone the global alias initializers.
- for (auto &A : SrcM.aliases()) {
- auto *NewA = cast<GlobalAlias>(VMap[&A]);
- assert(NewA && "Alias not cloned?");
- Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
- &Materializer);
- NewA->setAliasee(cast<Constant>(Init));
- }
-
- // Build a resolver for the globals module and add it to the base layer.
- auto LegacyLookup = [this, &LD](StringRef Name) -> JITSymbol {
- if (auto Sym = LD.StubsMgr->findStub(Name, false))
- return Sym;
-
- if (auto Sym = LD.findSymbol(BaseLayer, std::string(Name), false))
- return Sym;
- else if (auto Err = Sym.takeError())
- return std::move(Err);
-
- return nullptr;
- };
-
- auto GVsResolver = createSymbolResolver(
- [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
- auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
-
- if (!RS) {
- logAllUnhandledErrors(
- RS.takeError(), errs(),
- "CODLayer/GVsResolver responsibility set lookup failed: ");
- return SymbolNameSet();
- }
-
- if (RS->size() == Symbols.size())
- return *RS;
-
- SymbolNameSet NotFoundViaLegacyLookup;
- for (auto &S : Symbols)
- if (!RS->count(S))
- NotFoundViaLegacyLookup.insert(S);
- auto RS2 =
- LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
-
- for (auto &S : RS2)
- (*RS).insert(S);
-
- return *RS;
- },
- [this, &LD,
- LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
- SymbolNameSet Symbols) {
- auto NotFoundViaLegacyLookup =
- lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
- return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
- });
-
- SetSymbolResolver(LD.K, std::move(GVsResolver));
-
- if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
- return Err;
-
- LD.BaseLayerVModuleKeys.push_back(LD.K);
-
- return Error::success();
- }
-
- static std::string mangle(StringRef Name, const DataLayout &DL) {
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
- }
- return MangledName;
- }
-
- Expected<JITTargetAddress>
- extractAndCompile(LogicalDylib &LD,
- typename LogicalDylib::SourceModuleHandle LMId,
- Function &F) {
- Module &SrcM = LD.getSourceModule(LMId);
-
- // If F is a declaration we must already have compiled it.
- if (F.isDeclaration())
- return 0;
-
- // Grab the name of the function being called here.
- std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
-
- JITTargetAddress CalledAddr = 0;
- auto Part = Partition(F);
- if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
- auto &PartKey = *PartKeyOrErr;
- for (auto *SubF : Part) {
- std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
- if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
- if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
- JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
-
- // If this is the function we're calling record the address so we can
- // return it from this function.
- if (SubF == &F)
- CalledAddr = FnBodyAddr;
-
- // Update the function body pointer for the stub.
- if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
- return 0;
-
- } else
- return FnBodyAddrOrErr.takeError();
- } else if (auto Err = FnBodySym.takeError())
- return std::move(Err);
- else
- llvm_unreachable("Function not emitted for partition");
- }
-
- LD.BaseLayerVModuleKeys.push_back(PartKey);
- } else
- return PartKeyOrErr.takeError();
-
- return CalledAddr;
- }
-
- template <typename PartitionT>
- Expected<VModuleKey>
- emitPartition(LogicalDylib &LD,
- typename LogicalDylib::SourceModuleHandle LMId,
- const PartitionT &Part) {
- Module &SrcM = LD.getSourceModule(LMId);
-
- // Create the module.
- std::string NewName(SrcM.getName());
- for (auto *F : Part) {
- NewName += ".";
- NewName += F->getName();
- }
-
- auto M = std::make_unique<Module>(NewName, SrcM.getContext());
- M->setDataLayout(SrcM.getDataLayout());
- ValueToValueMapTy VMap;
-
- auto Materializer = createLambdaMaterializer([&LD, &LMId,
- &M](Value *V) -> Value * {
- if (auto *GV = dyn_cast<GlobalVariable>(V))
- return cloneGlobalVariableDecl(*M, *GV);
-
- if (auto *F = dyn_cast<Function>(V)) {
- // Check whether we want to clone an available_externally definition.
- if (!LD.getStubsToClone(LMId).count(F))
- return cloneFunctionDecl(*M, *F);
-
- // Ok - we want an inlinable stub. For that to work we need a decl
- // for the stub pointer.
- auto *StubPtr = createImplPointer(*F->getType(), *M,
- F->getName() + "$stub_ptr", nullptr);
- auto *ClonedF = cloneFunctionDecl(*M, *F);
- makeStub(*ClonedF, *StubPtr);
- ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
- ClonedF->addFnAttr(Attribute::AlwaysInline);
- return ClonedF;
- }
-
- if (auto *A = dyn_cast<GlobalAlias>(V)) {
- auto *Ty = A->getValueType();
- if (Ty->isFunctionTy())
- return Function::Create(cast<FunctionType>(Ty),
- GlobalValue::ExternalLinkage, A->getName(),
- M.get());
-
- return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
- nullptr, A->getName(), nullptr,
- GlobalValue::NotThreadLocal,
- A->getType()->getAddressSpace());
- }
-
- return nullptr;
- });
-
- // Create decls in the new module.
- for (auto *F : Part)
- cloneFunctionDecl(*M, *F, &VMap);
-
- // Move the function bodies.
- for (auto *F : Part)
- moveFunctionBody(*F, VMap, &Materializer);
-
- auto K = ES.allocateVModule();
-
- auto LegacyLookup = [this, &LD](StringRef Name) -> JITSymbol {
- return LD.findSymbol(BaseLayer, std::string(Name), false);
- };
-
- // Create memory manager and symbol resolver.
- auto Resolver = createSymbolResolver(
- [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
- auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
- if (!RS) {
- logAllUnhandledErrors(
- RS.takeError(), errs(),
- "CODLayer/SubResolver responsibility set lookup failed: ");
- return SymbolNameSet();
- }
-
- if (RS->size() == Symbols.size())
- return *RS;
-
- SymbolNameSet NotFoundViaLegacyLookup;
- for (auto &S : Symbols)
- if (!RS->count(S))
- NotFoundViaLegacyLookup.insert(S);
-
- auto RS2 =
- LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
-
- for (auto &S : RS2)
- (*RS).insert(S);
-
- return *RS;
- },
- [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
- SymbolNameSet Symbols) {
- auto NotFoundViaLegacyLookup =
- lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
- return LD.BackingResolver->lookup(Q,
- std::move(NotFoundViaLegacyLookup));
- });
- SetSymbolResolver(K, std::move(Resolver));
-
- if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
- return std::move(Err);
-
- return K;
- }
-
- ExecutionSession &ES;
- BaseLayerT &BaseLayer;
- SymbolResolverGetter GetSymbolResolver;
- SymbolResolverSetter SetSymbolResolver;
- PartitioningFtor Partition;
- CompileCallbackMgrT &CompileCallbackMgr;
- IndirectStubsManagerBuilderT CreateIndirectStubsManager;
-
- std::map<VModuleKey, LogicalDylib> LogicalDylibs;
- bool CloneStubsIntoPartitions;
-};
-
-template <typename BaseLayerT, typename CompileCallbackMgrT,
- typename IndirectStubsMgrT>
-LegacyCompileOnDemandLayer<BaseLayerT, CompileCallbackMgrT, IndirectStubsMgrT>::
- LegacyCompileOnDemandLayer(
- ExecutionSession &ES, BaseLayerT &BaseLayer,
- SymbolResolverGetter GetSymbolResolver,
- SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition,
- CompileCallbackMgrT &CallbackMgr,
- IndirectStubsManagerBuilderT CreateIndirectStubsManager,
- bool CloneStubsIntoPartitions)
- : ES(ES), BaseLayer(BaseLayer),
- GetSymbolResolver(std::move(GetSymbolResolver)),
- SetSymbolResolver(std::move(SetSymbolResolver)),
- Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
- CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
- CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
-
} // end namespace orc
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index 8376d163d57a..c7ba57228ab7 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
@@ -28,8 +28,6 @@ class TargetMachine;
namespace orc {
-class JITTargetMachineBuilder;
-
IRSymbolMapper::ManglingOptions
irManglingOptionsFromTargetOptions(const TargetOptions &Opts);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h
index a117acefd2d3..4a4b58ed32e3 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -16,11 +16,14 @@
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/ExecutionEngine/OrcV1Deprecation.h"
#include "llvm/Support/Debug.h"
+#include <atomic>
#include <memory>
#include <vector>
@@ -33,11 +36,67 @@ class ExecutionSession;
class MaterializationUnit;
class MaterializationResponsibility;
class JITDylib;
+class ResourceTracker;
+class InProgressLookupState;
+
enum class SymbolState : uint8_t;
-/// VModuleKey provides a unique identifier (allocated and managed by
-/// ExecutionSessions) for a module added to the JIT.
-using VModuleKey = uint64_t;
+using ResourceTrackerSP = IntrusiveRefCntPtr<ResourceTracker>;
+using JITDylibSP = IntrusiveRefCntPtr<JITDylib>;
+
+using ResourceKey = uintptr_t;
+
+/// API to remove / transfer ownership of JIT resources.
+class ResourceTracker : public ThreadSafeRefCountedBase<ResourceTracker> {
+private:
+ friend class ExecutionSession;
+ friend class JITDylib;
+ friend class MaterializationResponsibility;
+
+public:
+ ResourceTracker(const ResourceTracker &) = delete;
+ ResourceTracker &operator=(const ResourceTracker &) = delete;
+ ResourceTracker(ResourceTracker &&) = delete;
+ ResourceTracker &operator=(ResourceTracker &&) = delete;
+
+ ~ResourceTracker();
+
+ /// Return the JITDylib targeted by this tracker.
+ JITDylib &getJITDylib() const {
+ return *reinterpret_cast<JITDylib *>(JDAndFlag.load() &
+ ~static_cast<uintptr_t>(1));
+ }
+
+ /// Remove all resources associated with this key.
+ Error remove();
+
+ /// Transfer all resources associated with this key to the given
+ /// tracker, which must target the same JITDylib as this one.
+ void transferTo(ResourceTracker &DstRT);
+
+ /// Return true if this tracker has become defunct.
+ bool isDefunct() const { return JDAndFlag.load() & 0x1; }
+
+ /// Returns the key associated with this tracker.
+ /// This method should not be used except for debug logging: there is no
+ /// guarantee that the returned value will remain valid.
+ ResourceKey getKeyUnsafe() const { return reinterpret_cast<uintptr_t>(this); }
+
+private:
+ ResourceTracker(JITDylibSP JD);
+
+ void makeDefunct();
+
+ std::atomic_uintptr_t JDAndFlag;
+};
+
+/// Listens for ResourceTracker operations.
+class ResourceManager {
+public:
+ virtual ~ResourceManager();
+ virtual Error handleRemoveResources(ResourceKey K) = 0;
+ virtual void handleTransferResources(ResourceKey DstK, ResourceKey SrcK) = 0;
+};
/// A set of symbol names (represented by SymbolStringPtrs for
// efficiency).
@@ -158,9 +217,19 @@ public:
/// Add an element to the set. The client is responsible for checking that
/// duplicates are not added.
- void add(SymbolStringPtr Name,
- SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+ SymbolLookupSet &
+ add(SymbolStringPtr Name,
+ SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
Symbols.push_back(std::make_pair(std::move(Name), Flags));
+ return *this;
+ }
+
+ /// Quickly append one lookup set to another.
+ SymbolLookupSet &append(SymbolLookupSet Other) {
+ Symbols.reserve(Symbols.size() + Other.size());
+ for (auto &KV : Other)
+ Symbols.push_back(std::move(KV));
+ return *this;
}
bool empty() const { return Symbols.empty(); }
@@ -287,7 +356,7 @@ public:
for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
if (Symbols[I].first == Symbols[I - 1].first)
return true;
- return true;
+ return false;
}
#endif
@@ -318,6 +387,18 @@ using RegisterDependenciesFunction =
/// are no dependants to register with.
extern RegisterDependenciesFunction NoDependenciesToRegister;
+class ResourceTrackerDefunct : public ErrorInfo<ResourceTrackerDefunct> {
+public:
+ static char ID;
+
+ ResourceTrackerDefunct(ResourceTrackerSP RT);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+
+private:
+ ResourceTrackerSP RT;
+};
+
/// Used to notify a JITDylib that the given set of symbols failed to
/// materialize.
class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
@@ -408,9 +489,10 @@ private:
/// emit symbols, or abandon materialization by notifying any unmaterialized
/// symbols of an error.
class MaterializationResponsibility {
- friend class MaterializationUnit;
+ friend class ExecutionSession;
+
public:
- MaterializationResponsibility(MaterializationResponsibility &&) = default;
+ MaterializationResponsibility(MaterializationResponsibility &&) = delete;
MaterializationResponsibility &
operator=(MaterializationResponsibility &&) = delete;
@@ -419,12 +501,15 @@ public:
/// emitted or notified of an error.
~MaterializationResponsibility();
+ /// Returns the ResourceTracker for this instance.
+ template <typename Func> Error withResourceKeyDo(Func &&F) const;
+
/// Returns the target JITDylib that these symbols are being materialized
/// into.
JITDylib &getTargetJITDylib() const { return *JD; }
- /// Returns the VModuleKey for this instance.
- VModuleKey getVModuleKey() const { return K; }
+ /// Returns the ExecutionSession for this instance.
+ ExecutionSession &getExecutionSession();
/// Returns the symbol flags map for this responsibility instance.
/// Note: The returned flags may have transient flags (Lazy, Materializing)
@@ -509,13 +594,13 @@ public:
/// materializers to break up work based on run-time information (e.g.
/// by introspecting which symbols have actually been looked up and
/// materializing only those).
- void replace(std::unique_ptr<MaterializationUnit> MU);
+ Error replace(std::unique_ptr<MaterializationUnit> MU);
/// Delegates responsibility for the given symbols to the returned
/// materialization responsibility. Useful for breaking up work between
/// threads, or different kinds of materialization processes.
- MaterializationResponsibility delegate(const SymbolNameSet &Symbols,
- VModuleKey NewKey = VModuleKey());
+ Expected<std::unique_ptr<MaterializationResponsibility>>
+ delegate(const SymbolNameSet &Symbols);
void addDependencies(const SymbolStringPtr &Name,
const SymbolDependenceMap &Dependencies);
@@ -526,19 +611,17 @@ public:
private:
/// Create a MaterializationResponsibility for the given JITDylib and
/// initial symbols.
- MaterializationResponsibility(std::shared_ptr<JITDylib> JD,
- SymbolFlagsMap SymbolFlags,
- SymbolStringPtr InitSymbol, VModuleKey K)
+ MaterializationResponsibility(JITDylibSP JD, SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol)
: JD(std::move(JD)), SymbolFlags(std::move(SymbolFlags)),
- InitSymbol(std::move(InitSymbol)), K(std::move(K)) {
- assert(this->JD && "Cannot initialize with null JD");
+ InitSymbol(std::move(InitSymbol)) {
+ assert(this->JD && "Cannot initialize with null JITDylib");
assert(!this->SymbolFlags.empty() && "Materializing nothing?");
}
- std::shared_ptr<JITDylib> JD;
+ JITDylibSP JD;
SymbolFlagsMap SymbolFlags;
SymbolStringPtr InitSymbol;
- VModuleKey K;
};
/// A MaterializationUnit represents a set of symbol definitions that can
@@ -555,9 +638,9 @@ class MaterializationUnit {
public:
MaterializationUnit(SymbolFlagsMap InitalSymbolFlags,
- SymbolStringPtr InitSymbol, VModuleKey K)
+ SymbolStringPtr InitSymbol)
: SymbolFlags(std::move(InitalSymbolFlags)),
- InitSymbol(std::move(InitSymbol)), K(std::move(K)) {
+ InitSymbol(std::move(InitSymbol)) {
assert((!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) &&
"If set, InitSymbol should appear in InitialSymbolFlags map");
}
@@ -577,7 +660,8 @@ public:
/// Implementations of this method should materialize all symbols
/// in the materialzation unit, except for those that have been
/// previously discarded.
- virtual void materialize(MaterializationResponsibility R) = 0;
+ virtual void
+ materialize(std::unique_ptr<MaterializationResponsibility> R) = 0;
/// Called by JITDylibs to notify MaterializationUnits that the given symbol
/// has been overridden.
@@ -589,17 +673,10 @@ public:
protected:
SymbolFlagsMap SymbolFlags;
SymbolStringPtr InitSymbol;
- VModuleKey K;
private:
virtual void anchor();
- MaterializationResponsibility
- createMaterializationResponsibility(std::shared_ptr<JITDylib> JD) {
- return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
- std::move(InitSymbol), K);
- }
-
/// Implementations of this method should discard the given symbol
/// from the source (e.g. if the source is an LLVM IR Module and the
/// symbol is a function, delete the function body or mark it available
@@ -607,21 +684,18 @@ private:
virtual void discard(const JITDylib &JD, const SymbolStringPtr &Name) = 0;
};
-using MaterializationUnitList =
- std::vector<std::unique_ptr<MaterializationUnit>>;
-
/// A MaterializationUnit implementation for pre-existing absolute symbols.
///
/// All symbols will be resolved and marked ready as soon as the unit is
/// materialized.
class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit {
public:
- AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols, VModuleKey K);
+ AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols);
StringRef getName() const override;
private:
- void materialize(MaterializationResponsibility R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolMap &Symbols);
@@ -639,9 +713,9 @@ private:
/// \endcode
///
inline std::unique_ptr<AbsoluteSymbolsMaterializationUnit>
-absoluteSymbols(SymbolMap Symbols, VModuleKey K = VModuleKey()) {
+absoluteSymbols(SymbolMap Symbols) {
return std::make_unique<AbsoluteSymbolsMaterializationUnit>(
- std::move(Symbols), std::move(K));
+ std::move(Symbols));
}
/// A materialization unit for symbol aliases. Allows existing symbols to be
@@ -658,12 +732,12 @@ public:
/// resolved.
ReExportsMaterializationUnit(JITDylib *SourceJD,
JITDylibLookupFlags SourceJDLookupFlags,
- SymbolAliasMap Aliases, VModuleKey K);
+ SymbolAliasMap Aliases);
StringRef getName() const override;
private:
- void materialize(MaterializationResponsibility R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
@@ -684,10 +758,9 @@ private:
/// return Err;
/// \endcode
inline std::unique_ptr<ReExportsMaterializationUnit>
-symbolAliases(SymbolAliasMap Aliases, VModuleKey K = VModuleKey()) {
+symbolAliases(SymbolAliasMap Aliases) {
return std::make_unique<ReExportsMaterializationUnit>(
- nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases),
- std::move(K));
+ nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases));
}
/// Create a materialization unit for re-exporting symbols from another JITDylib
@@ -696,10 +769,9 @@ symbolAliases(SymbolAliasMap Aliases, VModuleKey K = VModuleKey()) {
inline std::unique_ptr<ReExportsMaterializationUnit>
reexports(JITDylib &SourceJD, SymbolAliasMap Aliases,
JITDylibLookupFlags SourceJDLookupFlags =
- JITDylibLookupFlags::MatchExportedSymbolsOnly,
- VModuleKey K = VModuleKey()) {
+ JITDylibLookupFlags::MatchExportedSymbolsOnly) {
return std::make_unique<ReExportsMaterializationUnit>(
- &SourceJD, SourceJDLookupFlags, std::move(Aliases), std::move(K));
+ &SourceJD, SourceJDLookupFlags, std::move(Aliases));
}
/// Build a SymbolAliasMap for the common case where you want to re-export
@@ -723,8 +795,10 @@ enum class SymbolState : uint8_t {
/// makes a callback when all symbols are available.
class AsynchronousSymbolQuery {
friend class ExecutionSession;
+ friend class InProgressFullLookupState;
friend class JITDylib;
friend class JITSymbolResolverAdapter;
+ friend class MaterializationResponsibility;
public:
/// Create a query for the given symbols. The NotifyComplete
@@ -757,8 +831,6 @@ private:
void dropSymbol(const SymbolStringPtr &Name);
- bool canStillFail();
-
void handleFailed(Error Err);
void detach();
@@ -770,34 +842,62 @@ private:
SymbolState RequiredState;
};
+/// Wraps state for a lookup-in-progress.
+/// DefinitionGenerators can optionally take ownership of a LookupState object
+/// to suspend a lookup-in-progress while they search for definitions.
+class LookupState {
+ friend class OrcV2CAPIHelper;
+ friend class ExecutionSession;
+
+public:
+ LookupState();
+ LookupState(LookupState &&);
+ LookupState &operator=(LookupState &&);
+ ~LookupState();
+
+ /// Continue the lookup. This can be called by DefinitionGenerators
+ /// to re-start a captured query-application operation.
+ void continueLookup(Error Err);
+
+private:
+ LookupState(std::unique_ptr<InProgressLookupState> IPLS);
+
+ // For C API.
+ void reset(InProgressLookupState *IPLS);
+
+ std::unique_ptr<InProgressLookupState> IPLS;
+};
+
+/// Definition generators can be attached to JITDylibs to generate new
+/// definitions for otherwise unresolved symbols during lookup.
+class DefinitionGenerator {
+public:
+ virtual ~DefinitionGenerator();
+
+ /// DefinitionGenerators should override this method to insert new
+ /// definitions into the parent JITDylib. K specifies the kind of this
+ /// lookup. JD specifies the target JITDylib being searched, and
+ /// JDLookupFlags specifies whether the search should match against
+ /// hidden symbols. Finally, Symbols describes the set of unresolved
+ /// symbols and their associated lookup flags.
+ virtual Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) = 0;
+};
+
/// A symbol table that supports asynchoronous symbol queries.
///
/// Represents a virtual shared object. Instances can not be copied or moved, so
/// their addresses may be used as keys for resource management.
/// JITDylib state changes must be made via an ExecutionSession to guarantee
/// that they are synchronized with respect to other JITDylib operations.
-class JITDylib : public std::enable_shared_from_this<JITDylib> {
+class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
+ public jitlink::JITLinkDylib {
friend class AsynchronousSymbolQuery;
friend class ExecutionSession;
friend class Platform;
friend class MaterializationResponsibility;
public:
- /// Definition generators can be attached to JITDylibs to generate new
- /// definitions for otherwise unresolved symbols during lookup.
- class DefinitionGenerator {
- public:
- virtual ~DefinitionGenerator();
-
- /// DefinitionGenerators should override this method to insert new
- /// definitions into the parent JITDylib. K specifies the kind of this
- /// lookup. JD specifies the target JITDylib being searched, and
- /// JDLookupFlags specifies whether the search should match against
- /// hidden symbols. Finally, Symbols describes the set of unresolved
- /// symbols and their associated lookup flags.
- virtual Error tryToGenerate(LookupKind K, JITDylib &JD,
- JITDylibLookupFlags JDLookupFlags,
- const SymbolLookupSet &LookupSet) = 0;
- };
using AsynchronousSymbolQuerySet =
std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
@@ -813,6 +913,21 @@ public:
/// Get a reference to the ExecutionSession for this JITDylib.
ExecutionSession &getExecutionSession() const { return ES; }
+ /// Calls remove on all trackers currently associated with this JITDylib.
+ /// Does not run static deinits.
+ ///
+ /// Note that removal happens outside the session lock, so new code may be
+ /// added concurrently while the clear is underway, and the newly added
+ /// code will *not* be cleared. Adding new code concurrently with a clear
+ /// is usually a bug and should be avoided.
+ Error clear();
+
+ /// Get the default resource tracker for this JITDylib.
+ ResourceTrackerSP getDefaultResourceTracker();
+
+ /// Create a resource tracker for this JITDylib.
+ ResourceTrackerSP createResourceTracker();
+
/// Adds a definition generator to this JITDylib and returns a referenece to
/// it.
///
@@ -873,10 +988,13 @@ public:
/// Define all symbols provided by the materialization unit to be part of this
/// JITDylib.
///
+ /// If RT is not specified then the default resource tracker will be used.
+ ///
/// This overload always takes ownership of the MaterializationUnit. If any
/// errors occur, the MaterializationUnit consumed.
template <typename MaterializationUnitType>
- Error define(std::unique_ptr<MaterializationUnitType> &&MU);
+ Error define(std::unique_ptr<MaterializationUnitType> &&MU,
+ ResourceTrackerSP RT = nullptr);
/// Define all symbols provided by the materialization unit to be part of this
/// JITDylib.
@@ -886,7 +1004,8 @@ public:
/// may allow the caller to modify the MaterializationUnit to correct the
/// issue, then re-call define.
template <typename MaterializationUnitType>
- Error define(std::unique_ptr<MaterializationUnitType> &MU);
+ Error define(std::unique_ptr<MaterializationUnitType> &MU,
+ ResourceTrackerSP RT = nullptr);
/// Tries to remove the given symbols.
///
@@ -900,41 +1019,47 @@ public:
/// left unmodified (no symbols are removed).
Error remove(const SymbolNameSet &Names);
- /// Search the given JITDylib for the symbols in Symbols. If found, store
- /// the flags for each symbol in Flags. If any required symbols are not found
- /// then an error will be returned.
- Expected<SymbolFlagsMap> lookupFlags(LookupKind K,
- JITDylibLookupFlags JDLookupFlags,
- SymbolLookupSet LookupSet);
-
/// Dump current JITDylib state to OS.
void dump(raw_ostream &OS);
- /// FIXME: Remove this when we remove the old ORC layers.
- /// Search the given JITDylibs in order for the symbols in Symbols. Results
- /// (once they become available) will be returned via the given Query.
- ///
- /// If any symbol is not found then the unresolved symbols will be returned,
- /// and the query will not be applied. The Query is not failed and can be
- /// re-used in a subsequent lookup once the symbols have been added, or
- /// manually failed.
- Expected<SymbolNameSet>
- legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names);
+ /// Returns the given JITDylibs and all of their transitive dependencies in
+ /// DFS order (based on linkage relationships). Each JITDylib will appear
+ /// only once.
+ static std::vector<JITDylibSP> getDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
+
+ /// Returns the given JITDylibs and all of their transitive dependensies in
+ /// reverse DFS order (based on linkage relationships). Each JITDylib will
+ /// appear only once.
+ static std::vector<JITDylibSP>
+ getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
+
+ /// Return this JITDylib and its transitive dependencies in DFS order
+ /// based on linkage relationships.
+ std::vector<JITDylibSP> getDFSLinkOrder();
+
+ /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order
+ /// based on linkage relationships.
+ std::vector<JITDylibSP> getReverseDFSLinkOrder();
private:
using AsynchronousSymbolQueryList =
std::vector<std::shared_ptr<AsynchronousSymbolQuery>>;
struct UnmaterializedInfo {
- UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU)
- : MU(std::move(MU)) {}
+ UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU,
+ ResourceTracker *RT)
+ : MU(std::move(MU)), RT(RT) {}
std::unique_ptr<MaterializationUnit> MU;
+ ResourceTracker *RT;
};
using UnmaterializedInfosMap =
DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>;
+ using UnmaterializedInfosList =
+ std::vector<std::shared_ptr<UnmaterializedInfo>>;
+
struct MaterializingInfo {
SymbolDependenceMap Dependants;
SymbolDependenceMap UnemittedDependencies;
@@ -1001,25 +1126,16 @@ private:
JITDylib(ExecutionSession &ES, std::string Name);
- Error defineImpl(MaterializationUnit &MU);
-
- void lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K,
- JITDylibLookupFlags JDLookupFlags,
- SymbolLookupSet &Unresolved);
+ ResourceTrackerSP getTracker(MaterializationResponsibility &MR);
+ std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>>
+ removeTracker(ResourceTracker &RT);
- Error lodgeQuery(MaterializationUnitList &MUs,
- std::shared_ptr<AsynchronousSymbolQuery> &Q, LookupKind K,
- JITDylibLookupFlags JDLookupFlags,
- SymbolLookupSet &Unresolved);
+ void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
- Error lodgeQueryImpl(MaterializationUnitList &MUs,
- std::shared_ptr<AsynchronousSymbolQuery> &Q,
- LookupKind K, JITDylibLookupFlags JDLookupFlags,
- SymbolLookupSet &Unresolved);
+ Error defineImpl(MaterializationUnit &MU);
- bool lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
- SymbolLookupSet &Unresolved);
+ void installMaterializationUnit(std::unique_ptr<MaterializationUnit> MU,
+ ResourceTracker &RT);
void detachQueryHelper(AsynchronousSymbolQuery &Q,
const SymbolNameSet &QuerySymbols);
@@ -1030,29 +1146,45 @@ private:
Expected<SymbolFlagsMap> defineMaterializing(SymbolFlagsMap SymbolFlags);
- void replace(std::unique_ptr<MaterializationUnit> MU);
+ Error replace(MaterializationResponsibility &FromMR,
+ std::unique_ptr<MaterializationUnit> MU);
+
+ Expected<std::unique_ptr<MaterializationResponsibility>>
+ delegate(MaterializationResponsibility &FromMR, SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol);
SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const;
void addDependencies(const SymbolStringPtr &Name,
const SymbolDependenceMap &Dependants);
- Error resolve(const SymbolMap &Resolved);
+ Error resolve(MaterializationResponsibility &MR, const SymbolMap &Resolved);
+
+ Error emit(MaterializationResponsibility &MR, const SymbolFlagsMap &Emitted);
- Error emit(const SymbolFlagsMap &Emitted);
+ void unlinkMaterializationResponsibility(MaterializationResponsibility &MR);
using FailedSymbolsWorklist =
std::vector<std::pair<JITDylib *, SymbolStringPtr>>;
- static void notifyFailed(FailedSymbolsWorklist FailedSymbols);
+
+ static std::pair<AsynchronousSymbolQuerySet,
+ std::shared_ptr<SymbolDependenceMap>>
+ failSymbols(FailedSymbolsWorklist);
ExecutionSession &ES;
std::string JITDylibName;
+ std::mutex GeneratorsMutex;
bool Open = true;
SymbolTable Symbols;
UnmaterializedInfosMap UnmaterializedInfos;
MaterializingInfosMap MaterializingInfos;
- std::vector<std::unique_ptr<DefinitionGenerator>> DefGenerators;
+ std::vector<std::shared_ptr<DefinitionGenerator>> DefGenerators;
JITDylibSearchOrder LinkOrder;
+ ResourceTrackerSP DefaultTracker;
+
+ // Map trackers to sets of symbols tracked.
+ DenseMap<ResourceTracker *, SymbolNameVector> TrackerSymbols;
+ DenseMap<MaterializationResponsibility *, ResourceTracker *> MRTrackers;
};
/// Platforms set up standard symbols and mediate interactions between dynamic
@@ -1071,11 +1203,12 @@ public:
/// This method will be called under the ExecutionSession lock each time a
/// MaterializationUnit is added to a JITDylib.
- virtual Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) = 0;
+ virtual Error notifyAdding(ResourceTracker &RT,
+ const MaterializationUnit &MU) = 0;
/// This method will be called under the ExecutionSession lock when a
- /// VModuleKey is removed.
- virtual Error notifyRemoving(JITDylib &JD, VModuleKey K) = 0;
+ /// ResourceTracker is removed.
+ virtual Error notifyRemoving(ResourceTracker &RT) = 0;
/// A utility function for looking up initializer symbols. Performs a blocking
/// lookup for the given symbols in each of the given JITDylibs.
@@ -1086,8 +1219,12 @@ public:
/// An ExecutionSession represents a running JIT program.
class ExecutionSession {
- // FIXME: Remove this when we remove the old ORC layers.
+ friend class InProgressLookupFlagsState;
+ friend class InProgressFullLookupState;
friend class JITDylib;
+ friend class LookupState;
+ friend class MaterializationResponsibility;
+ friend class ResourceTracker;
public:
/// For reporting errors.
@@ -1096,13 +1233,16 @@ public:
/// For dispatching MaterializationUnit::materialize calls.
using DispatchMaterializationFunction =
std::function<void(std::unique_ptr<MaterializationUnit> MU,
- MaterializationResponsibility MR)>;
+ std::unique_ptr<MaterializationResponsibility> MR)>;
/// Construct an ExecutionSession.
///
/// SymbolStringPools may be shared between ExecutionSessions.
ExecutionSession(std::shared_ptr<SymbolStringPool> SSP = nullptr);
+ /// End the session. Closes all JITDylibs.
+ Error endSession();
+
/// Add a symbol name to the SymbolStringPool and return a pointer to it.
SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); }
@@ -1122,6 +1262,14 @@ public:
return F();
}
+ /// Register the given ResourceManager with this ExecutionSession.
+ /// Managers will be notified of events in reverse order of registration.
+ void registerResourceManager(ResourceManager &RM);
+
+ /// Deregister the given ResourceManager with this ExecutionSession.
+ /// Manager must have been previously registered.
+ void deregisterResourceManager(ResourceManager &RM);
+
/// Return a pointer to the "name" JITDylib.
/// Ownership of JITDylib remains within Execution Session
JITDylib *getJITDylibByName(StringRef Name);
@@ -1147,17 +1295,6 @@ public:
/// If no Platform is attached this call is equivalent to createBareJITDylib.
Expected<JITDylib &> createJITDylib(std::string Name);
- /// Allocate a module key for a new module to add to the JIT.
- VModuleKey allocateVModule() {
- return runSessionLocked([this]() { return ++LastKey; });
- }
-
- /// Return a module key to the ExecutionSession so that it can be
- /// re-used. This should only be done once all resources associated
- /// with the original key have been released.
- void releaseVModule(VModuleKey Key) { /* FIXME: Recycle keys */
- }
-
/// Set the error reporter function.
ExecutionSession &setErrorReporter(ErrorReporter ReportError) {
this->ReportError = std::move(ReportError);
@@ -1176,19 +1313,18 @@ public:
return *this;
}
- void legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err);
+ /// Search the given JITDylibs to find the flags associated with each of the
+ /// given symbols.
+ void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
+ SymbolLookupSet Symbols,
+ unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
- using LegacyAsyncLookupFunction = std::function<SymbolNameSet(
- std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names)>;
-
- /// A legacy lookup function for JITSymbolResolverAdapter.
- /// Do not use -- this will be removed soon.
- Expected<SymbolMap>
- legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
- SymbolState RequiredState,
- RegisterDependenciesFunction RegisterDependencies);
+ /// Blocking version of lookupFlags.
+ Expected<SymbolFlagsMap> lookupFlags(LookupKind K,
+ JITDylibSearchOrder SearchOrder,
+ SymbolLookupSet Symbols);
- /// Search the given JITDylib list for the given symbols.
+ /// Search the given JITDylibs for the given symbols.
///
/// SearchOrder lists the JITDylibs to search. For each dylib, the associated
/// boolean indicates whether the search should match against non-exported
@@ -1248,10 +1384,11 @@ public:
SymbolState RequiredState = SymbolState::Ready);
/// Materialize the given unit.
- void dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
- MaterializationResponsibility MR) {
+ void
+ dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
+ std::unique_ptr<MaterializationResponsibility> MR) {
assert(MU && "MU must be non-null");
- DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR.getTargetJITDylib(), *MU));
+ DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU));
DispatchMaterialization(std::move(MU), std::move(MR));
}
@@ -1263,41 +1400,124 @@ private:
logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
}
- static void
- materializeOnCurrentThread(std::unique_ptr<MaterializationUnit> MU,
- MaterializationResponsibility MR) {
+ static void materializeOnCurrentThread(
+ std::unique_ptr<MaterializationUnit> MU,
+ std::unique_ptr<MaterializationResponsibility> MR) {
MU->materialize(std::move(MR));
}
- void runOutstandingMUs();
+ void dispatchOutstandingMUs();
+
+ static std::unique_ptr<MaterializationResponsibility>
+ createMaterializationResponsibility(ResourceTracker &RT,
+ SymbolFlagsMap Symbols,
+ SymbolStringPtr InitSymbol) {
+ auto &JD = RT.getJITDylib();
+ std::unique_ptr<MaterializationResponsibility> MR(
+ new MaterializationResponsibility(&JD, std::move(Symbols),
+ std::move(InitSymbol)));
+ JD.MRTrackers[MR.get()] = &RT;
+ return MR;
+ }
+
+ Error removeResourceTracker(ResourceTracker &RT);
+ void transferResourceTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
+ void destroyResourceTracker(ResourceTracker &RT);
+
+ // State machine functions for query application..
+
+ /// IL_updateCandidatesFor is called to remove already-defined symbols that
+ /// match a given query from the set of candidate symbols to generate
+ /// definitions for (no need to generate a definition if one already exists).
+ Error IL_updateCandidatesFor(JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &Candidates,
+ SymbolLookupSet *NonCandidates);
+
+ /// OL_applyQueryPhase1 is an optionally re-startable loop for triggering
+ /// definition generation. It is called when a lookup is performed, and again
+ /// each time that LookupState::continueLookup is called.
+ void OL_applyQueryPhase1(std::unique_ptr<InProgressLookupState> IPLS,
+ Error Err);
+
+ /// OL_completeLookup is run once phase 1 successfully completes for a lookup
+ /// call. It attempts to attach the symbol to all symbol table entries and
+ /// collect all MaterializationUnits to dispatch. If this method fails then
+ /// all MaterializationUnits will be left un-materialized.
+ void OL_completeLookup(std::unique_ptr<InProgressLookupState> IPLS,
+ std::shared_ptr<AsynchronousSymbolQuery> Q,
+ RegisterDependenciesFunction RegisterDependencies);
+
+ /// OL_completeLookupFlags is run once phase 1 successfully completes for a
+ /// lookupFlags call.
+ void OL_completeLookupFlags(
+ std::unique_ptr<InProgressLookupState> IPLS,
+ unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
+
+ // State machine functions for MaterializationResponsibility.
+ void OL_destroyMaterializationResponsibility(
+ MaterializationResponsibility &MR);
+ SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR);
+ Error OL_notifyResolved(MaterializationResponsibility &MR,
+ const SymbolMap &Symbols);
+ Error OL_notifyEmitted(MaterializationResponsibility &MR);
+ Error OL_defineMaterializing(MaterializationResponsibility &MR,
+ SymbolFlagsMap SymbolFlags);
+ void OL_notifyFailed(MaterializationResponsibility &MR);
+ Error OL_replace(MaterializationResponsibility &MR,
+ std::unique_ptr<MaterializationUnit> MU);
+ Expected<std::unique_ptr<MaterializationResponsibility>>
+ OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols);
+ void OL_addDependencies(MaterializationResponsibility &MR,
+ const SymbolStringPtr &Name,
+ const SymbolDependenceMap &Dependencies);
+ void OL_addDependenciesForAll(MaterializationResponsibility &MR,
+ const SymbolDependenceMap &Dependencies);
#ifndef NDEBUG
void dumpDispatchInfo(JITDylib &JD, MaterializationUnit &MU);
#endif // NDEBUG
mutable std::recursive_mutex SessionMutex;
+ bool SessionOpen = true;
std::shared_ptr<SymbolStringPool> SSP;
std::unique_ptr<Platform> P;
- VModuleKey LastKey = 0;
ErrorReporter ReportError = logErrorsToStdErr;
DispatchMaterializationFunction DispatchMaterialization =
materializeOnCurrentThread;
- std::vector<std::shared_ptr<JITDylib>> JDs;
+ std::vector<ResourceManager *> ResourceManagers;
+
+ std::vector<JITDylibSP> JDs;
// FIXME: Remove this (and runOutstandingMUs) once the linking layer works
// with callbacks from asynchronous queries.
mutable std::recursive_mutex OutstandingMUsMutex;
std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
- MaterializationResponsibility>>
+ std::unique_ptr<MaterializationResponsibility>>>
OutstandingMUs;
};
+inline ExecutionSession &MaterializationResponsibility::getExecutionSession() {
+ return JD->getExecutionSession();
+}
+
+template <typename Func>
+Error MaterializationResponsibility::withResourceKeyDo(Func &&F) const {
+ return JD->getExecutionSession().runSessionLocked([&]() -> Error {
+ auto I = JD->MRTrackers.find(this);
+ assert(I != JD->MRTrackers.end() && "No tracker for this MR");
+ if (I->second->isDefunct())
+ return make_error<ResourceTrackerDefunct>(I->second);
+ F(I->second->getKeyUnsafe());
+ return Error::success();
+ });
+}
+
template <typename GeneratorT>
GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) {
auto &G = *DefGenerator;
- ES.runSessionLocked(
- [&]() { DefGenerators.push_back(std::move(DefGenerator)); });
+ std::lock_guard<std::mutex> Lock(GeneratorsMutex);
+ DefGenerators.push_back(std::move(DefGenerator));
return G;
}
@@ -1308,7 +1528,8 @@ auto JITDylib::withLinkOrderDo(Func &&F)
}
template <typename MaterializationUnitType>
-Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU) {
+Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
+ ResourceTrackerSP RT) {
assert(MU && "Can not define with a null MU");
if (MU->getSymbols().empty()) {
@@ -1320,29 +1541,36 @@ Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU) {
return Error::success();
} else
DEBUG_WITH_TYPE("orc", {
- dbgs() << "Defining MU " << MU->getName() << " for " << getName() << "\n";
+ dbgs() << "Defining MU " << MU->getName() << " for " << getName()
+ << " (tracker: ";
+ if (RT == getDefaultResourceTracker())
+ dbgs() << "default)";
+ else if (RT)
+ dbgs() << RT.get() << ")\n";
+ else
+ dbgs() << "0x0, default will be used)\n";
});
return ES.runSessionLocked([&, this]() -> Error {
if (auto Err = defineImpl(*MU))
return Err;
+ if (!RT)
+ RT = getDefaultResourceTracker();
+
if (auto *P = ES.getPlatform()) {
- if (auto Err = P->notifyAdding(*this, *MU))
+ if (auto Err = P->notifyAdding(*RT, *MU))
return Err;
}
- /// defineImpl succeeded.
- auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
- for (auto &KV : UMI->MU->getSymbols())
- UnmaterializedInfos[KV.first] = UMI;
-
+ installMaterializationUnit(std::move(MU), *RT);
return Error::success();
});
}
template <typename MaterializationUnitType>
-Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU) {
+Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU,
+ ResourceTrackerSP RT) {
assert(MU && "Can not define with a null MU");
if (MU->getSymbols().empty()) {
@@ -1354,30 +1582,36 @@ Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU) {
return Error::success();
} else
DEBUG_WITH_TYPE("orc", {
- dbgs() << "Defining MU " << MU->getName() << " for " << getName() << "\n";
+ dbgs() << "Defining MU " << MU->getName() << " for " << getName()
+ << " (tracker: ";
+ if (RT == getDefaultResourceTracker())
+ dbgs() << "default)";
+ else if (RT)
+ dbgs() << RT.get() << ")\n";
+ else
+ dbgs() << "0x0, default will be used)\n";
});
return ES.runSessionLocked([&, this]() -> Error {
if (auto Err = defineImpl(*MU))
return Err;
+ if (!RT)
+ RT = getDefaultResourceTracker();
+
if (auto *P = ES.getPlatform()) {
- if (auto Err = P->notifyAdding(*this, *MU))
+ if (auto Err = P->notifyAdding(*RT, *MU))
return Err;
}
- /// defineImpl succeeded.
- auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
- for (auto &KV : UMI->MU->getSymbols())
- UnmaterializedInfos[KV.first] = UMI;
-
+ installMaterializationUnit(std::move(MU), *RT);
return Error::success();
});
}
/// ReexportsGenerator can be used with JITDylib::addGenerator to automatically
/// re-export a subset of the source JITDylib's symbols in the target.
-class ReexportsGenerator : public JITDylib::DefinitionGenerator {
+class ReexportsGenerator : public DefinitionGenerator {
public:
using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
@@ -1388,7 +1622,7 @@ public:
JITDylibLookupFlags SourceJDLookupFlags,
SymbolPredicate Allow = SymbolPredicate());
- Error tryToGenerate(LookupKind K, JITDylib &JD,
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags,
const SymbolLookupSet &LookupSet) override;
@@ -1398,6 +1632,57 @@ private:
SymbolPredicate Allow;
};
+// --------------- IMPLEMENTATION --------------
+// Implementations for inline functions/methods.
+// ---------------------------------------------
+
+inline MaterializationResponsibility::~MaterializationResponsibility() {
+ JD->getExecutionSession().OL_destroyMaterializationResponsibility(*this);
+}
+
+inline SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
+ return JD->getExecutionSession().OL_getRequestedSymbols(*this);
+}
+
+inline Error MaterializationResponsibility::notifyResolved(
+ const SymbolMap &Symbols) {
+ return JD->getExecutionSession().OL_notifyResolved(*this, Symbols);
+}
+
+inline Error MaterializationResponsibility::notifyEmitted() {
+ return JD->getExecutionSession().OL_notifyEmitted(*this);
+}
+
+inline Error MaterializationResponsibility::defineMaterializing(
+ SymbolFlagsMap SymbolFlags) {
+ return JD->getExecutionSession().OL_defineMaterializing(
+ *this, std::move(SymbolFlags));
+}
+
+inline void MaterializationResponsibility::failMaterialization() {
+ JD->getExecutionSession().OL_notifyFailed(*this);
+}
+
+inline Error MaterializationResponsibility::replace(
+ std::unique_ptr<MaterializationUnit> MU) {
+ return JD->getExecutionSession().OL_replace(*this, std::move(MU));
+}
+
+inline Expected<std::unique_ptr<MaterializationResponsibility>>
+MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) {
+ return JD->getExecutionSession().OL_delegate(*this, Symbols);
+}
+
+inline void MaterializationResponsibility::addDependencies(
+ const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
+ JD->getExecutionSession().OL_addDependencies(*this, Name, Dependencies);
+}
+
+inline void MaterializationResponsibility::addDependenciesForAll(
+ const SymbolDependenceMap &Dependencies) {
+ JD->getExecutionSession().OL_addDependenciesForAll(*this, Dependencies);
+}
+
} // End namespace orc
} // End namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index 3b824b83b052..fdddc9694d0b 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -18,7 +18,7 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Mangling.h"
-#include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/Archive.h"
#include "llvm/Support/DynamicLibrary.h"
@@ -41,17 +41,6 @@ namespace orc {
class ObjectLayer;
-/// Run a main function, returning the result.
-///
-/// If the optional ProgramName argument is given then it will be inserted
-/// before the strings in Args as the first argument to the called function.
-///
-/// It is legal to have an empty argument list and no program name, however
-/// many main functions will expect a name argument at least, and will fail
-/// if none is provided.
-int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args,
- Optional<StringRef> ProgramName = None);
-
/// This iterator provides a convenient way to iterate over the elements
/// of an llvm.global_ctors/llvm.global_dtors instance.
///
@@ -152,56 +141,6 @@ inline iterator_range<StaticInitGVIterator> getStaticInitGVs(Module &M) {
return make_range(StaticInitGVIterator(M), StaticInitGVIterator());
}
-/// Convenience class for recording constructor/destructor names for
-/// later execution.
-template <typename JITLayerT>
-class LegacyCtorDtorRunner {
-public:
- /// Construct a CtorDtorRunner for the given range using the given
- /// name mangling function.
- LLVM_ATTRIBUTE_DEPRECATED(
- LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames,
- VModuleKey K),
- "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
- "Please use the ORCv2 CtorDtorRunner utility instead");
-
- LegacyCtorDtorRunner(ORCv1DeprecationAcknowledgement,
- std::vector<std::string> CtorDtorNames, VModuleKey K)
- : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
-
- /// Run the recorded constructors/destructors through the given JIT
- /// layer.
- Error runViaLayer(JITLayerT &JITLayer) const {
- using CtorDtorTy = void (*)();
-
- for (const auto &CtorDtorName : CtorDtorNames) {
- if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) {
- if (auto AddrOrErr = CtorDtorSym.getAddress()) {
- CtorDtorTy CtorDtor =
- reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
- CtorDtor();
- } else
- return AddrOrErr.takeError();
- } else {
- if (auto Err = CtorDtorSym.takeError())
- return Err;
- else
- return make_error<JITSymbolNotFound>(CtorDtorName);
- }
- }
- return Error::success();
- }
-
-private:
- std::vector<std::string> CtorDtorNames;
- orc::VModuleKey K;
-};
-
-template <typename JITLayerT>
-LegacyCtorDtorRunner<JITLayerT>::LegacyCtorDtorRunner(
- std::vector<std::string> CtorDtorNames, VModuleKey K)
- : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
-
class CtorDtorRunner {
public:
CtorDtorRunner(JITDylib &JD) : JD(JD) {}
@@ -250,45 +189,6 @@ protected:
void *DSOHandle);
};
-class LegacyLocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {
-public:
- /// Create a runtime-overrides class.
- template <typename MangleFtorT>
- LLVM_ATTRIBUTE_DEPRECATED(
- LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle),
- "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
- "Please use the ORCv2 LocalCXXRuntimeOverrides utility instead");
-
- template <typename MangleFtorT>
- LegacyLocalCXXRuntimeOverrides(ORCv1DeprecationAcknowledgement,
- const MangleFtorT &Mangle) {
- addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
- addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
- }
-
- /// Search overrided symbols.
- JITEvaluatedSymbol searchOverrides(const std::string &Name) {
- auto I = CXXRuntimeOverrides.find(Name);
- if (I != CXXRuntimeOverrides.end())
- return JITEvaluatedSymbol(I->second, JITSymbolFlags::Exported);
- return nullptr;
- }
-
-private:
- void addOverride(const std::string &Name, JITTargetAddress Addr) {
- CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
- }
-
- StringMap<JITTargetAddress> CXXRuntimeOverrides;
-};
-
-template <typename MangleFtorT>
-LegacyLocalCXXRuntimeOverrides::LegacyLocalCXXRuntimeOverrides(
- const MangleFtorT &Mangle) {
- addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
- addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
-}
-
class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {
public:
Error enable(JITDylib &JD, MangleAndInterner &Mangler);
@@ -315,7 +215,7 @@ private:
/// If an instance of this class is attached to a JITDylib as a fallback
/// definition generator, then any symbol found in the given DynamicLibrary that
/// passes the 'Allow' predicate will be added to the JITDylib.
-class DynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator {
+class DynamicLibrarySearchGenerator : public DefinitionGenerator {
public:
using SymbolPredicate = std::function<bool(const SymbolStringPtr &)>;
@@ -343,7 +243,7 @@ public:
return Load(nullptr, GlobalPrefix, std::move(Allow));
}
- Error tryToGenerate(LookupKind K, JITDylib &JD,
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags,
const SymbolLookupSet &Symbols) override;
@@ -358,7 +258,7 @@ private:
/// If an instance of this class is attached to a JITDylib as a fallback
/// definition generator, then any symbol found in the archive will result in
/// the containing object being added to the JITDylib.
-class StaticLibraryDefinitionGenerator : public JITDylib::DefinitionGenerator {
+class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
public:
/// Try to create a StaticLibraryDefinitionGenerator from the given path.
///
@@ -381,7 +281,7 @@ public:
static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer);
- Error tryToGenerate(LookupKind K, JITDylib &JD,
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags,
const SymbolLookupSet &Symbols) override;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h
deleted file mode 100644
index a4e43d4e1c9c..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h
+++ /dev/null
@@ -1,111 +0,0 @@
-//===- GlobalMappingLayer.h - Run all IR through a functor ------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Convenience layer for injecting symbols that will appear in calls to
-// findSymbol.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
-
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include <map>
-#include <memory>
-#include <string>
-
-namespace llvm {
-
-class Module;
-class JITSymbolResolver;
-
-namespace orc {
-
-/// Global mapping layer.
-///
-/// This layer overrides the findSymbol method to first search a local symbol
-/// table that the client can define. It can be used to inject new symbol
-/// mappings into the JIT. Beware, however: symbols within a single IR module or
-/// object file will still resolve locally (via RuntimeDyld's symbol table) -
-/// such internal references cannot be overriden via this layer.
-template <typename BaseLayerT>
-class GlobalMappingLayer {
-public:
-
- /// Handle to an added module.
- using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
-
- /// Construct an GlobalMappingLayer with the given BaseLayer
- GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
-
- /// Add the given module to the JIT.
- /// @return A handle for the added modules.
- Expected<ModuleHandleT>
- addModule(std::shared_ptr<Module> M,
- std::shared_ptr<JITSymbolResolver> Resolver) {
- return BaseLayer.addModule(std::move(M), std::move(Resolver));
- }
-
- /// Remove the module set associated with the handle H.
- Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
-
- /// Manually set the address to return for the given symbol.
- void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) {
- SymbolTable[Name] = Addr;
- }
-
- /// Remove the given symbol from the global mapping.
- void eraseGlobalMapping(const std::string &Name) {
- SymbolTable.erase(Name);
- }
-
- /// Search for the given named symbol.
- ///
- /// This method will first search the local symbol table, returning
- /// any symbol found there. If the symbol is not found in the local
- /// table then this call will be passed through to the base layer.
- ///
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it exists.
- JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
- auto I = SymbolTable.find(Name);
- if (I != SymbolTable.end())
- return JITSymbol(I->second, JITSymbolFlags::Exported);
- return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
- }
-
- /// Get the address of the given symbol in the context of the of the
- /// module represented by the handle H. This call is forwarded to the
- /// base layer's implementation.
- /// @param H The handle for the module to search in.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it is found in the
- /// given module.
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
- }
-
- /// Immediately emit and finalize the module set represented by the
- /// given handle.
- /// @param H Handle for module set to emit/finalize.
- Error emitAndFinalize(ModuleHandleT H) {
- return BaseLayer.emitAndFinalize(H);
- }
-
-private:
- BaseLayerT &BaseLayer;
- std::map<std::string, JITTargetAddress> SymbolTable;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index eb74d283f043..f8fdb171bbf9 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -45,8 +45,8 @@ public:
IRSymbolMapper::ManglingOptions MO;
};
- using NotifyCompiledFunction =
- std::function<void(VModuleKey K, ThreadSafeModule TSM)>;
+ using NotifyCompiledFunction = std::function<void(
+ MaterializationResponsibility &R, ThreadSafeModule TSM)>;
IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
std::unique_ptr<IRCompiler> Compile);
@@ -55,7 +55,8 @@ public:
void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled);
- void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
private:
mutable std::mutex IRLayerMutex;
@@ -65,99 +66,6 @@ private:
NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction();
};
-/// Eager IR compiling layer.
-///
-/// This layer immediately compiles each IR module added via addModule to an
-/// object file and adds this module file to the layer below, which must
-/// implement the object layer concept.
-template <typename BaseLayerT, typename CompileFtor>
-class LegacyIRCompileLayer {
-public:
- /// Callback type for notifications when modules are compiled.
- using NotifyCompiledCallback =
- std::function<void(VModuleKey K, std::unique_ptr<Module>)>;
-
- /// Construct an LegacyIRCompileLayer with the given BaseLayer, which must
- /// implement the ObjectLayer concept.
- LLVM_ATTRIBUTE_DEPRECATED(
- LegacyIRCompileLayer(
- BaseLayerT &BaseLayer, CompileFtor Compile,
- NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()),
- "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
- "use "
- "the ORCv2 IRCompileLayer instead");
-
- /// Legacy layer constructor with deprecation acknowledgement.
- LegacyIRCompileLayer(
- ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer,
- CompileFtor Compile,
- NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback())
- : BaseLayer(BaseLayer), Compile(std::move(Compile)),
- NotifyCompiled(std::move(NotifyCompiled)) {}
-
- /// Get a reference to the compiler functor.
- CompileFtor& getCompiler() { return Compile; }
-
- /// (Re)set the NotifyCompiled callback.
- void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) {
- this->NotifyCompiled = std::move(NotifyCompiled);
- }
-
- /// Compile the module, and add the resulting object to the base layer
- /// along with the given memory manager and symbol resolver.
- Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
- auto Obj = Compile(*M);
- if (!Obj)
- return Obj.takeError();
- if (auto Err = BaseLayer.addObject(std::move(K), std::move(*Obj)))
- return Err;
- if (NotifyCompiled)
- NotifyCompiled(std::move(K), std::move(M));
- return Error::success();
- }
-
- /// Remove the module associated with the VModuleKey K.
- Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); }
-
- /// Search for the given named symbol.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it exists.
- JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
- }
-
- /// Get the address of the given symbol in compiled module represented
- /// by the handle H. This call is forwarded to the base layer's
- /// implementation.
- /// @param K The VModuleKey for the module to search in.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it is found in the
- /// given module.
- JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
- }
-
- /// Immediately emit and finalize the module represented by the given
- /// handle.
- /// @param K The VModuleKey for the module to emit/finalize.
- Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
-
-private:
- BaseLayerT &BaseLayer;
- CompileFtor Compile;
- NotifyCompiledCallback NotifyCompiled;
-};
-
-template <typename BaseLayerT, typename CompileFtor>
-LegacyIRCompileLayer<BaseLayerT, CompileFtor>::LegacyIRCompileLayer(
- BaseLayerT &BaseLayer, CompileFtor Compile,
- NotifyCompiledCallback NotifyCompiled)
- : BaseLayer(BaseLayer), Compile(std::move(Compile)),
- NotifyCompiled(std::move(NotifyCompiled)) {}
-
} // end namespace orc
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
index 296d74ae6b86..66966a0f8762 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -13,6 +13,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
+#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
#include <memory>
@@ -27,7 +28,7 @@ namespace orc {
/// before operating on the module.
class IRTransformLayer : public IRLayer {
public:
- using TransformFunction = std::function<Expected<ThreadSafeModule>(
+ using TransformFunction = unique_function<Expected<ThreadSafeModule>(
ThreadSafeModule, MaterializationResponsibility &R)>;
IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer,
@@ -37,7 +38,8 @@ public:
this->Transform = std::move(Transform);
}
- void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
static ThreadSafeModule identityTransform(ThreadSafeModule TSM,
MaterializationResponsibility &R) {
@@ -49,80 +51,6 @@ private:
TransformFunction Transform;
};
-/// IR mutating layer.
-///
-/// This layer applies a user supplied transform to each module that is added,
-/// then adds the transformed module to the layer below.
-template <typename BaseLayerT, typename TransformFtor>
-class LegacyIRTransformLayer {
-public:
-
- /// Construct an LegacyIRTransformLayer with the given BaseLayer
- LLVM_ATTRIBUTE_DEPRECATED(
- LegacyIRTransformLayer(BaseLayerT &BaseLayer,
- TransformFtor Transform = TransformFtor()),
- "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
- "use "
- "the ORCv2 IRTransformLayer instead");
-
- /// Legacy layer constructor with deprecation acknowledgement.
- LegacyIRTransformLayer(ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer,
- TransformFtor Transform = TransformFtor())
- : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
-
- /// Apply the transform functor to the module, then add the module to
- /// the layer below, along with the memory manager and symbol resolver.
- ///
- /// @return A handle for the added modules.
- Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
- return BaseLayer.addModule(std::move(K), Transform(std::move(M)));
- }
-
- /// Remove the module associated with the VModuleKey K.
- Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); }
-
- /// Search for the given named symbol.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it exists.
- JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
- }
-
- /// Get the address of the given symbol in the context of the module
- /// represented by the VModuleKey K. This call is forwarded to the base
- /// layer's implementation.
- /// @param K The VModuleKey for the module to search in.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it is found in the
- /// given module.
- JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
- }
-
- /// Immediately emit and finalize the module represented by the given
- /// VModuleKey.
- /// @param K The VModuleKey for the module to emit/finalize.
- Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
-
- /// Access the transform functor directly.
- TransformFtor& getTransform() { return Transform; }
-
- /// Access the mumate functor directly.
- const TransformFtor& getTransform() const { return Transform; }
-
-private:
- BaseLayerT &BaseLayer;
- TransformFtor Transform;
-};
-
-template <typename BaseLayerT, typename TransformFtor>
-LegacyIRTransformLayer<BaseLayerT, TransformFtor>::LegacyIRTransformLayer(
- BaseLayerT &BaseLayer, TransformFtor Transform)
- : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
-
} // end namespace orc
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index e0cfd8bf2409..78e3ceef50e2 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -62,14 +62,33 @@ public:
JITTargetAddress TrampolineAddr,
NotifyLandingResolvedFunction OnLandingResolved) const>;
- virtual ~TrampolinePool() {}
+ virtual ~TrampolinePool();
/// Get an available trampoline address.
/// Returns an error if no trampoline can be created.
- virtual Expected<JITTargetAddress> getTrampoline() = 0;
+ Expected<JITTargetAddress> getTrampoline() {
+ std::lock_guard<std::mutex> Lock(TPMutex);
+ if (AvailableTrampolines.empty()) {
+ if (auto Err = grow())
+ return std::move(Err);
+ }
+ assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
+ auto TrampolineAddr = AvailableTrampolines.back();
+ AvailableTrampolines.pop_back();
+ return TrampolineAddr;
+ }
-private:
- virtual void anchor();
+ /// Returns the given trampoline to the pool for re-use.
+ void releaseTrampoline(JITTargetAddress TrampolineAddr) {
+ std::lock_guard<std::mutex> Lock(TPMutex);
+ AvailableTrampolines.push_back(TrampolineAddr);
+ }
+
+protected:
+ virtual Error grow() = 0;
+
+ std::mutex TPMutex;
+ std::vector<JITTargetAddress> AvailableTrampolines;
};
/// A trampoline pool for trampolines within the current process.
@@ -90,26 +109,6 @@ public:
return std::move(LTP);
}
- /// Get a free trampoline. Returns an error if one can not be provided (e.g.
- /// because the pool is empty and can not be grown).
- Expected<JITTargetAddress> getTrampoline() override {
- std::lock_guard<std::mutex> Lock(LTPMutex);
- if (AvailableTrampolines.empty()) {
- if (auto Err = grow())
- return std::move(Err);
- }
- assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
- auto TrampolineAddr = AvailableTrampolines.back();
- AvailableTrampolines.pop_back();
- return TrampolineAddr;
- }
-
- /// Returns the given trampoline to the pool for re-use.
- void releaseTrampoline(JITTargetAddress TrampolineAddr) {
- std::lock_guard<std::mutex> Lock(LTPMutex);
- AvailableTrampolines.push_back(TrampolineAddr);
- }
-
private:
static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {
LocalTrampolinePool<ORCABI> *TrampolinePool =
@@ -154,8 +153,8 @@ private:
}
}
- Error grow() {
- assert(this->AvailableTrampolines.empty() && "Growing prematurely?");
+ Error grow() override {
+ assert(AvailableTrampolines.empty() && "Growing prematurely?");
std::error_code EC;
auto TrampolineBlock =
@@ -175,7 +174,7 @@ private:
pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
for (unsigned I = 0; I < NumTrampolines; ++I)
- this->AvailableTrampolines.push_back(pointerToJITTargetAddress(
+ AvailableTrampolines.push_back(pointerToJITTargetAddress(
TrampolineMem + (I * ORCABI::TrampolineSize)));
if (auto EC = sys::Memory::protectMappedMemory(
@@ -189,10 +188,8 @@ private:
ResolveLandingFunction ResolveLanding;
- std::mutex LTPMutex;
sys::OwningMemoryBlock ResolverBlock;
std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
- std::vector<JITTargetAddress> AvailableTrampolines;
};
/// Target-independent base class for compile callback management.
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
index 96f8e169e7dc..ff0aa0238523 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -19,7 +19,6 @@
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
-#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ThreadPool.h"
@@ -29,6 +28,8 @@ namespace orc {
class LLJITBuilderState;
class LLLazyJITBuilderState;
+class ObjectTransformLayer;
+class TargetProcessControl;
/// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
///
@@ -85,21 +86,8 @@ public:
return ES->createJITDylib(std::move(Name));
}
- /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can
- /// be useful for succinctly defining absolute symbols, aliases and
- /// re-exports.
- template <typename MUType>
- Error define(std::unique_ptr<MUType> &&MU) {
- return Main->define(std::move(MU));
- }
-
- /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can
- /// be usedful for succinctly defining absolute symbols, aliases and
- /// re-exports.
- template <typename MUType>
- Error define(std::unique_ptr<MUType> &MU) {
- return Main->define(MU);
- }
+ /// Adds an IR module with the given ResourceTracker.
+ Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
/// Adds an IR module to the given JITDylib.
Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
@@ -110,6 +98,9 @@ public:
}
/// Adds an object file to the given JITDylib.
+ Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> Obj);
+
+ /// Adds an object file to the given JITDylib.
Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
/// Adds an object file to the given JITDylib.
@@ -178,7 +169,7 @@ public:
ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
/// Returns a reference to the object transform layer.
- ObjectTransformLayer &getObjTransformLayer() { return ObjTransformLayer; }
+ ObjectTransformLayer &getObjTransformLayer() { return *ObjTransformLayer; }
/// Returns a reference to the IR transform layer.
IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }
@@ -195,7 +186,7 @@ public:
}
protected:
- static std::unique_ptr<ObjectLayer>
+ static Expected<std::unique_ptr<ObjectLayer>>
createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
static Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
@@ -218,7 +209,7 @@ protected:
std::unique_ptr<ThreadPool> CompileThreads;
std::unique_ptr<ObjectLayer> ObjLinkingLayer;
- ObjectTransformLayer ObjTransformLayer;
+ std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
std::unique_ptr<IRCompileLayer> CompileLayer;
std::unique_ptr<IRTransformLayer> TransformLayer;
std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;
@@ -237,6 +228,9 @@ public:
CODLayer->setPartitionFunction(std::move(Partition));
}
+ /// Returns a reference to the on-demand layer.
+ CompileOnDemandLayer &getCompileOnDemandLayer() { return *CODLayer; }
+
/// Add a module to be lazily compiled to JITDylib JD.
Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
@@ -256,8 +250,9 @@ private:
class LLJITBuilderState {
public:
- using ObjectLinkingLayerCreator = std::function<std::unique_ptr<ObjectLayer>(
- ExecutionSession &, const Triple &TT)>;
+ using ObjectLinkingLayerCreator =
+ std::function<Expected<std::unique_ptr<ObjectLayer>>(ExecutionSession &,
+ const Triple &)>;
using CompileFunctionCreator =
std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
@@ -272,6 +267,7 @@ public:
CompileFunctionCreator CreateCompileFunction;
PlatformSetupFunction SetUpPlatform;
unsigned NumCompileThreads = 0;
+ TargetProcessControl *TPC = nullptr;
/// Called prior to JIT class construcion to fix up defaults.
Error prepareForConstruction();
@@ -354,6 +350,17 @@ public:
return impl();
}
+ /// Set a TargetProcessControl object.
+ ///
+ /// If the platform uses ObjectLinkingLayer by default and no
+ /// ObjectLinkingLayerCreator has been set then the TargetProcessControl
+ /// object will be used to supply the memory manager for the
+ /// ObjectLinkingLayer.
+ SetterImpl &setTargetProcessControl(TargetProcessControl &TPC) {
+ impl().TPC = &TPC;
+ return impl();
+ }
+
/// Create an instance of the JIT.
Expected<std::unique_ptr<JITType>> create() {
if (auto Err = impl().prepareForConstruction())
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
deleted file mode 100644
index b31914f12a0d..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===- LambdaResolverMM - Redirect symbol lookup via a functor --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines a RuntimeDyld::SymbolResolver subclass that uses a user-supplied
-// functor for symbol resolution.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
-#define LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/OrcV1Deprecation.h"
-#include <memory>
-
-namespace llvm {
-namespace orc {
-
-template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
-class LambdaResolver : public LegacyJITSymbolResolver {
-public:
- LLVM_ATTRIBUTE_DEPRECATED(
- LambdaResolver(DylibLookupFtorT DylibLookupFtor,
- ExternalLookupFtorT ExternalLookupFtor),
- "ORCv1 utilities (including resolvers) are deprecated and will be "
- "removed "
- "in the next release. Please use ORCv2 (see docs/ORCv2.rst)");
-
- LambdaResolver(ORCv1DeprecationAcknowledgement,
- DylibLookupFtorT DylibLookupFtor,
- ExternalLookupFtorT ExternalLookupFtor)
- : DylibLookupFtor(DylibLookupFtor),
- ExternalLookupFtor(ExternalLookupFtor) {}
-
- JITSymbol findSymbolInLogicalDylib(const std::string &Name) final {
- return DylibLookupFtor(Name);
- }
-
- JITSymbol findSymbol(const std::string &Name) final {
- return ExternalLookupFtor(Name);
- }
-
-private:
- DylibLookupFtorT DylibLookupFtor;
- ExternalLookupFtorT ExternalLookupFtor;
-};
-
-template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
-LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>::LambdaResolver(
- DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor)
- : DylibLookupFtor(DylibLookupFtor), ExternalLookupFtor(ExternalLookupFtor) {
-}
-
-template <typename DylibLookupFtorT,
- typename ExternalLookupFtorT>
-std::shared_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>>
-createLambdaResolver(DylibLookupFtorT DylibLookupFtor,
- ExternalLookupFtorT ExternalLookupFtor) {
- using LR = LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>;
- return std::make_unique<LR>(std::move(DylibLookupFtor),
- std::move(ExternalLookupFtor));
-}
-
-template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
-std::shared_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>>
-createLambdaResolver(ORCv1DeprecationAcknowledgement,
- DylibLookupFtorT DylibLookupFtor,
- ExternalLookupFtorT ExternalLookupFtor) {
- using LR = LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>;
- return std::make_unique<LR>(AcknowledgeORCv1Deprecation,
- std::move(DylibLookupFtor),
- std::move(ExternalLookupFtor));
-}
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
index e843d0f56245..f9cc15583b42 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
@@ -34,15 +34,15 @@ public:
/// SymbolFlags and SymbolToDefinition maps.
IRMaterializationUnit(ExecutionSession &ES,
const IRSymbolMapper::ManglingOptions &MO,
- ThreadSafeModule TSM, VModuleKey K);
+ ThreadSafeModule TSM);
/// Create an IRMaterializationLayer from a module, and pre-existing
/// SymbolFlags and SymbolToDefinition maps. The maps must provide
/// entries for each definition in M.
/// This constructor is useful for delegating work from one
/// IRMaterializationUnit to another.
- IRMaterializationUnit(ThreadSafeModule TSM, VModuleKey K,
- SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol,
+ IRMaterializationUnit(ThreadSafeModule TSM, SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol,
SymbolNameToDefinitionMap SymbolToDefinition);
/// Return the ModuleIdentifier as the name for this MaterializationUnit.
@@ -94,13 +94,19 @@ public:
/// Returns the current value of the CloneToNewContextOnEmit flag.
bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
+ /// Add a MaterializatinoUnit representing the given IR to the JITDylib
+ /// targeted by the given tracker.
+ virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM);
+
/// Adds a MaterializationUnit representing the given IR to the given
- /// JITDylib.
- virtual Error add(JITDylib &JD, ThreadSafeModule TSM,
- VModuleKey K = VModuleKey());
+ /// JITDylib. If RT is not specif
+ Error add(JITDylib &JD, ThreadSafeModule TSM) {
+ return add(JD.getDefaultResourceTracker(), std::move(TSM));
+ }
/// Emit should materialize the given IR.
- virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0;
+ virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) = 0;
private:
bool CloneToNewContextOnEmit = false;
@@ -114,14 +120,12 @@ class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
public:
BasicIRLayerMaterializationUnit(IRLayer &L,
const IRSymbolMapper::ManglingOptions &MO,
- ThreadSafeModule TSM, VModuleKey K);
+ ThreadSafeModule TSM);
private:
-
- void materialize(MaterializationResponsibility R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
IRLayer &L;
- VModuleKey K;
};
/// Interface for Layers that accept object files.
@@ -135,11 +139,14 @@ public:
/// Adds a MaterializationUnit representing the given IR to the given
/// JITDylib.
- virtual Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
- VModuleKey K = VModuleKey());
+ virtual Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O);
+
+ Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {
+ return add(JD.getDefaultResourceTracker(), std::move(O));
+ }
/// Emit should materialize the given IR.
- virtual void emit(MaterializationResponsibility R,
+ virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) = 0;
private:
@@ -151,9 +158,9 @@ private:
class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
public:
static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
- Create(ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O);
+ Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> O);
- BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K,
+ BasicObjectLayerMaterializationUnit(ObjectLayer &L,
std::unique_ptr<MemoryBuffer> O,
SymbolFlagsMap SymbolFlags,
SymbolStringPtr InitSymbol);
@@ -162,8 +169,7 @@ public:
StringRef getName() const override;
private:
-
- void materialize(MaterializationResponsibility R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
ObjectLayer &L;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
deleted file mode 100644
index 84f5e0350c2e..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ /dev/null
@@ -1,267 +0,0 @@
-//===- LazyEmittingLayer.h - Lazily emit IR to lower JIT layers -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Contains the definition for a lazy-emitting layer for the JIT.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/Orc/Core.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/Mangler.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <list>
-#include <memory>
-#include <string>
-
-namespace llvm {
-namespace orc {
-
-/// Lazy-emitting IR layer.
-///
-/// This layer accepts LLVM IR Modules (via addModule) but does not
-/// immediately emit them the layer below. Instead, emission to the base layer
-/// is deferred until the first time the client requests the address (via
-/// JITSymbol::getAddress) for a symbol contained in this layer.
-template <typename BaseLayerT> class LazyEmittingLayer {
-private:
- class EmissionDeferredModule {
- public:
- EmissionDeferredModule(VModuleKey K, std::unique_ptr<Module> M)
- : K(std::move(K)), M(std::move(M)) {}
-
- JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
- switch (EmitState) {
- case NotEmitted:
- if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
- JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV);
- auto GetAddress = [this, ExportedSymbolsOnly, Name = Name.str(),
- &B]() -> Expected<JITTargetAddress> {
- if (this->EmitState == Emitting)
- return 0;
- else if (this->EmitState == NotEmitted) {
- this->EmitState = Emitting;
- if (auto Err = this->emitToBaseLayer(B))
- return std::move(Err);
- this->EmitState = Emitted;
- }
- if (auto Sym = B.findSymbolIn(K, Name, ExportedSymbolsOnly))
- return Sym.getAddress();
- else if (auto Err = Sym.takeError())
- return std::move(Err);
- else
- llvm_unreachable("Successful symbol lookup should return "
- "definition address here");
- };
- return JITSymbol(std::move(GetAddress), Flags);
- } else
- return nullptr;
- case Emitting:
- // Calling "emit" can trigger a recursive call to 'find' (e.g. to check
- // for pre-existing definitions of common-symbol), but any symbol in
- // this module would already have been found internally (in the
- // RuntimeDyld that did the lookup), so just return a nullptr here.
- return nullptr;
- case Emitted:
- return B.findSymbolIn(K, std::string(Name), ExportedSymbolsOnly);
- }
- llvm_unreachable("Invalid emit-state.");
- }
-
- Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) {
- return EmitState != NotEmitted ? BaseLayer.removeModule(K)
- : Error::success();
- }
-
- void emitAndFinalize(BaseLayerT &BaseLayer) {
- assert(EmitState != Emitting &&
- "Cannot emitAndFinalize while already emitting");
- if (EmitState == NotEmitted) {
- EmitState = Emitting;
- emitToBaseLayer(BaseLayer);
- EmitState = Emitted;
- }
- BaseLayer.emitAndFinalize(K);
- }
-
- private:
-
- const GlobalValue* searchGVs(StringRef Name,
- bool ExportedSymbolsOnly) const {
- // FIXME: We could clean all this up if we had a way to reliably demangle
- // names: We could just demangle name and search, rather than
- // mangling everything else.
-
- // If we have already built the mangled name set then just search it.
- if (MangledSymbols) {
- auto VI = MangledSymbols->find(Name);
- if (VI == MangledSymbols->end())
- return nullptr;
- auto GV = VI->second;
- if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
- return GV;
- return nullptr;
- }
-
- // If we haven't built the mangled name set yet, try to build it. As an
- // optimization this will leave MangledNames set to nullptr if we find
- // Name in the process of building the set.
- return buildMangledSymbols(Name, ExportedSymbolsOnly);
- }
-
- Error emitToBaseLayer(BaseLayerT &BaseLayer) {
- // We don't need the mangled names set any more: Once we've emitted this
- // to the base layer we'll just look for symbols there.
- MangledSymbols.reset();
- return BaseLayer.addModule(std::move(K), std::move(M));
- }
-
- // If the mangled name of the given GlobalValue matches the given search
- // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
- // return the symbol. Otherwise, add the mangled name to the Names map and
- // return nullptr.
- const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
- const GlobalValue &GV,
- const Mangler &Mang, StringRef SearchName,
- bool ExportedSymbolsOnly) const {
- // Modules don't "provide" decls or common symbols.
- if (GV.isDeclaration() || GV.hasCommonLinkage())
- return nullptr;
-
- // Mangle the GV name.
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mang.getNameWithPrefix(MangledNameStream, &GV, false);
- }
-
- // Check whether this is the name we were searching for, and if it is then
- // bail out early.
- if (MangledName == SearchName)
- if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
- return &GV;
-
- // Otherwise add this to the map for later.
- Names[MangledName] = &GV;
- return nullptr;
- }
-
- // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
- // to nullptr) if the given SearchName is found while building the map.
- const GlobalValue* buildMangledSymbols(StringRef SearchName,
- bool ExportedSymbolsOnly) const {
- assert(!MangledSymbols && "Mangled symbols map already exists?");
-
- auto Symbols = std::make_unique<StringMap<const GlobalValue*>>();
-
- Mangler Mang;
-
- for (const auto &GO : M->global_objects())
- if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName,
- ExportedSymbolsOnly))
- return GV;
-
- MangledSymbols = std::move(Symbols);
- return nullptr;
- }
-
- enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
- VModuleKey K;
- std::unique_ptr<Module> M;
- mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
- };
-
- BaseLayerT &BaseLayer;
- std::map<VModuleKey, std::unique_ptr<EmissionDeferredModule>> ModuleMap;
-
-public:
-
- /// Construct a lazy emitting layer.
- LLVM_ATTRIBUTE_DEPRECATED(
- LazyEmittingLayer(BaseLayerT &BaseLayer),
- "ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use "
- "ORCv2, where lazy emission is the default");
-
- /// Construct a lazy emitting layer.
- LazyEmittingLayer(ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer)
- : BaseLayer(BaseLayer) {}
-
- /// Add the given module to the lazy emitting layer.
- Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
- assert(!ModuleMap.count(K) && "VModuleKey K already in use");
- ModuleMap[K] =
- std::make_unique<EmissionDeferredModule>(std::move(K), std::move(M));
- return Error::success();
- }
-
- /// Remove the module represented by the given handle.
- ///
- /// This method will free the memory associated with the given module, both
- /// in this layer, and the base layer.
- Error removeModule(VModuleKey K) {
- auto I = ModuleMap.find(K);
- assert(I != ModuleMap.end() && "VModuleKey K not valid here");
- auto EDM = std::move(I.second);
- ModuleMap.erase(I);
- return EDM->removeModuleFromBaseLayer(BaseLayer);
- }
-
- /// Search for the given named symbol.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it exists.
- JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
- // Look for the symbol among existing definitions.
- if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
- return Symbol;
-
- // If not found then search the deferred modules. If any of these contain a
- // definition of 'Name' then they will return a JITSymbol that will emit
- // the corresponding module when the symbol address is requested.
- for (auto &KV : ModuleMap)
- if (auto Symbol = KV.second->find(Name, ExportedSymbolsOnly, BaseLayer))
- return Symbol;
-
- // If no definition found anywhere return a null symbol.
- return nullptr;
- }
-
- /// Get the address of the given symbol in the context of the of
- /// compiled modules represented by the key K.
- JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
- bool ExportedSymbolsOnly) {
- assert(ModuleMap.count(K) && "VModuleKey K not valid here");
- return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer);
- }
-
- /// Immediately emit and finalize the module represented by the given
- /// key.
- Error emitAndFinalize(VModuleKey K) {
- assert(ModuleMap.count(K) && "VModuleKey K not valid here");
- return ModuleMap[K]->emitAndFinalize(BaseLayer);
- }
-};
-
-template <typename BaseLayerT>
-LazyEmittingLayer<BaseLayerT>::LazyEmittingLayer(BaseLayerT &BaseLayer)
- : BaseLayer(BaseLayer) {}
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
index 0d3ccecdf121..e6a9d8945285 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
@@ -40,6 +40,9 @@ public:
using NotifyResolvedFunction =
unique_function<Error(JITTargetAddress ResolvedAddr)>;
+ LazyCallThroughManager(ExecutionSession &ES,
+ JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP);
+
// Return a free call-through trampoline and bind it to look up and call
// through to the given symbol.
Expected<JITTargetAddress>
@@ -56,9 +59,6 @@ protected:
using NotifyLandingResolvedFunction =
TrampolinePool::NotifyLandingResolvedFunction;
- LazyCallThroughManager(ExecutionSession &ES,
- JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP);
-
struct ReexportsEntry {
JITDylib *SourceJD;
SymbolStringPtr SymbolName;
@@ -144,12 +144,12 @@ public:
IndirectStubsManager &ISManager,
JITDylib &SourceJD,
SymbolAliasMap CallableAliases,
- ImplSymbolMap *SrcJDLoc, VModuleKey K);
+ ImplSymbolMap *SrcJDLoc);
StringRef getName() const override;
private:
- void materialize(MaterializationResponsibility R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
@@ -166,11 +166,10 @@ private:
inline std::unique_ptr<LazyReexportsMaterializationUnit>
lazyReexports(LazyCallThroughManager &LCTManager,
IndirectStubsManager &ISManager, JITDylib &SourceJD,
- SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc = nullptr,
- VModuleKey K = VModuleKey()) {
+ SymbolAliasMap CallableAliases,
+ ImplSymbolMap *SrcJDLoc = nullptr) {
return std::make_unique<LazyReexportsMaterializationUnit>(
- LCTManager, ISManager, SourceJD, std::move(CallableAliases), SrcJDLoc,
- std::move(K));
+ LCTManager, ISManager, SourceJD, std::move(CallableAliases), SrcJDLoc);
}
} // End namespace orc
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h
deleted file mode 100644
index b20202a49ef6..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h
+++ /dev/null
@@ -1,211 +0,0 @@
-//===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Contains core ORC APIs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LEGACY_H
-#define LLVM_EXECUTIONENGINE_ORC_LEGACY_H
-
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/Orc/Core.h"
-
-namespace llvm {
-namespace orc {
-
-/// SymbolResolver is a composable interface for looking up symbol flags
-/// and addresses using the AsynchronousSymbolQuery type. It will
-/// eventually replace the LegacyJITSymbolResolver interface as the
-/// stardard ORC symbol resolver type.
-///
-/// FIXME: SymbolResolvers should go away and be replaced with VSOs with
-/// defenition generators.
-class SymbolResolver {
-public:
- virtual ~SymbolResolver() = default;
-
- /// Returns the subset of the given symbols that the caller is responsible for
- /// materializing.
- virtual SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) = 0;
-
- /// For each symbol in Symbols that can be found, assigns that symbols
- /// value in Query. Returns the set of symbols that could not be found.
- virtual SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
- SymbolNameSet Symbols) = 0;
-
-private:
- virtual void anchor();
-};
-
-/// Implements SymbolResolver with a pair of supplied function objects
-/// for convenience. See createSymbolResolver.
-template <typename GetResponsibilitySetFn, typename LookupFn>
-class LambdaSymbolResolver final : public SymbolResolver {
-public:
- template <typename GetResponsibilitySetFnRef, typename LookupFnRef>
- LambdaSymbolResolver(GetResponsibilitySetFnRef &&GetResponsibilitySet,
- LookupFnRef &&Lookup)
- : GetResponsibilitySet(
- std::forward<GetResponsibilitySetFnRef>(GetResponsibilitySet)),
- Lookup(std::forward<LookupFnRef>(Lookup)) {}
-
- SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
- return GetResponsibilitySet(Symbols);
- }
-
- SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
- SymbolNameSet Symbols) final {
- return Lookup(std::move(Query), std::move(Symbols));
- }
-
-private:
- GetResponsibilitySetFn GetResponsibilitySet;
- LookupFn Lookup;
-};
-
-/// Creates a SymbolResolver implementation from the pair of supplied
-/// function objects.
-template <typename GetResponsibilitySetFn, typename LookupFn>
-std::unique_ptr<LambdaSymbolResolver<
- std::remove_cv_t<std::remove_reference_t<GetResponsibilitySetFn>>,
- std::remove_cv_t<std::remove_reference_t<LookupFn>>>>
-createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet,
- LookupFn &&Lookup) {
- using LambdaSymbolResolverImpl = LambdaSymbolResolver<
- std::remove_cv_t<std::remove_reference_t<GetResponsibilitySetFn>>,
- std::remove_cv_t<std::remove_reference_t<LookupFn>>>;
- return std::make_unique<LambdaSymbolResolverImpl>(
- std::forward<GetResponsibilitySetFn>(GetResponsibilitySet),
- std::forward<LookupFn>(Lookup));
-}
-
-/// Legacy adapter. Remove once we kill off the old ORC layers.
-class JITSymbolResolverAdapter : public JITSymbolResolver {
-public:
- JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R,
- MaterializationResponsibility *MR);
- Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) override;
- void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) override;
-
-private:
- ExecutionSession &ES;
- std::set<SymbolStringPtr> ResolvedStrings;
- SymbolResolver &R;
- MaterializationResponsibility *MR;
-};
-
-/// Use the given legacy-style FindSymbol function (i.e. a function that takes
-/// a const std::string& or StringRef and returns a JITSymbol) to get the
-/// subset of symbols that the caller is responsible for materializing. If any
-/// JITSymbol returned by FindSymbol is in an error state the function returns
-/// immediately with that error.
-///
-/// Useful for implementing getResponsibilitySet bodies that query legacy
-/// resolvers.
-template <typename FindSymbolFn>
-Expected<SymbolNameSet>
-getResponsibilitySetWithLegacyFn(const SymbolNameSet &Symbols,
- FindSymbolFn FindSymbol) {
- SymbolNameSet Result;
-
- for (auto &S : Symbols) {
- if (JITSymbol Sym = FindSymbol(*S)) {
- if (!Sym.getFlags().isStrong())
- Result.insert(S);
- } else if (auto Err = Sym.takeError())
- return std::move(Err);
- }
-
- return Result;
-}
-
-/// Use the given legacy-style FindSymbol function (i.e. a function that
-/// takes a const std::string& or StringRef and returns a JITSymbol) to
-/// find the address and flags for each symbol in Symbols and store the
-/// result in Query. If any JITSymbol returned by FindSymbol is in an
-/// error then Query.notifyFailed(...) is called with that error and the
-/// function returns immediately. On success, returns the set of symbols
-/// not found.
-///
-/// Useful for implementing lookup bodies that query legacy resolvers.
-template <typename FindSymbolFn>
-SymbolNameSet
-lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query,
- const SymbolNameSet &Symbols, FindSymbolFn FindSymbol) {
- SymbolNameSet SymbolsNotFound;
- bool NewSymbolsResolved = false;
-
- for (auto &S : Symbols) {
- if (JITSymbol Sym = FindSymbol(*S)) {
- if (auto Addr = Sym.getAddress()) {
- Query.notifySymbolMetRequiredState(
- S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
- NewSymbolsResolved = true;
- } else {
- ES.legacyFailQuery(Query, Addr.takeError());
- return SymbolNameSet();
- }
- } else if (auto Err = Sym.takeError()) {
- ES.legacyFailQuery(Query, std::move(Err));
- return SymbolNameSet();
- } else
- SymbolsNotFound.insert(S);
- }
-
- if (NewSymbolsResolved && Query.isComplete())
- Query.handleComplete();
-
- return SymbolsNotFound;
-}
-
-/// An ORC SymbolResolver implementation that uses a legacy
-/// findSymbol-like function to perform lookup;
-template <typename LegacyLookupFn>
-class LegacyLookupFnResolver final : public SymbolResolver {
-public:
- using ErrorReporter = std::function<void(Error)>;
-
- LegacyLookupFnResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup,
- ErrorReporter ReportError)
- : ES(ES), LegacyLookup(std::move(LegacyLookup)),
- ReportError(std::move(ReportError)) {}
-
- SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
- if (auto ResponsibilitySet =
- getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup))
- return std::move(*ResponsibilitySet);
- else {
- ReportError(ResponsibilitySet.takeError());
- return SymbolNameSet();
- }
- }
-
- SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
- SymbolNameSet Symbols) final {
- return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
- }
-
-private:
- ExecutionSession &ES;
- LegacyLookupFn LegacyLookup;
- ErrorReporter ReportError;
-};
-
-template <typename LegacyLookupFn>
-std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>>
-createLegacyLookupResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup,
- std::function<void(Error)> ErrorReporter) {
- return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>(
- ES, std::move(LegacyLookup), std::move(ErrorReporter));
-}
-
-} // End namespace orc
-} // End namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LEGACY_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
index 15fe079eccaf..90e1d4704f34 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
@@ -98,8 +98,9 @@ public:
ExecutionSession &getExecutionSession() const { return ES; }
Error setupJITDylib(JITDylib &JD) override;
- Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) override;
- Error notifyRemoving(JITDylib &JD, VModuleKey K) override;
+ Error notifyAdding(ResourceTracker &RT,
+ const MaterializationUnit &MU) override;
+ Error notifyRemoving(ResourceTracker &RT) override;
Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
@@ -119,6 +120,19 @@ private:
LocalDependenciesMap getSyntheticSymbolLocalDependencies(
MaterializationResponsibility &MR) override;
+ // FIXME: We should be tentatively tracking scraped sections and discarding
+ // if the MR fails.
+ Error notifyFailed(MaterializationResponsibility &MR) override {
+ return Error::success();
+ }
+
+ Error notifyRemovingResources(ResourceKey K) override {
+ return Error::success();
+ }
+
+ void notifyTransferringResources(ResourceKey DstKey,
+ ResourceKey SrcKey) override {}
+
private:
using InitSymbolDepMap =
DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
@@ -136,8 +150,6 @@ private:
InitSymbolDepMap InitSymbolDeps;
};
- static std::vector<JITDylib *> getDFSLinkOrder(JITDylib &JD);
-
void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
MachOJITDylibInitializers::SectionExtent ModInits,
MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h
deleted file mode 100644
index ffa37a13d064..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===------ NullResolver.h - Reject symbol lookup requests ------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines a RuntimeDyld::SymbolResolver subclass that rejects all symbol
-// resolution requests, for clients that have no cross-object fixups.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
-#define LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
-
-#include "llvm/ExecutionEngine/Orc/Legacy.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
-
-namespace llvm {
-namespace orc {
-
-class NullResolver : public SymbolResolver {
-public:
- SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final;
-
- SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
- SymbolNameSet Symbols) final;
-};
-
-/// SymbolResolver impliementation that rejects all resolution requests.
-/// Useful for clients that have no cross-object fixups.
-class NullLegacyResolver : public LegacyJITSymbolResolver {
-public:
- JITSymbol findSymbol(const std::string &Name) final;
-
- JITSymbol findSymbolInLogicalDylib(const std::string &Name) final;
-};
-
-} // End namespace orc.
-} // End namespace llvm.
-
-#endif // LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index 2bfe3b001709..f2975e29fcd6 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -35,6 +35,7 @@ namespace llvm {
namespace jitlink {
class EHFrameRegistrar;
+class LinkGraph;
class Symbol;
} // namespace jitlink
@@ -51,7 +52,7 @@ class ObjectLinkingLayerJITLinkContext;
/// Clients can use this class to add relocatable object files to an
/// ExecutionSession, and it typically serves as the base layer (underneath
/// a compiling layer like IRCompileLayer) for the rest of the JIT.
-class ObjectLinkingLayer : public ObjectLayer {
+class ObjectLinkingLayer : public ObjectLayer, private ResourceManager {
friend class ObjectLinkingLayerJITLinkContext;
public:
@@ -72,10 +73,10 @@ public:
virtual Error notifyEmitted(MaterializationResponsibility &MR) {
return Error::success();
}
- virtual Error notifyRemovingModule(VModuleKey K) {
- return Error::success();
- }
- virtual Error notifyRemovingAllModules() { return Error::success(); }
+ virtual Error notifyFailed(MaterializationResponsibility &MR) = 0;
+ virtual Error notifyRemovingResources(ResourceKey K) = 0;
+ virtual void notifyTransferringResources(ResourceKey DstKey,
+ ResourceKey SrcKey) = 0;
/// Return any dependencies that synthetic symbols (e.g. init symbols)
/// have on locally scoped jitlink::Symbols. This is used by the
@@ -90,8 +91,14 @@ public:
using ReturnObjectBufferFunction =
std::function<void(std::unique_ptr<MemoryBuffer>)>;
- /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
- /// and NotifyEmitted functors.
+ /// Construct an ObjectLinkingLayer.
+ ObjectLinkingLayer(ExecutionSession &ES,
+ jitlink::JITLinkMemoryManager &MemMgr);
+
+ /// Construct an ObjectLinkingLayer. Takes ownership of the given
+ /// JITLinkMemoryManager. This method is a temporary hack to simplify
+ /// co-existence with RTDyldObjectLinkingLayer (which also owns its
+ /// allocators).
ObjectLinkingLayer(ExecutionSession &ES,
std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
@@ -112,10 +119,14 @@ public:
return *this;
}
- /// Emit the object.
- void emit(MaterializationResponsibility R,
+ /// Emit an object file.
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
+ /// Emit a LinkGraph.
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ std::unique_ptr<jitlink::LinkGraph> G);
+
/// Instructs this ObjectLinkingLayer instance to override the symbol flags
/// found in the AtomGraph with the flags supplied by the
/// MaterializationResponsibility instance. This is a workaround to support
@@ -155,27 +166,31 @@ private:
void notifyLoaded(MaterializationResponsibility &MR);
Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
- Error removeModule(VModuleKey K);
- Error removeAllModules();
+ Error handleRemoveResources(ResourceKey K) override;
+ void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
mutable std::mutex LayerMutex;
- std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr;
+ jitlink::JITLinkMemoryManager &MemMgr;
+ std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgrOwnership;
bool OverrideObjectFlags = false;
bool AutoClaimObjectSymbols = false;
ReturnObjectBufferFunction ReturnObjectBuffer;
- DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
- std::vector<AllocPtr> UntrackedAllocs;
+ DenseMap<ResourceKey, std::vector<AllocPtr>> Allocs;
std::vector<std::unique_ptr<Plugin>> Plugins;
};
class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
public:
- EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
- Error notifyEmitted(MaterializationResponsibility &MR) override;
+ EHFrameRegistrationPlugin(
+ ExecutionSession &ES,
+ std::unique_ptr<jitlink::EHFrameRegistrar> Registrar);
void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
jitlink::PassConfiguration &PassConfig) override;
- Error notifyRemovingModule(VModuleKey K) override;
- Error notifyRemovingAllModules() override;
+ Error notifyEmitted(MaterializationResponsibility &MR) override;
+ Error notifyFailed(MaterializationResponsibility &MR) override;
+ Error notifyRemovingResources(ResourceKey K) override;
+ void notifyTransferringResources(ResourceKey DstKey,
+ ResourceKey SrcKey) override;
private:
@@ -185,10 +200,10 @@ private:
};
std::mutex EHFramePluginMutex;
- jitlink::EHFrameRegistrar &Registrar;
+ ExecutionSession &ES;
+ std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
- DenseMap<VModuleKey, EHFrameRange> TrackedEHFrameRanges;
- std::vector<EHFrameRange> UntrackedEHFrameRanges;
+ DenseMap<ResourceKey, std::vector<EHFrameRange>> EHFrameRanges;
};
} // end namespace orc
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
index bf989cc8677c..d8395ab34e47 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
@@ -31,7 +31,7 @@ public:
ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
TransformFunction Transform = TransformFunction());
- void emit(MaterializationResponsibility R,
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
void setTransform(TransformFunction Transform) {
@@ -43,88 +43,6 @@ private:
TransformFunction Transform;
};
-/// Object mutating layer.
-///
-/// This layer accepts sets of ObjectFiles (via addObject). It
-/// immediately applies the user supplied functor to each object, then adds
-/// the set of transformed objects to the layer below.
-template <typename BaseLayerT, typename TransformFtor>
-class LegacyObjectTransformLayer {
-public:
- /// Construct an ObjectTransformLayer with the given BaseLayer
- LLVM_ATTRIBUTE_DEPRECATED(
- LegacyObjectTransformLayer(BaseLayerT &BaseLayer,
- TransformFtor Transform = TransformFtor()),
- "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
- "use "
- "the ORCv2 ObjectTransformLayer instead");
-
- /// Legacy layer constructor with deprecation acknowledgement.
- LegacyObjectTransformLayer(ORCv1DeprecationAcknowledgement,
- BaseLayerT &BaseLayer,
- TransformFtor Transform = TransformFtor())
- : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
-
- /// Apply the transform functor to each object in the object set, then
- /// add the resulting set of objects to the base layer, along with the
- /// memory manager and symbol resolver.
- ///
- /// @return A handle for the added objects.
- template <typename ObjectPtr> Error addObject(VModuleKey K, ObjectPtr Obj) {
- return BaseLayer.addObject(std::move(K), Transform(std::move(Obj)));
- }
-
- /// Remove the object set associated with the VModuleKey K.
- Error removeObject(VModuleKey K) { return BaseLayer.removeObject(K); }
-
- /// Search for the given named symbol.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it exists.
- JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
- }
-
- /// Get the address of the given symbol in the context of the set of
- /// objects represented by the VModuleKey K. This call is forwarded to
- /// the base layer's implementation.
- /// @param K The VModuleKey associated with the object set to search in.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it is found in the
- /// given object set.
- JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
- }
-
- /// Immediately emit and finalize the object set represented by the
- /// given VModuleKey K.
- Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
-
- /// Map section addresses for the objects associated with the
- /// VModuleKey K.
- void mapSectionAddress(VModuleKey K, const void *LocalAddress,
- JITTargetAddress TargetAddr) {
- BaseLayer.mapSectionAddress(K, LocalAddress, TargetAddr);
- }
-
- /// Access the transform functor directly.
- TransformFtor &getTransform() { return Transform; }
-
- /// Access the mumate functor directly.
- const TransformFtor &getTransform() const { return Transform; }
-
-private:
- BaseLayerT &BaseLayer;
- TransformFtor Transform;
-};
-
-template <typename BaseLayerT, typename TransformFtor>
-LegacyObjectTransformLayer<BaseLayerT, TransformFtor>::
- LegacyObjectTransformLayer(BaseLayerT &BaseLayer, TransformFtor Transform)
- : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
-
} // end namespace orc
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h
new file mode 100644
index 000000000000..a8aa42799115
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h
@@ -0,0 +1,415 @@
+//===--- OrcRPCTargetProcessControl.h - Remote target control ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for interacting with target processes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
+#define LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+namespace llvm {
+namespace orc {
+
+/// JITLinkMemoryManager implementation for a process connected via an ORC RPC
+/// endpoint.
+template <typename OrcRPCTPCImplT>
+class OrcRPCTPCJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
+private:
+ struct HostAlloc {
+ std::unique_ptr<char[]> Mem;
+ uint64_t Size;
+ };
+
+ struct TargetAlloc {
+ JITTargetAddress Address = 0;
+ uint64_t AllocatedSize = 0;
+ };
+
+ using HostAllocMap = DenseMap<int, HostAlloc>;
+ using TargetAllocMap = DenseMap<int, TargetAlloc>;
+
+public:
+ class OrcRPCAllocation : public Allocation {
+ public:
+ OrcRPCAllocation(OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent,
+ HostAllocMap HostAllocs, TargetAllocMap TargetAllocs)
+ : Parent(Parent), HostAllocs(std::move(HostAllocs)),
+ TargetAllocs(std::move(TargetAllocs)) {
+ assert(HostAllocs.size() == TargetAllocs.size() &&
+ "HostAllocs size should match TargetAllocs");
+ }
+
+ ~OrcRPCAllocation() override {
+ assert(TargetAllocs.empty() && "failed to deallocate");
+ }
+
+ MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
+ auto I = HostAllocs.find(Seg);
+ assert(I != HostAllocs.end() && "No host allocation for segment");
+ auto &HA = I->second;
+ return {HA.Mem.get(), static_cast<size_t>(HA.Size)};
+ }
+
+ JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
+ auto I = TargetAllocs.find(Seg);
+ assert(I != TargetAllocs.end() && "No target allocation for segment");
+ return I->second.Address;
+ }
+
+ void finalizeAsync(FinalizeContinuation OnFinalize) override {
+
+ std::vector<tpctypes::BufferWrite> BufferWrites;
+ orcrpctpc::ReleaseOrFinalizeMemRequest FMR;
+
+ for (auto &KV : HostAllocs) {
+ assert(TargetAllocs.count(KV.first) &&
+ "No target allocation for buffer");
+ auto &HA = KV.second;
+ auto &TA = TargetAllocs[KV.first];
+ BufferWrites.push_back({TA.Address, StringRef(HA.Mem.get(), HA.Size)});
+ FMR.push_back({orcrpctpc::toWireProtectionFlags(
+ static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+ TA.Address, TA.AllocatedSize});
+ }
+
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "finalizeAsync " << (void *)this << ":\n";
+ auto FMRI = FMR.begin();
+ for (auto &B : BufferWrites) {
+ auto Prot = FMRI->Prot;
+ ++FMRI;
+ dbgs() << " Writing " << formatv("{0:x16}", B.Buffer.size())
+ << " bytes to " << ((Prot & orcrpctpc::WPF_Read) ? 'R' : '-')
+ << ((Prot & orcrpctpc::WPF_Write) ? 'W' : '-')
+ << ((Prot & orcrpctpc::WPF_Exec) ? 'X' : '-')
+ << " segment: local " << (const void *)B.Buffer.data()
+ << " -> target " << formatv("{0:x16}", B.Address) << "\n";
+ }
+ });
+ if (auto Err =
+ Parent.Parent.getMemoryAccess().writeBuffers(BufferWrites)) {
+ OnFinalize(std::move(Err));
+ return;
+ }
+
+ DEBUG_WITH_TYPE("orc", dbgs() << " Applying permissions...\n");
+ if (auto Err =
+ Parent.getEndpoint().template callAsync<orcrpctpc::FinalizeMem>(
+ [OF = std::move(OnFinalize)](Error Err2) {
+ // FIXME: Dispatch to work queue.
+ std::thread([OF = std::move(OF),
+ Err3 = std::move(Err2)]() mutable {
+ DEBUG_WITH_TYPE(
+ "orc", { dbgs() << " finalizeAsync complete\n"; });
+ OF(std::move(Err3));
+ }).detach();
+ return Error::success();
+ },
+ FMR)) {
+ DEBUG_WITH_TYPE("orc", dbgs() << " failed.\n");
+ Parent.getEndpoint().abandonPendingResponses();
+ Parent.reportError(std::move(Err));
+ }
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Leaving finalizeAsync (finalization may continue in "
+ "background)\n";
+ });
+ }
+
+ Error deallocate() override {
+ orcrpctpc::ReleaseOrFinalizeMemRequest RMR;
+ for (auto &KV : TargetAllocs)
+ RMR.push_back({orcrpctpc::toWireProtectionFlags(
+ static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+ KV.second.Address, KV.second.AllocatedSize});
+ TargetAllocs.clear();
+
+ return Parent.getEndpoint().template callB<orcrpctpc::ReleaseMem>(RMR);
+ }
+
+ private:
+ OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent;
+ HostAllocMap HostAllocs;
+ TargetAllocMap TargetAllocs;
+ };
+
+ OrcRPCTPCJITLinkMemoryManager(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
+
+ Expected<std::unique_ptr<Allocation>>
+ allocate(const jitlink::JITLinkDylib *JD,
+ const SegmentsRequestMap &Request) override {
+ orcrpctpc::ReserveMemRequest RMR;
+ HostAllocMap HostAllocs;
+
+ for (auto &KV : Request) {
+ assert(KV.second.getContentSize() <= std::numeric_limits<size_t>::max() &&
+ "Content size is out-of-range for host");
+
+ RMR.push_back({orcrpctpc::toWireProtectionFlags(
+ static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+ KV.second.getContentSize() + KV.second.getZeroFillSize(),
+ KV.second.getAlignment()});
+ HostAllocs[KV.first] = {
+ std::make_unique<char[]>(KV.second.getContentSize()),
+ KV.second.getContentSize()};
+ }
+
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Orc remote memmgr got request:\n";
+ for (auto &KV : Request)
+ dbgs() << " permissions: "
+ << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
+ << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
+ << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
+ << ", content size: "
+ << formatv("{0:x16}", KV.second.getContentSize())
+ << " + zero-fill-size: "
+ << formatv("{0:x16}", KV.second.getZeroFillSize())
+ << ", align: " << KV.second.getAlignment() << "\n";
+ });
+
+ // FIXME: LLVM RPC needs to be fixed to support alt
+ // serialization/deserialization on return types. For now just
+ // translate from std::map to DenseMap manually.
+ auto TmpTargetAllocs =
+ Parent.getEndpoint().template callB<orcrpctpc::ReserveMem>(RMR);
+ if (!TmpTargetAllocs)
+ return TmpTargetAllocs.takeError();
+
+ if (TmpTargetAllocs->size() != RMR.size())
+ return make_error<StringError>(
+ "Number of target allocations does not match request",
+ inconvertibleErrorCode());
+
+ TargetAllocMap TargetAllocs;
+ for (auto &E : *TmpTargetAllocs)
+ TargetAllocs[orcrpctpc::fromWireProtectionFlags(E.Prot)] = {
+ E.Address, E.AllocatedSize};
+
+ DEBUG_WITH_TYPE("orc", {
+ auto HAI = HostAllocs.begin();
+ for (auto &KV : TargetAllocs)
+ dbgs() << " permissions: "
+ << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
+ << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
+ << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
+ << " assigned local " << (void *)HAI->second.Mem.get()
+ << ", target " << formatv("{0:x16}", KV.second.Address) << "\n";
+ });
+
+ return std::make_unique<OrcRPCAllocation>(*this, std::move(HostAllocs),
+ std::move(TargetAllocs));
+ }
+
+private:
+ void reportError(Error Err) { Parent.reportError(std::move(Err)); }
+
+ decltype(std::declval<OrcRPCTPCImplT>().getEndpoint()) getEndpoint() {
+ return Parent.getEndpoint();
+ }
+
+ OrcRPCTPCImplT &Parent;
+};
+
+/// TargetProcessControl::MemoryAccess implementation for a process connected
+/// via an ORC RPC endpoint.
+template <typename OrcRPCTPCImplT>
+class OrcRPCTPCMemoryAccess : public TargetProcessControl::MemoryAccess {
+public:
+ OrcRPCTPCMemoryAccess(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
+
+ void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt8s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt16s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt32s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt64s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteBuffers>(Ws, std::move(OnWriteComplete));
+ }
+
+private:
+ template <typename WriteRPCFunction, typename WriteElementT>
+ void writeViaRPC(ArrayRef<WriteElementT> Ws, WriteResultFn OnWriteComplete) {
+ if (auto Err = Parent.getEndpoint().template callAsync<WriteRPCFunction>(
+ [OWC = std::move(OnWriteComplete)](Error Err2) mutable -> Error {
+ OWC(std::move(Err2));
+ return Error::success();
+ },
+ Ws)) {
+ Parent.reportError(std::move(Err));
+ Parent.getEndpoint().abandonPendingResponses();
+ }
+ }
+
+ OrcRPCTPCImplT &Parent;
+};
+
+// TargetProcessControl for a process connected via an ORC RPC Endpoint.
+template <typename RPCEndpointT>
+class OrcRPCTargetProcessControlBase : public TargetProcessControl {
+public:
+ using ErrorReporter = unique_function<void(Error)>;
+
+ using OnCloseConnectionFunction = unique_function<Error(Error)>;
+
+ OrcRPCTargetProcessControlBase(std::shared_ptr<SymbolStringPool> SSP,
+ RPCEndpointT &EP, ErrorReporter ReportError)
+ : TargetProcessControl(std::move(SSP)),
+ ReportError(std::move(ReportError)), EP(EP) {}
+
+ void reportError(Error Err) { ReportError(std::move(Err)); }
+
+ RPCEndpointT &getEndpoint() { return EP; }
+
+ Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Loading dylib \"" << (DylibPath ? DylibPath : "") << "\" ";
+ if (!DylibPath)
+ dbgs() << "(process symbols)";
+ dbgs() << "\n";
+ });
+ if (!DylibPath)
+ DylibPath = "";
+ auto H = EP.template callB<orcrpctpc::LoadDylib>(DylibPath);
+ DEBUG_WITH_TYPE("orc", {
+ if (H)
+ dbgs() << " got handle " << formatv("{0:x16}", *H) << "\n";
+ else
+ dbgs() << " error, unable to load\n";
+ });
+ return H;
+ }
+
+ Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(ArrayRef<LookupRequest> Request) override {
+ std::vector<orcrpctpc::RemoteLookupRequest> RR;
+ for (auto &E : Request) {
+ RR.push_back({});
+ RR.back().first = E.Handle;
+ for (auto &KV : E.Symbols)
+ RR.back().second.push_back(
+ {(*KV.first).str(),
+ KV.second == SymbolLookupFlags::WeaklyReferencedSymbol});
+ }
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Compound lookup:\n";
+ for (auto &R : Request) {
+ dbgs() << " In " << formatv("{0:x16}", R.Handle) << ": {";
+ bool First = true;
+ for (auto &KV : R.Symbols) {
+ dbgs() << (First ? "" : ",") << " " << *KV.first;
+ First = false;
+ }
+ dbgs() << " }\n";
+ }
+ });
+ return EP.template callB<orcrpctpc::LookupSymbols>(RR);
+ }
+
+ Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+ ArrayRef<std::string> Args) override {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Running as main: " << formatv("{0:x16}", MainFnAddr)
+ << ", args = [";
+ for (unsigned I = 0; I != Args.size(); ++I)
+ dbgs() << (I ? "," : "") << " \"" << Args[I] << "\"";
+ dbgs() << "]\n";
+ });
+ auto Result = EP.template callB<orcrpctpc::RunMain>(MainFnAddr, Args);
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << " call to " << formatv("{0:x16}", MainFnAddr);
+ if (Result)
+ dbgs() << " returned result " << *Result << "\n";
+ else
+ dbgs() << " failed\n";
+ });
+ return Result;
+ }
+
+ Expected<tpctypes::WrapperFunctionResult>
+ runWrapper(JITTargetAddress WrapperFnAddr,
+ ArrayRef<uint8_t> ArgBuffer) override {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Running as wrapper function "
+ << formatv("{0:x16}", WrapperFnAddr) << " with "
+ << formatv("{0:x16}", ArgBuffer.size()) << " argument buffer\n";
+ });
+ auto Result =
+ EP.template callB<orcrpctpc::RunWrapper>(WrapperFnAddr, ArgBuffer);
+ // dbgs() << "Returned from runWrapper...\n";
+ return Result;
+ }
+
+ Error closeConnection(OnCloseConnectionFunction OnCloseConnection) {
+ DEBUG_WITH_TYPE("orc", dbgs() << "Closing connection to remote\n");
+ return EP.template callAsync<orcrpctpc::CloseConnection>(
+ std::move(OnCloseConnection));
+ }
+
+ Error closeConnectionAndWait() {
+ std::promise<MSVCPError> P;
+ auto F = P.get_future();
+ if (auto Err = closeConnection([&](Error Err2) -> Error {
+ P.set_value(std::move(Err2));
+ return Error::success();
+ })) {
+ EP.abandonAllPendingResponses();
+ return joinErrors(std::move(Err), F.get());
+ }
+ return F.get();
+ }
+
+protected:
+ /// Subclasses must call this during construction to initialize the
+ /// TargetTriple and PageSize members.
+ Error initializeORCRPCTPCBase() {
+ if (auto TripleOrErr = EP.template callB<orcrpctpc::GetTargetTriple>())
+ TargetTriple = Triple(*TripleOrErr);
+ else
+ return TripleOrErr.takeError();
+
+ if (auto PageSizeOrErr = EP.template callB<orcrpctpc::GetPageSize>())
+ PageSize = *PageSizeOrErr;
+ else
+ return PageSizeOrErr.takeError();
+
+ return Error::success();
+ }
+
+private:
+ ErrorReporter ReportError;
+ RPCEndpointT &EP;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
index 86e8d5df3ad9..3d139740d677 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
@@ -53,7 +54,7 @@ namespace remote {
/// OrcRemoteTargetServer class) via an RPC system (see RPCUtils.h) to carry out
/// its actions.
class OrcRemoteTargetClient
- : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
+ : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
public:
/// Remote-mapped RuntimeDyld-compatible memory manager.
class RemoteRTDyldMemoryManager : public RuntimeDyld::MemoryManager {
@@ -329,6 +330,221 @@ public:
std::vector<EHFrame> RegisteredEHFrames;
};
+ class RPCMMAlloc : public jitlink::JITLinkMemoryManager::Allocation {
+ using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;
+ using FinalizeContinuation =
+ jitlink::JITLinkMemoryManager::Allocation::FinalizeContinuation;
+ using ProtectionFlags = sys::Memory::ProtectionFlags;
+ using SegmentsRequestMap =
+ DenseMap<unsigned, jitlink::JITLinkMemoryManager::SegmentRequest>;
+
+ RPCMMAlloc(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id)
+ : Client(Client), Id(Id) {}
+
+ public:
+ static Expected<std::unique_ptr<RPCMMAlloc>>
+ Create(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id,
+ const SegmentsRequestMap &Request) {
+ auto *MM = new RPCMMAlloc(Client, Id);
+
+ if (Error Err = MM->allocateHostBlocks(Request))
+ return std::move(Err);
+
+ if (Error Err = MM->allocateTargetBlocks())
+ return std::move(Err);
+
+ return std::unique_ptr<RPCMMAlloc>(MM);
+ }
+
+ MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
+ assert(HostSegBlocks.count(Seg) && "No allocation for segment");
+ return {static_cast<char *>(HostSegBlocks[Seg].base()),
+ HostSegBlocks[Seg].allocatedSize()};
+ }
+
+ JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
+ assert(TargetSegBlocks.count(Seg) && "No allocation for segment");
+ return pointerToJITTargetAddress(TargetSegBlocks[Seg].base());
+ }
+
+ void finalizeAsync(FinalizeContinuation OnFinalize) override {
+ // Host allocations (working memory) remain ReadWrite.
+ OnFinalize(copyAndProtect());
+ }
+
+ Error deallocate() override {
+ // TODO: Cannot release target allocation. RPCAPI has no function
+ // symmetric to reserveMem(). Add RPC call like freeMem()?
+ return errorCodeToError(sys::Memory::releaseMappedMemory(HostAllocation));
+ }
+
+ private:
+ OrcRemoteTargetClient &Client;
+ ResourceIdMgr::ResourceId Id;
+ AllocationMap HostSegBlocks;
+ AllocationMap TargetSegBlocks;
+ JITTargetAddress TargetSegmentAddr;
+ sys::MemoryBlock HostAllocation;
+
+ Error allocateHostBlocks(const SegmentsRequestMap &Request) {
+ unsigned TargetPageSize = Client.getPageSize();
+
+ if (!isPowerOf2_64(static_cast<uint64_t>(TargetPageSize)))
+ return make_error<StringError>("Host page size is not a power of 2",
+ inconvertibleErrorCode());
+
+ auto TotalSize = calcTotalAllocSize(Request, TargetPageSize);
+ if (!TotalSize)
+ return TotalSize.takeError();
+
+ // Allocate one slab to cover all the segments.
+ const sys::Memory::ProtectionFlags ReadWrite =
+ static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
+ sys::Memory::MF_WRITE);
+ std::error_code EC;
+ HostAllocation =
+ sys::Memory::allocateMappedMemory(*TotalSize, nullptr, ReadWrite, EC);
+ if (EC)
+ return errorCodeToError(EC);
+
+ char *SlabAddr = static_cast<char *>(HostAllocation.base());
+#ifndef NDEBUG
+ char *SlabAddrEnd = SlabAddr + HostAllocation.allocatedSize();
+#endif
+
+ // Allocate segment memory from the slab.
+ for (auto &KV : Request) {
+ const auto &Seg = KV.second;
+
+ uint64_t SegmentSize = Seg.getContentSize() + Seg.getZeroFillSize();
+ uint64_t AlignedSegmentSize = alignTo(SegmentSize, TargetPageSize);
+
+ // Zero out zero-fill memory.
+ char *ZeroFillBegin = SlabAddr + Seg.getContentSize();
+ memset(ZeroFillBegin, 0, Seg.getZeroFillSize());
+
+ // Record the block for this segment.
+ HostSegBlocks[KV.first] =
+ sys::MemoryBlock(SlabAddr, AlignedSegmentSize);
+
+ SlabAddr += AlignedSegmentSize;
+ assert(SlabAddr <= SlabAddrEnd && "Out of range");
+ }
+
+ return Error::success();
+ }
+
+ Error allocateTargetBlocks() {
+ // Reserve memory for all blocks on the target. We need as much space on
+ // the target as we allocated on the host.
+ TargetSegmentAddr = Client.reserveMem(Id, HostAllocation.allocatedSize(),
+ Client.getPageSize());
+ if (!TargetSegmentAddr)
+ return make_error<StringError>("Failed to reserve memory on the target",
+ inconvertibleErrorCode());
+
+ // Map memory blocks into the allocation, that match the host allocation.
+ JITTargetAddress TargetAllocAddr = TargetSegmentAddr;
+ for (const auto &KV : HostSegBlocks) {
+ size_t TargetAllocSize = KV.second.allocatedSize();
+
+ TargetSegBlocks[KV.first] =
+ sys::MemoryBlock(jitTargetAddressToPointer<void *>(TargetAllocAddr),
+ TargetAllocSize);
+
+ TargetAllocAddr += TargetAllocSize;
+ assert(TargetAllocAddr - TargetSegmentAddr <=
+ HostAllocation.allocatedSize() &&
+ "Out of range on target");
+ }
+
+ return Error::success();
+ }
+
+ Error copyAndProtect() {
+ unsigned Permissions = 0u;
+
+ // Copy segments one by one.
+ for (auto &KV : TargetSegBlocks) {
+ Permissions |= KV.first;
+
+ const sys::MemoryBlock &TargetBlock = KV.second;
+ const sys::MemoryBlock &HostBlock = HostSegBlocks.lookup(KV.first);
+
+ size_t TargetAllocSize = TargetBlock.allocatedSize();
+ auto TargetAllocAddr = pointerToJITTargetAddress(TargetBlock.base());
+ auto *HostAllocBegin = static_cast<const char *>(HostBlock.base());
+
+ bool CopyErr =
+ Client.writeMem(TargetAllocAddr, HostAllocBegin, TargetAllocSize);
+ if (CopyErr)
+ return createStringError(inconvertibleErrorCode(),
+ "Failed to copy %d segment to the target",
+ KV.first);
+ }
+
+ // Set permission flags for all segments at once.
+ bool ProtectErr =
+ Client.setProtections(Id, TargetSegmentAddr, Permissions);
+ if (ProtectErr)
+ return createStringError(inconvertibleErrorCode(),
+ "Failed to apply permissions for %d segment "
+ "on the target",
+ Permissions);
+ return Error::success();
+ }
+
+ static Expected<size_t>
+ calcTotalAllocSize(const SegmentsRequestMap &Request,
+ unsigned TargetPageSize) {
+ size_t TotalSize = 0;
+ for (const auto &KV : Request) {
+ const auto &Seg = KV.second;
+
+ if (Seg.getAlignment() > TargetPageSize)
+ return make_error<StringError>("Cannot request alignment higher than "
+ "page alignment on target",
+ inconvertibleErrorCode());
+
+ TotalSize = alignTo(TotalSize, TargetPageSize);
+ TotalSize += Seg.getContentSize();
+ TotalSize += Seg.getZeroFillSize();
+ }
+
+ return TotalSize;
+ }
+ };
+
+ class RemoteJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
+ public:
+ RemoteJITLinkMemoryManager(OrcRemoteTargetClient &Client,
+ ResourceIdMgr::ResourceId Id)
+ : Client(Client), Id(Id) {}
+
+ RemoteJITLinkMemoryManager(const RemoteJITLinkMemoryManager &) = delete;
+ RemoteJITLinkMemoryManager(RemoteJITLinkMemoryManager &&) = default;
+
+ RemoteJITLinkMemoryManager &
+ operator=(const RemoteJITLinkMemoryManager &) = delete;
+ RemoteJITLinkMemoryManager &
+ operator=(RemoteJITLinkMemoryManager &&) = delete;
+
+ ~RemoteJITLinkMemoryManager() {
+ Client.destroyRemoteAllocator(Id);
+ LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n");
+ }
+
+ Expected<std::unique_ptr<Allocation>>
+ allocate(const jitlink::JITLinkDylib *JD,
+ const SegmentsRequestMap &Request) override {
+ return RPCMMAlloc::Create(Client, Id, Request);
+ }
+
+ private:
+ OrcRemoteTargetClient &Client;
+ ResourceIdMgr::ResourceId Id;
+ };
+
/// Remote indirect stubs manager.
class RemoteIndirectStubsManager : public IndirectStubsManager {
public:
@@ -453,20 +669,8 @@ public:
public:
RemoteTrampolinePool(OrcRemoteTargetClient &Client) : Client(Client) {}
- Expected<JITTargetAddress> getTrampoline() override {
- std::lock_guard<std::mutex> Lock(RTPMutex);
- if (AvailableTrampolines.empty()) {
- if (auto Err = grow())
- return std::move(Err);
- }
- assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
- auto TrampolineAddr = AvailableTrampolines.back();
- AvailableTrampolines.pop_back();
- return TrampolineAddr;
- }
-
private:
- Error grow() {
+ Error grow() override {
JITTargetAddress BlockAddr = 0;
uint32_t NumTrampolines = 0;
if (auto TrampolineInfoOrErr = Client.emitTrampolineBlock())
@@ -476,14 +680,12 @@ public:
uint32_t TrampolineSize = Client.getTrampolineSize();
for (unsigned I = 0; I < NumTrampolines; ++I)
- this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
+ AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
return Error::success();
}
- std::mutex RTPMutex;
OrcRemoteTargetClient &Client;
- std::vector<JITTargetAddress> AvailableTrampolines;
};
/// Remote compile callback manager.
@@ -501,7 +703,7 @@ public:
/// Channel is the ChannelT instance to communicate on. It is assumed that
/// the channel is ready to be read from and written to.
static Expected<std::unique_ptr<OrcRemoteTargetClient>>
- Create(rpc::RawByteChannel &Channel, ExecutionSession &ES) {
+ Create(shared::RawByteChannel &Channel, ExecutionSession &ES) {
Error Err = Error::success();
auto Client = std::unique_ptr<OrcRemoteTargetClient>(
new OrcRemoteTargetClient(Channel, ES, Err));
@@ -518,6 +720,14 @@ public:
return callB<exec::CallIntVoid>(Addr);
}
+ /// Call the int(int) function at the given address in the target and return
+ /// its result.
+ Expected<int> callIntInt(JITTargetAddress Addr, int Arg) {
+ LLVM_DEBUG(dbgs() << "Calling int(*)(int) " << format("0x%016" PRIx64, Addr)
+ << "\n");
+ return callB<exec::CallIntInt>(Addr, Arg);
+ }
+
/// Call the int(int, char*[]) function at the given address in the target and
/// return its result.
Expected<int> callMain(JITTargetAddress Addr,
@@ -546,6 +756,18 @@ public:
new RemoteRTDyldMemoryManager(*this, Id));
}
+ /// Create a JITLink-compatible memory manager which will allocate working
+ /// memory on the host and target memory on the remote target.
+ Expected<std::unique_ptr<RemoteJITLinkMemoryManager>>
+ createRemoteJITLinkMemoryManager() {
+ auto Id = AllocatorIds.getNext();
+ if (auto Err = callB<mem::CreateRemoteAllocator>(Id))
+ return std::move(Err);
+ LLVM_DEBUG(dbgs() << "Created remote allocator " << Id << "\n");
+ return std::unique_ptr<RemoteJITLinkMemoryManager>(
+ new RemoteJITLinkMemoryManager(*this, Id));
+ }
+
/// Create an RCIndirectStubsManager that will allocate stubs on the remote
/// target.
Expected<std::unique_ptr<RemoteIndirectStubsManager>>
@@ -583,9 +805,10 @@ public:
Error terminateSession() { return callB<utils::TerminateSession>(); }
private:
- OrcRemoteTargetClient(rpc::RawByteChannel &Channel, ExecutionSession &ES,
+ OrcRemoteTargetClient(shared::RawByteChannel &Channel, ExecutionSession &ES,
Error &Err)
- : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(Channel, true),
+ : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
+ true),
ES(ES) {
ErrorAsOutParameter EAO(&Err);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
index 52a328165240..367bfb369191 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
@@ -16,8 +16,8 @@
#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/Orc/RPC/RPCUtils.h"
-#include "llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
namespace llvm {
namespace orc {
@@ -73,10 +73,9 @@ private:
} // end namespace remote
-namespace rpc {
+namespace shared {
-template <>
-class RPCTypeName<JITSymbolFlags> {
+template <> class SerializationTypeName<JITSymbolFlags> {
public:
static const char *getName() { return "JITSymbolFlags"; }
};
@@ -100,7 +99,7 @@ public:
}
};
-template <> class RPCTypeName<remote::DirectBufferWriter> {
+template <> class SerializationTypeName<remote::DirectBufferWriter> {
public:
static const char *getName() { return "DirectBufferWriter"; }
};
@@ -133,7 +132,7 @@ public:
}
};
-} // end namespace rpc
+} // end namespace shared
namespace remote {
@@ -167,20 +166,20 @@ private:
namespace eh {
/// Registers EH frames on the remote.
- class RegisterEHFrames
- : public rpc::Function<RegisterEHFrames,
- void(JITTargetAddress Addr, uint32_t Size)> {
- public:
- static const char *getName() { return "RegisterEHFrames"; }
- };
+class RegisterEHFrames
+ : public shared::RPCFunction<RegisterEHFrames,
+ void(JITTargetAddress Addr, uint32_t Size)> {
+public:
+ static const char *getName() { return "RegisterEHFrames"; }
+};
/// Deregisters EH frames on the remote.
- class DeregisterEHFrames
- : public rpc::Function<DeregisterEHFrames,
- void(JITTargetAddress Addr, uint32_t Size)> {
- public:
- static const char *getName() { return "DeregisterEHFrames"; }
- };
+class DeregisterEHFrames
+ : public shared::RPCFunction<DeregisterEHFrames,
+ void(JITTargetAddress Addr, uint32_t Size)> {
+public:
+ static const char *getName() { return "DeregisterEHFrames"; }
+};
} // end namespace eh
@@ -189,28 +188,38 @@ namespace exec {
/// Call an 'int32_t()'-type function on the remote, returns the called
/// function's return value.
- class CallIntVoid
- : public rpc::Function<CallIntVoid, int32_t(JITTargetAddress Addr)> {
- public:
- static const char *getName() { return "CallIntVoid"; }
- };
+class CallIntVoid
+ : public shared::RPCFunction<CallIntVoid, int32_t(JITTargetAddress Addr)> {
+public:
+ static const char *getName() { return "CallIntVoid"; }
+};
+
+ /// Call an 'int32_t(int32_t)'-type function on the remote, returns the called
+ /// function's return value.
+class CallIntInt
+ : public shared::RPCFunction<CallIntInt,
+ int32_t(JITTargetAddress Addr, int)> {
+public:
+ static const char *getName() { return "CallIntInt"; }
+};
/// Call an 'int32_t(int32_t, char**)'-type function on the remote, returns the
/// called function's return value.
- class CallMain
- : public rpc::Function<CallMain, int32_t(JITTargetAddress Addr,
- std::vector<std::string> Args)> {
- public:
- static const char *getName() { return "CallMain"; }
- };
+class CallMain
+ : public shared::RPCFunction<CallMain,
+ int32_t(JITTargetAddress Addr,
+ std::vector<std::string> Args)> {
+public:
+ static const char *getName() { return "CallMain"; }
+};
/// Calls a 'void()'-type function on the remote, returns when the called
/// function completes.
- class CallVoidVoid
- : public rpc::Function<CallVoidVoid, void(JITTargetAddress FnAddr)> {
- public:
- static const char *getName() { return "CallVoidVoid"; }
- };
+class CallVoidVoid
+ : public shared::RPCFunction<CallVoidVoid, void(JITTargetAddress FnAddr)> {
+public:
+ static const char *getName() { return "CallVoidVoid"; }
+};
} // end namespace exec
@@ -218,60 +227,62 @@ namespace exec {
namespace mem {
/// Creates a memory allocator on the remote.
- class CreateRemoteAllocator
- : public rpc::Function<CreateRemoteAllocator,
- void(ResourceIdMgr::ResourceId AllocatorID)> {
- public:
- static const char *getName() { return "CreateRemoteAllocator"; }
- };
+class CreateRemoteAllocator
+ : public shared::RPCFunction<CreateRemoteAllocator,
+ void(ResourceIdMgr::ResourceId AllocatorID)> {
+public:
+ static const char *getName() { return "CreateRemoteAllocator"; }
+};
/// Destroys a remote allocator, freeing any memory allocated by it.
- class DestroyRemoteAllocator
- : public rpc::Function<DestroyRemoteAllocator,
- void(ResourceIdMgr::ResourceId AllocatorID)> {
- public:
- static const char *getName() { return "DestroyRemoteAllocator"; }
- };
+class DestroyRemoteAllocator
+ : public shared::RPCFunction<DestroyRemoteAllocator,
+ void(ResourceIdMgr::ResourceId AllocatorID)> {
+public:
+ static const char *getName() { return "DestroyRemoteAllocator"; }
+};
/// Read a remote memory block.
- class ReadMem
- : public rpc::Function<ReadMem, std::vector<uint8_t>(JITTargetAddress Src,
- uint64_t Size)> {
- public:
- static const char *getName() { return "ReadMem"; }
- };
+class ReadMem
+ : public shared::RPCFunction<
+ ReadMem, std::vector<uint8_t>(JITTargetAddress Src, uint64_t Size)> {
+public:
+ static const char *getName() { return "ReadMem"; }
+};
/// Reserve a block of memory on the remote via the given allocator.
- class ReserveMem
- : public rpc::Function<ReserveMem,
- JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
- uint64_t Size, uint32_t Align)> {
- public:
- static const char *getName() { return "ReserveMem"; }
- };
+class ReserveMem
+ : public shared::RPCFunction<
+ ReserveMem, JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
+ uint64_t Size, uint32_t Align)> {
+public:
+ static const char *getName() { return "ReserveMem"; }
+};
/// Set the memory protection on a memory block.
- class SetProtections
- : public rpc::Function<SetProtections,
- void(ResourceIdMgr::ResourceId AllocID,
- JITTargetAddress Dst, uint32_t ProtFlags)> {
- public:
- static const char *getName() { return "SetProtections"; }
- };
+class SetProtections
+ : public shared::RPCFunction<
+ SetProtections, void(ResourceIdMgr::ResourceId AllocID,
+ JITTargetAddress Dst, uint32_t ProtFlags)> {
+public:
+ static const char *getName() { return "SetProtections"; }
+};
/// Write to a remote memory block.
- class WriteMem
- : public rpc::Function<WriteMem, void(remote::DirectBufferWriter DB)> {
- public:
- static const char *getName() { return "WriteMem"; }
- };
+class WriteMem
+ : public shared::RPCFunction<WriteMem,
+ void(remote::DirectBufferWriter DB)> {
+public:
+ static const char *getName() { return "WriteMem"; }
+};
/// Write to a remote pointer.
- class WritePtr : public rpc::Function<WritePtr, void(JITTargetAddress Dst,
- JITTargetAddress Val)> {
- public:
- static const char *getName() { return "WritePtr"; }
- };
+class WritePtr
+ : public shared::RPCFunction<WritePtr, void(JITTargetAddress Dst,
+ JITTargetAddress Val)> {
+public:
+ static const char *getName() { return "WritePtr"; }
+};
} // end namespace mem
@@ -279,45 +290,46 @@ namespace mem {
namespace stubs {
/// Creates an indirect stub owner on the remote.
- class CreateIndirectStubsOwner
- : public rpc::Function<CreateIndirectStubsOwner,
- void(ResourceIdMgr::ResourceId StubOwnerID)> {
- public:
- static const char *getName() { return "CreateIndirectStubsOwner"; }
- };
+class CreateIndirectStubsOwner
+ : public shared::RPCFunction<CreateIndirectStubsOwner,
+ void(ResourceIdMgr::ResourceId StubOwnerID)> {
+public:
+ static const char *getName() { return "CreateIndirectStubsOwner"; }
+};
/// RPC function for destroying an indirect stubs owner.
- class DestroyIndirectStubsOwner
- : public rpc::Function<DestroyIndirectStubsOwner,
- void(ResourceIdMgr::ResourceId StubsOwnerID)> {
- public:
- static const char *getName() { return "DestroyIndirectStubsOwner"; }
- };
+class DestroyIndirectStubsOwner
+ : public shared::RPCFunction<DestroyIndirectStubsOwner,
+ void(ResourceIdMgr::ResourceId StubsOwnerID)> {
+public:
+ static const char *getName() { return "DestroyIndirectStubsOwner"; }
+};
/// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
- class EmitIndirectStubs
- : public rpc::Function<
- EmitIndirectStubs,
- std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
- ResourceIdMgr::ResourceId StubsOwnerID,
- uint32_t NumStubsRequired)> {
- public:
- static const char *getName() { return "EmitIndirectStubs"; }
- };
+class EmitIndirectStubs
+ : public shared::RPCFunction<
+ EmitIndirectStubs,
+ std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
+ ResourceIdMgr::ResourceId StubsOwnerID,
+ uint32_t NumStubsRequired)> {
+public:
+ static const char *getName() { return "EmitIndirectStubs"; }
+};
/// RPC function to emit the resolver block and return its address.
- class EmitResolverBlock : public rpc::Function<EmitResolverBlock, void()> {
- public:
- static const char *getName() { return "EmitResolverBlock"; }
- };
+class EmitResolverBlock
+ : public shared::RPCFunction<EmitResolverBlock, void()> {
+public:
+ static const char *getName() { return "EmitResolverBlock"; }
+};
/// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
- class EmitTrampolineBlock
- : public rpc::Function<EmitTrampolineBlock,
- std::tuple<JITTargetAddress, uint32_t>()> {
- public:
- static const char *getName() { return "EmitTrampolineBlock"; }
- };
+class EmitTrampolineBlock
+ : public shared::RPCFunction<EmitTrampolineBlock,
+ std::tuple<JITTargetAddress, uint32_t>()> {
+public:
+ static const char *getName() { return "EmitTrampolineBlock"; }
+};
} // end namespace stubs
@@ -326,44 +338,44 @@ namespace utils {
/// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
/// IndirectStubsSize).
- class GetRemoteInfo
- : public rpc::Function<
- GetRemoteInfo,
- std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
- public:
- static const char *getName() { return "GetRemoteInfo"; }
- };
+class GetRemoteInfo
+ : public shared::RPCFunction<
+ GetRemoteInfo,
+ std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
+public:
+ static const char *getName() { return "GetRemoteInfo"; }
+};
/// Get the address of a remote symbol.
- class GetSymbolAddress
- : public rpc::Function<GetSymbolAddress,
- JITTargetAddress(std::string SymbolName)> {
- public:
- static const char *getName() { return "GetSymbolAddress"; }
- };
+class GetSymbolAddress
+ : public shared::RPCFunction<GetSymbolAddress,
+ JITTargetAddress(std::string SymbolName)> {
+public:
+ static const char *getName() { return "GetSymbolAddress"; }
+};
/// Request that the host execute a compile callback.
- class RequestCompile
- : public rpc::Function<
- RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
- public:
- static const char *getName() { return "RequestCompile"; }
- };
+class RequestCompile
+ : public shared::RPCFunction<
+ RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
+public:
+ static const char *getName() { return "RequestCompile"; }
+};
/// Notify the remote and terminate the session.
- class TerminateSession : public rpc::Function<TerminateSession, void()> {
- public:
- static const char *getName() { return "TerminateSession"; }
- };
+class TerminateSession : public shared::RPCFunction<TerminateSession, void()> {
+public:
+ static const char *getName() { return "TerminateSession"; }
+};
} // namespace utils
class OrcRemoteTargetRPCAPI
- : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
+ : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
public:
// FIXME: Remove constructors once MSVC supports synthesizing move-ops.
- OrcRemoteTargetRPCAPI(rpc::RawByteChannel &C)
- : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(C, true) {}
+ OrcRemoteTargetRPCAPI(shared::RawByteChannel &C)
+ : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(C, true) {}
};
} // end namespace remote
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 50c155d77db1..ce9bf064303d 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -16,8 +16,8 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
-#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
@@ -46,7 +46,7 @@ namespace remote {
template <typename ChannelT, typename TargetT>
class OrcRemoteTargetServer
- : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
+ : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
public:
using SymbolLookupFtor =
std::function<JITTargetAddress(const std::string &Name)>;
@@ -57,12 +57,14 @@ public:
OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup,
EHFrameRegistrationFtor EHFramesRegister,
EHFrameRegistrationFtor EHFramesDeregister)
- : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(Channel, true),
+ : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
+ true),
SymbolLookup(std::move(SymbolLookup)),
EHFramesRegister(std::move(EHFramesRegister)),
EHFramesDeregister(std::move(EHFramesDeregister)) {
using ThisT = std::remove_reference_t<decltype(*this)>;
addHandler<exec::CallIntVoid>(*this, &ThisT::handleCallIntVoid);
+ addHandler<exec::CallIntInt>(*this, &ThisT::handleCallIntInt);
addHandler<exec::CallMain>(*this, &ThisT::handleCallMain);
addHandler<exec::CallVoidVoid>(*this, &ThisT::handleCallVoidVoid);
addHandler<mem::CreateRemoteAllocator>(*this,
@@ -168,6 +170,19 @@ private:
return Result;
}
+ Expected<int32_t> handleCallIntInt(JITTargetAddress Addr, int Arg) {
+ using IntIntFnTy = int (*)(int);
+
+ IntIntFnTy Fn = reinterpret_cast<IntIntFnTy>(static_cast<uintptr_t>(Addr));
+
+ LLVM_DEBUG(dbgs() << " Calling " << format("0x%016x", Addr)
+ << " with argument " << Arg << "\n");
+ int Result = Fn(Arg);
+ LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
+
+ return Result;
+ }
+
Expected<int32_t> handleCallMain(JITTargetAddress Addr,
std::vector<std::string> Args) {
using MainFnTy = int (*)(int, const char *[]);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index 9ada0871cf0c..7dfbf32b1ffa 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -20,7 +20,6 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
-#include "llvm/ExecutionEngine/Orc/Legacy.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
@@ -36,16 +35,16 @@
namespace llvm {
namespace orc {
-class RTDyldObjectLinkingLayer : public ObjectLayer {
+class RTDyldObjectLinkingLayer : public ObjectLayer, private ResourceManager {
public:
/// Functor for receiving object-loaded notifications.
- using NotifyLoadedFunction =
- std::function<void(VModuleKey, const object::ObjectFile &Obj,
- const RuntimeDyld::LoadedObjectInfo &)>;
+ using NotifyLoadedFunction = std::function<void(
+ MaterializationResponsibility &R, const object::ObjectFile &Obj,
+ const RuntimeDyld::LoadedObjectInfo &)>;
/// Functor for receiving finalization notifications.
- using NotifyEmittedFunction =
- std::function<void(VModuleKey, std::unique_ptr<MemoryBuffer>)>;
+ using NotifyEmittedFunction = std::function<void(
+ MaterializationResponsibility &R, std::unique_ptr<MemoryBuffer>)>;
using GetMemoryManagerFunction =
std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
@@ -58,7 +57,7 @@ public:
~RTDyldObjectLinkingLayer();
/// Emit the object.
- void emit(MaterializationResponsibility R,
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
/// Set the NotifyLoaded callback.
@@ -123,16 +122,23 @@ public:
void unregisterJITEventListener(JITEventListener &L);
private:
- Error onObjLoad(VModuleKey K, MaterializationResponsibility &R,
+ using MemoryManagerUP = std::unique_ptr<RuntimeDyld::MemoryManager>;
+
+ Error onObjLoad(MaterializationResponsibility &R,
const object::ObjectFile &Obj,
- RuntimeDyld::MemoryManager *MemMgr,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
std::map<StringRef, JITEvaluatedSymbol> Resolved,
std::set<StringRef> &InternalSymbols);
- void onObjEmit(VModuleKey K, MaterializationResponsibility &R,
+ void onObjEmit(MaterializationResponsibility &R,
object::OwningBinary<object::ObjectFile> O,
- RuntimeDyld::MemoryManager *MemMgr, Error Err);
+ std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
+ Error Err);
+
+ Error handleRemoveResources(ResourceKey K) override;
+ void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
mutable std::mutex RTDyldLayerMutex;
GetMemoryManagerFunction GetMemoryManager;
@@ -141,361 +147,8 @@ private:
bool ProcessAllSections = false;
bool OverrideObjectFlags = false;
bool AutoClaimObjectSymbols = false;
- std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs;
+ DenseMap<ResourceKey, std::vector<MemoryManagerUP>> MemMgrs;
std::vector<JITEventListener *> EventListeners;
- DenseMap<RuntimeDyld::MemoryManager *,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
- LoadedObjInfos;
-};
-
-class LegacyRTDyldObjectLinkingLayerBase {
-public:
- using ObjectPtr = std::unique_ptr<MemoryBuffer>;
-
-protected:
-
- /// Holds an object to be allocated/linked as a unit in the JIT.
- ///
- /// An instance of this class will be created for each object added
- /// via JITObjectLayer::addObject. Deleting the instance (via
- /// removeObject) frees its memory, removing all symbol definitions that
- /// had been provided by this instance. Higher level layers are responsible
- /// for taking any action required to handle the missing symbols.
- class LinkedObject {
- public:
- LinkedObject() = default;
- LinkedObject(const LinkedObject&) = delete;
- void operator=(const LinkedObject&) = delete;
- virtual ~LinkedObject() = default;
-
- virtual Error finalize() = 0;
-
- virtual JITSymbol::GetAddressFtor
- getSymbolMaterializer(std::string Name) = 0;
-
- virtual void mapSectionAddress(const void *LocalAddress,
- JITTargetAddress TargetAddr) const = 0;
-
- JITSymbol getSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- auto SymEntry = SymbolTable.find(Name);
- if (SymEntry == SymbolTable.end())
- return nullptr;
- if (!SymEntry->second.getFlags().isExported() && ExportedSymbolsOnly)
- return nullptr;
- if (!Finalized)
- return JITSymbol(getSymbolMaterializer(std::string(Name)),
- SymEntry->second.getFlags());
- return JITSymbol(SymEntry->second);
- }
-
- protected:
- StringMap<JITEvaluatedSymbol> SymbolTable;
- bool Finalized = false;
- };
-};
-
-/// Bare bones object linking layer.
-///
-/// This class is intended to be used as the base layer for a JIT. It allows
-/// object files to be loaded into memory, linked, and the addresses of their
-/// symbols queried. All objects added to this layer can see each other's
-/// symbols.
-class LegacyRTDyldObjectLinkingLayer : public LegacyRTDyldObjectLinkingLayerBase {
-public:
-
- using LegacyRTDyldObjectLinkingLayerBase::ObjectPtr;
-
- /// Functor for receiving object-loaded notifications.
- using NotifyLoadedFtor =
- std::function<void(VModuleKey, const object::ObjectFile &Obj,
- const RuntimeDyld::LoadedObjectInfo &)>;
-
- /// Functor for receiving finalization notifications.
- using NotifyFinalizedFtor =
- std::function<void(VModuleKey, const object::ObjectFile &Obj,
- const RuntimeDyld::LoadedObjectInfo &)>;
-
- /// Functor for receiving deallocation notifications.
- using NotifyFreedFtor = std::function<void(VModuleKey, const object::ObjectFile &Obj)>;
-
-private:
- using OwnedObject = object::OwningBinary<object::ObjectFile>;
-
- template <typename MemoryManagerPtrT>
- class ConcreteLinkedObject : public LinkedObject {
- public:
- ConcreteLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
- OwnedObject Obj, MemoryManagerPtrT MemMgr,
- std::shared_ptr<SymbolResolver> Resolver,
- bool ProcessAllSections)
- : K(std::move(K)),
- Parent(Parent),
- MemMgr(std::move(MemMgr)),
- PFC(std::make_unique<PreFinalizeContents>(
- std::move(Obj), std::move(Resolver),
- ProcessAllSections)) {
- buildInitialSymbolTable(PFC->Obj);
- }
-
- ~ConcreteLinkedObject() override {
- if (this->Parent.NotifyFreed && ObjForNotify.getBinary())
- this->Parent.NotifyFreed(K, *ObjForNotify.getBinary());
-
- MemMgr->deregisterEHFrames();
- }
-
- Error finalize() override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObject");
-
- JITSymbolResolverAdapter ResolverAdapter(Parent.ES, *PFC->Resolver,
- nullptr);
- PFC->RTDyld = std::make_unique<RuntimeDyld>(*MemMgr, ResolverAdapter);
- PFC->RTDyld->setProcessAllSections(PFC->ProcessAllSections);
-
- Finalized = true;
-
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
- PFC->RTDyld->loadObject(*PFC->Obj.getBinary());
-
- // Copy the symbol table out of the RuntimeDyld instance.
- {
- auto SymTab = PFC->RTDyld->getSymbolTable();
- for (auto &KV : SymTab)
- SymbolTable[KV.first] = KV.second;
- }
-
- if (Parent.NotifyLoaded)
- Parent.NotifyLoaded(K, *PFC->Obj.getBinary(), *Info);
-
- PFC->RTDyld->finalizeWithMemoryManagerLocking();
-
- if (PFC->RTDyld->hasError())
- return make_error<StringError>(PFC->RTDyld->getErrorString(),
- inconvertibleErrorCode());
-
- if (Parent.NotifyFinalized)
- Parent.NotifyFinalized(K, *PFC->Obj.getBinary(), *Info);
-
- // Release resources.
- if (this->Parent.NotifyFreed)
- ObjForNotify = std::move(PFC->Obj); // needed for callback
- PFC = nullptr;
- return Error::success();
- }
-
- JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override {
- return [this, Name]() -> Expected<JITTargetAddress> {
- // The symbol may be materialized between the creation of this lambda
- // and its execution, so we need to double check.
- if (!this->Finalized)
- if (auto Err = this->finalize())
- return std::move(Err);
- return this->getSymbol(Name, false).getAddress();
- };
- }
-
- void mapSectionAddress(const void *LocalAddress,
- JITTargetAddress TargetAddr) const override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObject");
- assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
- PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
- }
-
- private:
- void buildInitialSymbolTable(const OwnedObject &Obj) {
- for (auto &Symbol : Obj.getBinary()->symbols()) {
- if (Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags()) {
- if (*SymbolFlagsOrErr & object::SymbolRef::SF_Undefined)
- continue;
- } else {
- // FIXME: Raise an error for bad symbols.
- consumeError(SymbolFlagsOrErr.takeError());
- continue;
- }
-
- Expected<StringRef> SymbolName = Symbol.getName();
- // FIXME: Raise an error for bad symbols.
- if (!SymbolName) {
- consumeError(SymbolName.takeError());
- continue;
- }
- // FIXME: Raise an error for bad symbols.
- auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
- if (!Flags) {
- consumeError(Flags.takeError());
- continue;
- }
- SymbolTable.insert(
- std::make_pair(*SymbolName, JITEvaluatedSymbol(0, *Flags)));
- }
- }
-
- // Contains the information needed prior to finalization: the object files,
- // memory manager, resolver, and flags needed for RuntimeDyld.
- struct PreFinalizeContents {
- PreFinalizeContents(OwnedObject Obj,
- std::shared_ptr<SymbolResolver> Resolver,
- bool ProcessAllSections)
- : Obj(std::move(Obj)),
- Resolver(std::move(Resolver)),
- ProcessAllSections(ProcessAllSections) {}
-
- OwnedObject Obj;
- std::shared_ptr<SymbolResolver> Resolver;
- bool ProcessAllSections;
- std::unique_ptr<RuntimeDyld> RTDyld;
- };
-
- VModuleKey K;
- LegacyRTDyldObjectLinkingLayer &Parent;
- MemoryManagerPtrT MemMgr;
- OwnedObject ObjForNotify;
- std::unique_ptr<PreFinalizeContents> PFC;
- };
-
- template <typename MemoryManagerPtrT>
- std::unique_ptr<ConcreteLinkedObject<MemoryManagerPtrT>>
- createLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
- OwnedObject Obj, MemoryManagerPtrT MemMgr,
- std::shared_ptr<SymbolResolver> Resolver,
- bool ProcessAllSections) {
- using LOS = ConcreteLinkedObject<MemoryManagerPtrT>;
- return std::make_unique<LOS>(Parent, std::move(K), std::move(Obj),
- std::move(MemMgr), std::move(Resolver),
- ProcessAllSections);
- }
-
-public:
- struct Resources {
- std::shared_ptr<RuntimeDyld::MemoryManager> MemMgr;
- std::shared_ptr<SymbolResolver> Resolver;
- };
-
- using ResourcesGetter = std::function<Resources(VModuleKey)>;
-
- /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
- /// and NotifyFinalized functors.
- LLVM_ATTRIBUTE_DEPRECATED(
- LegacyRTDyldObjectLinkingLayer(
- ExecutionSession &ES, ResourcesGetter GetResources,
- NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
- NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(),
- NotifyFreedFtor NotifyFreed = NotifyFreedFtor()),
- "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
- "use "
- "ORCv2 (see docs/ORCv2.rst)");
-
- // Legacy layer constructor with deprecation acknowledgement.
- LegacyRTDyldObjectLinkingLayer(
- ORCv1DeprecationAcknowledgement, ExecutionSession &ES,
- ResourcesGetter GetResources,
- NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
- NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(),
- NotifyFreedFtor NotifyFreed = NotifyFreedFtor())
- : ES(ES), GetResources(std::move(GetResources)),
- NotifyLoaded(std::move(NotifyLoaded)),
- NotifyFinalized(std::move(NotifyFinalized)),
- NotifyFreed(std::move(NotifyFreed)), ProcessAllSections(false) {}
-
- /// Set the 'ProcessAllSections' flag.
- ///
- /// If set to true, all sections in each object file will be allocated using
- /// the memory manager, rather than just the sections required for execution.
- ///
- /// This is kludgy, and may be removed in the future.
- void setProcessAllSections(bool ProcessAllSections) {
- this->ProcessAllSections = ProcessAllSections;
- }
-
- /// Add an object to the JIT.
- Error addObject(VModuleKey K, ObjectPtr ObjBuffer) {
-
- auto Obj =
- object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
- if (!Obj)
- return Obj.takeError();
-
- assert(!LinkedObjects.count(K) && "VModuleKey already in use");
-
- auto R = GetResources(K);
-
- LinkedObjects[K] = createLinkedObject(
- *this, K, OwnedObject(std::move(*Obj), std::move(ObjBuffer)),
- std::move(R.MemMgr), std::move(R.Resolver), ProcessAllSections);
-
- return Error::success();
- }
-
- /// Remove the object associated with VModuleKey K.
- ///
- /// All memory allocated for the object will be freed, and the sections and
- /// symbols it provided will no longer be available. No attempt is made to
- /// re-emit the missing symbols, and any use of these symbols (directly or
- /// indirectly) will result in undefined behavior. If dependence tracking is
- /// required to detect or resolve such issues it should be added at a higher
- /// layer.
- Error removeObject(VModuleKey K) {
- assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
- // How do we invalidate the symbols in H?
- LinkedObjects.erase(K);
- return Error::success();
- }
-
- /// Search for the given named symbol.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it exists.
- JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- for (auto &KV : LinkedObjects)
- if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly))
- return Sym;
- else if (auto Err = Sym.takeError())
- return std::move(Err);
-
- return nullptr;
- }
-
- /// Search for the given named symbol in the context of the loaded
- /// object represented by the VModuleKey K.
- /// @param K The VModuleKey for the object to search in.
- /// @param Name The name of the symbol to search for.
- /// @param ExportedSymbolsOnly If true, search only for exported symbols.
- /// @return A handle for the given named symbol, if it is found in the
- /// given object.
- JITSymbol findSymbolIn(VModuleKey K, StringRef Name,
- bool ExportedSymbolsOnly) {
- assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
- return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly);
- }
-
- /// Map section addresses for the object associated with the
- /// VModuleKey K.
- void mapSectionAddress(VModuleKey K, const void *LocalAddress,
- JITTargetAddress TargetAddr) {
- assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
- LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr);
- }
-
- /// Immediately emit and finalize the object represented by the given
- /// VModuleKey.
- /// @param K VModuleKey for object to emit/finalize.
- Error emitAndFinalize(VModuleKey K) {
- assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
- return LinkedObjects[K]->finalize();
- }
-
-private:
- ExecutionSession &ES;
-
- ResourcesGetter GetResources;
- NotifyLoadedFtor NotifyLoaded;
- NotifyFinalizedFtor NotifyFinalized;
- NotifyFreedFtor NotifyFreed;
-
- // NB! `LinkedObjects` needs to be destroyed before `NotifyFreed` because
- // `~ConcreteLinkedObject` calls `NotifyFreed`
- std::map<VModuleKey, std::unique_ptr<LinkedObject>> LinkedObjects;
- bool ProcessAllSections = false;
};
} // end namespace orc
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h
deleted file mode 100644
index d7304cfcf931..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h
+++ /dev/null
@@ -1,564 +0,0 @@
-//===------ RemoteObjectLayer.h - Forwards objs to a remote -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Forwards objects to a remote object layer via RPC.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
-
-#include "llvm/ExecutionEngine/Orc/Core.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
-#include "llvm/Object/ObjectFile.h"
-#include <map>
-
-namespace llvm {
-namespace orc {
-
-/// RPC API needed by RemoteObjectClientLayer and RemoteObjectServerLayer.
-class RemoteObjectLayerAPI {
-public:
-
- using ObjHandleT = remote::ResourceIdMgr::ResourceId;
-
-protected:
-
- using RemoteSymbolId = remote::ResourceIdMgr::ResourceId;
- using RemoteSymbol = std::pair<RemoteSymbolId, JITSymbolFlags>;
-
-public:
-
- using BadSymbolHandleError = remote::ResourceNotFound<RemoteSymbolId>;
- using BadObjectHandleError = remote::ResourceNotFound<ObjHandleT>;
-
-protected:
-
- static const ObjHandleT InvalidObjectHandleId = 0;
- static const RemoteSymbolId NullSymbolId = 0;
-
- class AddObject
- : public rpc::Function<AddObject, Expected<ObjHandleT>(std::string)> {
- public:
- static const char *getName() { return "AddObject"; }
- };
-
- class RemoveObject
- : public rpc::Function<RemoveObject, Error(ObjHandleT)> {
- public:
- static const char *getName() { return "RemoveObject"; }
- };
-
- class FindSymbol
- : public rpc::Function<FindSymbol, Expected<RemoteSymbol>(std::string,
- bool)> {
- public:
- static const char *getName() { return "FindSymbol"; }
- };
-
- class FindSymbolIn
- : public rpc::Function<FindSymbolIn,
- Expected<RemoteSymbol>(ObjHandleT, std::string,
- bool)> {
- public:
- static const char *getName() { return "FindSymbolIn"; }
- };
-
- class EmitAndFinalize
- : public rpc::Function<EmitAndFinalize,
- Error(ObjHandleT)> {
- public:
- static const char *getName() { return "EmitAndFinalize"; }
- };
-
- class Lookup
- : public rpc::Function<Lookup,
- Expected<RemoteSymbol>(ObjHandleT, std::string)> {
- public:
- static const char *getName() { return "Lookup"; }
- };
-
- class LookupInLogicalDylib
- : public rpc::Function<LookupInLogicalDylib,
- Expected<RemoteSymbol>(ObjHandleT, std::string)> {
- public:
- static const char *getName() { return "LookupInLogicalDylib"; }
- };
-
- class ReleaseRemoteSymbol
- : public rpc::Function<ReleaseRemoteSymbol, Error(RemoteSymbolId)> {
- public:
- static const char *getName() { return "ReleaseRemoteSymbol"; }
- };
-
- class MaterializeRemoteSymbol
- : public rpc::Function<MaterializeRemoteSymbol,
- Expected<JITTargetAddress>(RemoteSymbolId)> {
- public:
- static const char *getName() { return "MaterializeRemoteSymbol"; }
- };
-};
-
-/// Base class containing common utilities for RemoteObjectClientLayer and
-/// RemoteObjectServerLayer.
-template <typename RPCEndpoint>
-class RemoteObjectLayer : public RemoteObjectLayerAPI {
-public:
-
- RemoteObjectLayer(RPCEndpoint &Remote,
- std::function<void(Error)> ReportError)
- : Remote(Remote), ReportError(std::move(ReportError)),
- SymbolIdMgr(NullSymbolId + 1) {
- using ThisT = RemoteObjectLayer<RPCEndpoint>;
- Remote.template addHandler<ReleaseRemoteSymbol>(
- *this, &ThisT::handleReleaseRemoteSymbol);
- Remote.template addHandler<MaterializeRemoteSymbol>(
- *this, &ThisT::handleMaterializeRemoteSymbol);
- }
-
-protected:
-
- /// This class is used as the symbol materializer for JITSymbols returned by
- /// RemoteObjectLayerClient/RemoteObjectLayerServer -- the materializer knows
- /// how to call back to the other RPC endpoint to get the address when
- /// requested.
- class RemoteSymbolMaterializer {
- public:
-
- /// Construct a RemoteSymbolMaterializer for the given RemoteObjectLayer
- /// with the given Id.
- RemoteSymbolMaterializer(RemoteObjectLayer &C,
- RemoteSymbolId Id)
- : C(C), Id(Id) {}
-
- RemoteSymbolMaterializer(RemoteSymbolMaterializer &&Other)
- : C(Other.C), Id(Other.Id) {
- Other.Id = 0;
- }
-
- RemoteSymbolMaterializer &operator=(RemoteSymbolMaterializer &&) = delete;
-
- /// Release the remote symbol.
- ~RemoteSymbolMaterializer() {
- if (Id)
- C.releaseRemoteSymbol(Id);
- }
-
- /// Materialize the symbol on the remote and get its address.
- Expected<JITTargetAddress> materialize() {
- auto Addr = C.materializeRemoteSymbol(Id);
- Id = 0;
- return Addr;
- }
-
- private:
- RemoteObjectLayer &C;
- RemoteSymbolId Id;
- };
-
- /// Convenience function for getting a null remote symbol value.
- RemoteSymbol nullRemoteSymbol() {
- return RemoteSymbol(0, JITSymbolFlags());
- }
-
- /// Creates a StringError that contains a copy of Err's log message, then
- /// sends that StringError to ReportError.
- ///
- /// This allows us to locally log error messages for errors that will actually
- /// be delivered to the remote.
- Error teeLog(Error Err) {
- return handleErrors(std::move(Err),
- [this](std::unique_ptr<ErrorInfoBase> EIB) {
- ReportError(make_error<StringError>(
- EIB->message(),
- EIB->convertToErrorCode()));
- return Error(std::move(EIB));
- });
- }
-
- Error badRemoteSymbolIdError(RemoteSymbolId Id) {
- return make_error<BadSymbolHandleError>(Id, "Remote JIT Symbol");
- }
-
- Error badObjectHandleError(ObjHandleT H) {
- return make_error<RemoteObjectLayerAPI::BadObjectHandleError>(
- H, "Bad object handle");
- }
-
- /// Create a RemoteSymbol wrapping the given JITSymbol.
- Expected<RemoteSymbol> jitSymbolToRemote(JITSymbol Sym) {
- if (Sym) {
- auto Id = SymbolIdMgr.getNext();
- auto Flags = Sym.getFlags();
- assert(!InUseSymbols.count(Id) && "Symbol id already in use");
- InUseSymbols.insert(std::make_pair(Id, std::move(Sym)));
- return RemoteSymbol(Id, Flags);
- } else if (auto Err = Sym.takeError())
- return teeLog(std::move(Err));
- // else...
- return nullRemoteSymbol();
- }
-
- /// Convert an Expected<RemoteSymbol> to a JITSymbol.
- JITSymbol remoteToJITSymbol(Expected<RemoteSymbol> RemoteSymOrErr) {
- if (RemoteSymOrErr) {
- auto &RemoteSym = *RemoteSymOrErr;
- if (RemoteSym == nullRemoteSymbol())
- return nullptr;
- // else...
- RemoteSymbolMaterializer RSM(*this, RemoteSym.first);
- auto Sym = JITSymbol(
- [RSM = std::move(RSM)]() mutable { return RSM.materialize(); },
- RemoteSym.second);
- return Sym;
- } else
- return RemoteSymOrErr.takeError();
- }
-
- RPCEndpoint &Remote;
- std::function<void(Error)> ReportError;
-
-private:
-
- /// Notify the remote to release the given JITSymbol.
- void releaseRemoteSymbol(RemoteSymbolId Id) {
- if (auto Err = Remote.template callB<ReleaseRemoteSymbol>(Id))
- ReportError(std::move(Err));
- }
-
- /// Notify the remote to materialize the JITSymbol with the given Id and
- /// return its address.
- Expected<JITTargetAddress> materializeRemoteSymbol(RemoteSymbolId Id) {
- return Remote.template callB<MaterializeRemoteSymbol>(Id);
- }
-
- /// Release the JITSymbol with the given Id.
- Error handleReleaseRemoteSymbol(RemoteSymbolId Id) {
- auto SI = InUseSymbols.find(Id);
- if (SI != InUseSymbols.end()) {
- InUseSymbols.erase(SI);
- return Error::success();
- } else
- return teeLog(badRemoteSymbolIdError(Id));
- }
-
- /// Run the materializer for the JITSymbol with the given Id and return its
- /// address.
- Expected<JITTargetAddress> handleMaterializeRemoteSymbol(RemoteSymbolId Id) {
- auto SI = InUseSymbols.find(Id);
- if (SI != InUseSymbols.end()) {
- auto AddrOrErr = SI->second.getAddress();
- InUseSymbols.erase(SI);
- SymbolIdMgr.release(Id);
- if (AddrOrErr)
- return *AddrOrErr;
- else
- return teeLog(AddrOrErr.takeError());
- } else {
- return teeLog(badRemoteSymbolIdError(Id));
- }
- }
-
- remote::ResourceIdMgr SymbolIdMgr;
- std::map<RemoteSymbolId, JITSymbol> InUseSymbols;
-};
-
-/// RemoteObjectClientLayer forwards the ORC Object Layer API over an RPC
-/// connection.
-///
-/// This class can be used as the base layer of a JIT stack on the client and
-/// will forward operations to a corresponding RemoteObjectServerLayer on the
-/// server (which can be composed on top of a "real" object layer like
-/// RTDyldObjectLinkingLayer to actually carry out the operations).
-///
-/// Sending relocatable objects to the server (rather than fully relocated
-/// bits) allows JIT'd code to be cached on the server side and re-used in
-/// subsequent JIT sessions.
-template <typename RPCEndpoint>
-class RemoteObjectClientLayer : public RemoteObjectLayer<RPCEndpoint> {
-private:
-
- using AddObject = RemoteObjectLayerAPI::AddObject;
- using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
- using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
- using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
- using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
- using Lookup = RemoteObjectLayerAPI::Lookup;
- using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
-
- using RemoteObjectLayer<RPCEndpoint>::teeLog;
- using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
- using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
-
-public:
-
- using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
- using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
-
- using ObjectPtr = std::unique_ptr<MemoryBuffer>;
-
- /// Create a RemoteObjectClientLayer that communicates with a
- /// RemoteObjectServerLayer instance via the given RPCEndpoint.
- ///
- /// The ReportError functor can be used locally log errors that are intended
- /// to be sent sent
- LLVM_ATTRIBUTE_DEPRECATED(
- RemoteObjectClientLayer(RPCEndpoint &Remote,
- std::function<void(Error)> ReportError),
- "ORCv1 layers (including RemoteObjectClientLayer) are deprecated. Please "
- "use "
- "ORCv2 (see docs/ORCv2.rst)");
-
- RemoteObjectClientLayer(ORCv1DeprecationAcknowledgement, RPCEndpoint &Remote,
- std::function<void(Error)> ReportError)
- : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {
- using ThisT = RemoteObjectClientLayer<RPCEndpoint>;
- Remote.template addHandler<Lookup>(*this, &ThisT::lookup);
- Remote.template addHandler<LookupInLogicalDylib>(
- *this, &ThisT::lookupInLogicalDylib);
- }
-
- /// Add an object to the JIT.
- ///
- /// @return A handle that can be used to refer to the loaded object (for
- /// symbol searching, finalization, freeing memory, etc.).
- Expected<ObjHandleT>
- addObject(ObjectPtr ObjBuffer,
- std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
- if (auto HandleOrErr =
- this->Remote.template callB<AddObject>(ObjBuffer->getBuffer())) {
- auto &Handle = *HandleOrErr;
- // FIXME: Return an error for this:
- assert(!Resolvers.count(Handle) && "Handle already in use?");
- Resolvers[Handle] = std::move(Resolver);
- return Handle;
- } else
- return HandleOrErr.takeError();
- }
-
- /// Remove the given object from the JIT.
- Error removeObject(ObjHandleT H) {
- return this->Remote.template callB<RemoveObject>(H);
- }
-
- /// Search for the given named symbol.
- JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- return remoteToJITSymbol(
- this->Remote.template callB<FindSymbol>(Name,
- ExportedSymbolsOnly));
- }
-
- /// Search for the given named symbol within the given context.
- JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) {
- return remoteToJITSymbol(
- this->Remote.template callB<FindSymbolIn>(H, Name,
- ExportedSymbolsOnly));
- }
-
- /// Immediately emit and finalize the object with the given handle.
- Error emitAndFinalize(ObjHandleT H) {
- return this->Remote.template callB<EmitAndFinalize>(H);
- }
-
-private:
-
- Expected<RemoteSymbol> lookup(ObjHandleT H, const std::string &Name) {
- auto RI = Resolvers.find(H);
- if (RI != Resolvers.end()) {
- return this->jitSymbolToRemote(RI->second->findSymbol(Name));
- } else
- return teeLog(badObjectHandleError(H));
- }
-
- Expected<RemoteSymbol> lookupInLogicalDylib(ObjHandleT H,
- const std::string &Name) {
- auto RI = Resolvers.find(H);
- if (RI != Resolvers.end())
- return this->jitSymbolToRemote(
- RI->second->findSymbolInLogicalDylib(Name));
- else
- return teeLog(badObjectHandleError(H));
- }
-
- std::map<remote::ResourceIdMgr::ResourceId,
- std::shared_ptr<LegacyJITSymbolResolver>>
- Resolvers;
-};
-
-/// RemoteObjectServerLayer acts as a server and handling RPC calls for the
-/// object layer API from the given RPC connection.
-///
-/// This class can be composed on top of a 'real' object layer (e.g.
-/// RTDyldObjectLinkingLayer) to do the actual work of relocating objects
-/// and making them executable.
-template <typename BaseLayerT, typename RPCEndpoint>
-class RemoteObjectServerLayer : public RemoteObjectLayer<RPCEndpoint> {
-private:
-
- using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
- using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
-
- using AddObject = RemoteObjectLayerAPI::AddObject;
- using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
- using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
- using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
- using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
- using Lookup = RemoteObjectLayerAPI::Lookup;
- using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
-
- using RemoteObjectLayer<RPCEndpoint>::teeLog;
- using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
- using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
-
-public:
-
- /// Create a RemoteObjectServerLayer with the given base layer (which must be
- /// an object layer), RPC endpoint, and error reporter function.
- LLVM_ATTRIBUTE_DEPRECATED(
- RemoteObjectServerLayer(BaseLayerT &BaseLayer, RPCEndpoint &Remote,
- std::function<void(Error)> ReportError),
- "ORCv1 layers (including RemoteObjectServerLayer) are deprecated. Please "
- "use "
- "ORCv2 (see docs/ORCv2.rst)");
-
- RemoteObjectServerLayer(ORCv1DeprecationAcknowledgement,
- BaseLayerT &BaseLayer, RPCEndpoint &Remote,
- std::function<void(Error)> ReportError)
- : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),
- BaseLayer(BaseLayer), HandleIdMgr(1) {
- using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;
-
- Remote.template addHandler<AddObject>(*this, &ThisT::addObject);
- Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);
- Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);
- Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);
- Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);
- }
-
-private:
-
- class StringMemoryBuffer : public MemoryBuffer {
- public:
- StringMemoryBuffer(std::string Buffer)
- : Buffer(std::move(Buffer)) {
- init(this->Buffer.data(), this->Buffer.data() + this->Buffer.size(),
- false);
- }
-
- BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }
- private:
- std::string Buffer;
- };
-
- JITSymbol lookup(ObjHandleT Id, const std::string &Name) {
- return remoteToJITSymbol(
- this->Remote.template callB<Lookup>(Id, Name));
- }
-
- JITSymbol lookupInLogicalDylib(ObjHandleT Id, const std::string &Name) {
- return remoteToJITSymbol(
- this->Remote.template callB<LookupInLogicalDylib>(Id, Name));
- }
-
- Expected<ObjHandleT> addObject(std::string ObjBuffer) {
- auto Buffer = std::make_unique<StringMemoryBuffer>(std::move(ObjBuffer));
- auto Id = HandleIdMgr.getNext();
- assert(!BaseLayerHandles.count(Id) && "Id already in use?");
-
- auto Resolver = createLambdaResolver(
- AcknowledgeORCv1Deprecation,
- [this, Id](const std::string &Name) { return lookup(Id, Name); },
- [this, Id](const std::string &Name) {
- return lookupInLogicalDylib(Id, Name);
- });
-
- if (auto HandleOrErr =
- BaseLayer.addObject(std::move(Buffer), std::move(Resolver))) {
- BaseLayerHandles[Id] = std::move(*HandleOrErr);
- return Id;
- } else
- return teeLog(HandleOrErr.takeError());
- }
-
- Error removeObject(ObjHandleT H) {
- auto HI = BaseLayerHandles.find(H);
- if (HI != BaseLayerHandles.end()) {
- if (auto Err = BaseLayer.removeObject(HI->second))
- return teeLog(std::move(Err));
- return Error::success();
- } else
- return teeLog(badObjectHandleError(H));
- }
-
- Expected<RemoteSymbol> findSymbol(const std::string &Name,
- bool ExportedSymbolsOnly) {
- if (auto Sym = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
- return this->jitSymbolToRemote(std::move(Sym));
- else if (auto Err = Sym.takeError())
- return teeLog(std::move(Err));
- return this->nullRemoteSymbol();
- }
-
- Expected<RemoteSymbol> findSymbolIn(ObjHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
- auto HI = BaseLayerHandles.find(H);
- if (HI != BaseLayerHandles.end()) {
- if (auto Sym = BaseLayer.findSymbolIn(HI->second, Name, ExportedSymbolsOnly))
- return this->jitSymbolToRemote(std::move(Sym));
- else if (auto Err = Sym.takeError())
- return teeLog(std::move(Err));
- return this->nullRemoteSymbol();
- } else
- return teeLog(badObjectHandleError(H));
- }
-
- Error emitAndFinalize(ObjHandleT H) {
- auto HI = BaseLayerHandles.find(H);
- if (HI != BaseLayerHandles.end()) {
- if (auto Err = BaseLayer.emitAndFinalize(HI->second))
- return teeLog(std::move(Err));
- return Error::success();
- } else
- return teeLog(badObjectHandleError(H));
- }
-
- BaseLayerT &BaseLayer;
- remote::ResourceIdMgr HandleIdMgr;
- std::map<ObjHandleT, typename BaseLayerT::ObjHandleT> BaseLayerHandles;
-};
-
-template <typename RPCEndpoint>
-RemoteObjectClientLayer<RPCEndpoint>::RemoteObjectClientLayer(
- RPCEndpoint &Remote, std::function<void(Error)> ReportError)
- : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {
- using ThisT = RemoteObjectClientLayer<RPCEndpoint>;
- Remote.template addHandler<Lookup>(*this, &ThisT::lookup);
- Remote.template addHandler<LookupInLogicalDylib>(
- *this, &ThisT::lookupInLogicalDylib);
-}
-
-template <typename BaseLayerT, typename RPCEndpoint>
-RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>::RemoteObjectServerLayer(
- BaseLayerT &BaseLayer, RPCEndpoint &Remote,
- std::function<void(Error)> ReportError)
- : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),
- BaseLayer(BaseLayer), HandleIdMgr(1) {
- using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;
-
- Remote.template addHandler<AddObject>(*this, &ThisT::addObject);
- Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);
- Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);
- Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);
- Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);
-}
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h
new file mode 100644
index 000000000000..3f96fe3da49d
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h
@@ -0,0 +1,79 @@
+//===- FDRawByteChannel.h - File descriptor based byte-channel -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// File descriptor based RawByteChannel.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+namespace llvm {
+namespace orc {
+namespace shared {
+
+/// Serialization channel that reads from and writes from file descriptors.
+class FDRawByteChannel final : public RawByteChannel {
+public:
+ FDRawByteChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}
+
+ llvm::Error readBytes(char *Dst, unsigned Size) override {
+ assert(Dst && "Attempt to read into null.");
+ ssize_t Completed = 0;
+ while (Completed < static_cast<ssize_t>(Size)) {
+ ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed);
+ if (Read <= 0) {
+ auto ErrNo = errno;
+ if (ErrNo == EAGAIN || ErrNo == EINTR)
+ continue;
+ else
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
+ Completed += Read;
+ }
+ return llvm::Error::success();
+ }
+
+ llvm::Error appendBytes(const char *Src, unsigned Size) override {
+ assert(Src && "Attempt to append from null.");
+ ssize_t Completed = 0;
+ while (Completed < static_cast<ssize_t>(Size)) {
+ ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed);
+ if (Written < 0) {
+ auto ErrNo = errno;
+ if (ErrNo == EAGAIN || ErrNo == EINTR)
+ continue;
+ else
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
+ Completed += Written;
+ }
+ return llvm::Error::success();
+ }
+
+ llvm::Error send() override { return llvm::Error::success(); }
+
+private:
+ int InFD, OutFD;
+};
+
+} // namespace shared
+} // namespace orc
+} // namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h
index 9b0d941f5459..9b0d941f5459 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
index f348844f39ce..e0ac640ebcdd 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
@@ -14,23 +14,23 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
-#define LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
#include <map>
#include <thread>
#include <vector>
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ExecutionEngine/Orc/OrcError.h"
-#include "llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
+#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
#include <future>
namespace llvm {
namespace orc {
-namespace rpc {
+namespace shared {
/// Base class of all fatal RPC errors (those that necessarily result in the
/// termination of the RPC session).
@@ -56,7 +56,7 @@ public:
/// function id it cannot parse the call.
template <typename FnIdT, typename SeqNoT>
class BadFunctionCall
- : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
+ : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
public:
static char ID;
@@ -68,8 +68,10 @@ public:
}
void log(raw_ostream &OS) const override {
- OS << "Call to invalid RPC function id '" << FnId << "' with "
- "sequence number " << SeqNo;
+ OS << "Call to invalid RPC function id '" << FnId
+ << "' with "
+ "sequence number "
+ << SeqNo;
}
private:
@@ -89,12 +91,12 @@ char BadFunctionCall<FnIdT, SeqNoT>::ID = 0;
/// a result parser for this sequence number it can't do that.
template <typename SeqNoT>
class InvalidSequenceNumberForResponse
- : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>, RPCFatalError> {
+ : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>,
+ RPCFatalError> {
public:
static char ID;
- InvalidSequenceNumberForResponse(SeqNoT SeqNo)
- : SeqNo(std::move(SeqNo)) {}
+ InvalidSequenceNumberForResponse(SeqNoT SeqNo) : SeqNo(std::move(SeqNo)) {}
std::error_code convertToErrorCode() const override {
return orcError(OrcErrorCode::UnexpectedRPCCall);
@@ -103,6 +105,7 @@ public:
void log(raw_ostream &OS) const override {
OS << "Response has unknown sequence number " << SeqNo;
}
+
private:
SeqNoT SeqNo;
};
@@ -131,17 +134,18 @@ public:
std::error_code convertToErrorCode() const override;
void log(raw_ostream &OS) const override;
const std::string &getSignature() const { return Signature; }
+
private:
std::string Signature;
};
-template <typename DerivedFunc, typename FnT> class Function;
+template <typename DerivedFunc, typename FnT> class RPCFunction;
// RPC Function class.
// DerivedFunc should be a user defined class with a static 'getName()' method
// returning a const char* representing the function's name.
template <typename DerivedFunc, typename RetT, typename... ArgTs>
-class Function<DerivedFunc, RetT(ArgTs...)> {
+class RPCFunction<DerivedFunc, RetT(ArgTs...)> {
public:
/// User defined function type.
using Type = RetT(ArgTs...);
@@ -154,8 +158,9 @@ public:
static std::string Name = [] {
std::string Name;
raw_string_ostream(Name)
- << RPCTypeName<RetT>::getName() << " " << DerivedFunc::getName()
- << "(" << llvm::orc::rpc::RPCTypeNameSequence<ArgTs...>() << ")";
+ << SerializationTypeName<RetT>::getName() << " "
+ << DerivedFunc::getName() << "("
+ << SerializationTypeNameSequence<ArgTs...>() << ")";
return Name;
}();
return Name.data();
@@ -199,10 +204,10 @@ private:
namespace detail {
/// Provides a typedef for a tuple containing the decayed argument types.
-template <typename T> class FunctionArgsTuple;
+template <typename T> class RPCFunctionArgsTuple;
template <typename RetT, typename... ArgTs>
-class FunctionArgsTuple<RetT(ArgTs...)> {
+class RPCFunctionArgsTuple<RetT(ArgTs...)> {
public:
using Type = std::tuple<std::decay_t<std::remove_reference_t<ArgTs>>...>;
};
@@ -287,34 +292,28 @@ class ResultTraits<Expected<RetT>> : public ResultTraits<RetT> {};
// Determines whether an RPC function's defined error return type supports
// error return value.
-template <typename T>
-class SupportsErrorReturn {
+template <typename T> class SupportsErrorReturn {
public:
static const bool value = false;
};
-template <>
-class SupportsErrorReturn<Error> {
+template <> class SupportsErrorReturn<Error> {
public:
static const bool value = true;
};
-template <typename T>
-class SupportsErrorReturn<Expected<T>> {
+template <typename T> class SupportsErrorReturn<Expected<T>> {
public:
static const bool value = true;
};
// RespondHelper packages return values based on whether or not the declared
// RPC function return type supports error returns.
-template <bool FuncSupportsErrorReturn>
-class RespondHelper;
+template <bool FuncSupportsErrorReturn> class RespondHelper;
// RespondHelper specialization for functions that support error returns.
-template <>
-class RespondHelper<true> {
+template <> class RespondHelper<true> {
public:
-
// Send Expected<T>.
template <typename WireRetT, typename HandlerRetT, typename ChannelT,
typename FunctionIdT, typename SequenceNumberT>
@@ -330,9 +329,8 @@ public:
// Serialize the result.
if (auto Err =
- SerializationTraits<ChannelT, WireRetT,
- Expected<HandlerRetT>>::serialize(
- C, std::move(ResultOrErr)))
+ SerializationTraits<ChannelT, WireRetT, Expected<HandlerRetT>>::
+ serialize(C, std::move(ResultOrErr)))
return Err;
// Close the response message.
@@ -354,14 +352,11 @@ public:
return Err2;
return C.send();
}
-
};
// RespondHelper specialization for functions that do not support error returns.
-template <>
-class RespondHelper<false> {
+template <> class RespondHelper<false> {
public:
-
template <typename WireRetT, typename HandlerRetT, typename ChannelT,
typename FunctionIdT, typename SequenceNumberT>
static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
@@ -376,8 +371,8 @@ public:
// Serialize the result.
if (auto Err =
- SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
- C, *ResultOrErr))
+ SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
+ C, *ResultOrErr))
return Err;
// End the response message.
@@ -398,18 +393,17 @@ public:
return Err2;
return C.send();
}
-
};
-
// Send a response of the given wire return type (WireRetT) over the
// channel, with the given sequence number.
template <typename WireRetT, typename HandlerRetT, typename ChannelT,
typename FunctionIdT, typename SequenceNumberT>
-Error respond(ChannelT &C, const FunctionIdT &ResponseId,
- SequenceNumberT SeqNo, Expected<HandlerRetT> ResultOrErr) {
+Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
+ Expected<HandlerRetT> ResultOrErr) {
return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
- template sendResult<WireRetT>(C, ResponseId, SeqNo, std::move(ResultOrErr));
+ template sendResult<WireRetT>(C, ResponseId, SeqNo,
+ std::move(ResultOrErr));
}
// Send an empty response message on the given channel to indicate that
@@ -418,8 +412,8 @@ template <typename WireRetT, typename ChannelT, typename FunctionIdT,
typename SequenceNumberT>
Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
Error Err) {
- return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
- sendResult(C, ResponseId, SeqNo, std::move(Err));
+ return RespondHelper<SupportsErrorReturn<WireRetT>::value>::sendResult(
+ C, ResponseId, SeqNo, std::move(Err));
}
// Converts a given type to the equivalent error return type.
@@ -453,7 +447,8 @@ public:
template <typename FnT> class AsyncHandlerTraits;
template <typename ResultT, typename... ArgTs>
-class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>, ArgTs...)> {
+class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>,
+ ArgTs...)> {
public:
using Type = Error(ArgTs...);
using ResultType = Expected<ResultT>;
@@ -490,9 +485,9 @@ class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)>
// specialized for function types) and inherits from the appropriate
// speciilization for the given non-function type's call operator.
template <typename HandlerT>
-class HandlerTraits : public HandlerTraits<decltype(
- &std::remove_reference<HandlerT>::type::operator())> {
-};
+class HandlerTraits
+ : public HandlerTraits<
+ decltype(&std::remove_reference<HandlerT>::type::operator())> {};
// Traits for handlers with a given function type.
template <typename RetT, typename... ArgTs>
@@ -524,7 +519,7 @@ public:
template <typename HandlerT>
static std::enable_if_t<
std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value, Error>
- run(HandlerT &Handler, ArgTs &&... Args) {
+ run(HandlerT &Handler, ArgTs &&...Args) {
Handler(std::move(Args)...);
return Error::success();
}
@@ -577,8 +572,8 @@ private:
// Handler traits for free functions.
template <typename RetT, typename... ArgTs>
-class HandlerTraits<RetT(*)(ArgTs...)>
- : public HandlerTraits<RetT(ArgTs...)> {};
+class HandlerTraits<RetT (*)(ArgTs...)> : public HandlerTraits<RetT(ArgTs...)> {
+};
// Handler traits for class methods (especially call operators for lambdas).
template <typename Class, typename RetT, typename... ArgTs>
@@ -714,9 +709,8 @@ public:
typename HandlerTraits<HandlerT>::Type>::ArgType;
HandlerArgType Result((typename HandlerArgType::value_type()));
- if (auto Err =
- SerializationTraits<ChannelT, Expected<FuncRetT>,
- HandlerArgType>::deserialize(C, Result))
+ if (auto Err = SerializationTraits<ChannelT, Expected<FuncRetT>,
+ HandlerArgType>::deserialize(C, Result))
return Err;
if (auto Err = C.endReceiveMessage())
return Err;
@@ -786,7 +780,7 @@ public:
using MethodT = RetT (ClassT::*)(ArgTs...);
MemberFnWrapper(ClassT &Instance, MethodT Method)
: Instance(Instance), Method(Method) {}
- RetT operator()(ArgTs &&... Args) {
+ RetT operator()(ArgTs &&...Args) {
return (Instance.*Method)(std::move(Args)...);
}
@@ -804,10 +798,9 @@ public:
template <typename ArgT, typename... ArgTs>
class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {
public:
- ReadArgs(ArgT &Arg, ArgTs &... Args)
- : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
+ ReadArgs(ArgT &Arg, ArgTs &...Args) : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
- Error operator()(ArgT &ArgVal, ArgTs &... ArgVals) {
+ Error operator()(ArgT &ArgVal, ArgTs &...ArgVals) {
this->Arg = std::move(ArgVal);
return ReadArgs<ArgTs...>::operator()(ArgVals...);
}
@@ -872,8 +865,8 @@ public:
template <template <class, class> class P, typename T1Sig, typename T2Sig>
class RPCArgTypeCheck {
public:
- using T1Tuple = typename FunctionArgsTuple<T1Sig>::Type;
- using T2Tuple = typename FunctionArgsTuple<T2Sig>::Type;
+ using T1Tuple = typename RPCFunctionArgsTuple<T1Sig>::Type;
+ using T2Tuple = typename RPCFunctionArgsTuple<T2Sig>::Type;
static_assert(std::tuple_size<T1Tuple>::value >=
std::tuple_size<T2Tuple>::value,
@@ -937,18 +930,18 @@ template <typename ImplT, typename ChannelT, typename FunctionIdT,
typename SequenceNumberT>
class RPCEndpointBase {
protected:
- class OrcRPCInvalid : public Function<OrcRPCInvalid, void()> {
+ class OrcRPCInvalid : public RPCFunction<OrcRPCInvalid, void()> {
public:
static const char *getName() { return "__orc_rpc$invalid"; }
};
- class OrcRPCResponse : public Function<OrcRPCResponse, void()> {
+ class OrcRPCResponse : public RPCFunction<OrcRPCResponse, void()> {
public:
static const char *getName() { return "__orc_rpc$response"; }
};
class OrcRPCNegotiate
- : public Function<OrcRPCNegotiate, FunctionIdT(std::string)> {
+ : public RPCFunction<OrcRPCNegotiate, FunctionIdT(std::string)> {
public:
static const char *getName() { return "__orc_rpc$negotiate"; }
};
@@ -994,7 +987,6 @@ public:
[this](const std::string &Name) { return handleNegotiate(Name); });
}
-
/// Negotiate a function id for Func with the other end of the channel.
template <typename Func> Error negotiateFunction(bool Retry = false) {
return getRemoteFunctionId<Func>(true, Retry).takeError();
@@ -1006,7 +998,7 @@ public:
/// or an Error (if Func::ReturnType is void). The handler will be called
/// with an error if the return value is abandoned due to a channel error.
template <typename Func, typename HandlerT, typename... ArgTs>
- Error appendCallAsync(HandlerT Handler, const ArgTs &... Args) {
+ Error appendCallAsync(HandlerT Handler, const ArgTs &...Args) {
static_assert(
detail::RPCArgTypeCheck<CanSerializeCheck, typename Func::Type,
@@ -1036,8 +1028,8 @@ public:
// Install the user handler.
PendingResponses[SeqNo] =
- detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
- std::move(Handler));
+ detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
+ std::move(Handler));
}
// Open the function call message.
@@ -1065,7 +1057,7 @@ public:
Error sendAppendedCalls() { return C.send(); };
template <typename Func, typename HandlerT, typename... ArgTs>
- Error callAsync(HandlerT Handler, const ArgTs &... Args) {
+ Error callAsync(HandlerT Handler, const ArgTs &...Args) {
if (auto Err = appendCallAsync<Func>(std::move(Handler), Args...))
return Err;
return C.send();
@@ -1104,7 +1096,7 @@ public:
/// /* Handle Args */ ;
///
template <typename... ArgTs>
- static detail::ReadArgs<ArgTs...> readArgs(ArgTs &... Args) {
+ static detail::ReadArgs<ArgTs...> readArgs(ArgTs &...Args) {
return detail::ReadArgs<ArgTs...>(Args...);
}
@@ -1128,8 +1120,7 @@ public:
/// Remove the handler for the given function.
/// A handler must currently be registered for this function.
- template <typename Func>
- void removeHandler() {
+ template <typename Func> void removeHandler() {
auto IdItr = LocalFunctionIds.find(Func::getPrototype());
assert(IdItr != LocalFunctionIds.end() &&
"Function does not have a registered handler");
@@ -1140,12 +1131,9 @@ public:
}
/// Clear all handlers.
- void clearHandlers() {
- Handlers.clear();
- }
+ void clearHandlers() { Handlers.clear(); }
protected:
-
FunctionIdT getInvalidFunctionId() const {
return FnIdAllocator.getInvalidId();
}
@@ -1168,12 +1156,12 @@ protected:
template <typename Func, typename HandlerT>
void addAsyncHandlerImpl(HandlerT Handler) {
- static_assert(detail::RPCArgTypeCheck<
- CanDeserializeCheck, typename Func::Type,
- typename detail::AsyncHandlerTraits<
- typename detail::HandlerTraits<HandlerT>::Type
- >::Type>::value,
- "");
+ static_assert(
+ detail::RPCArgTypeCheck<
+ CanDeserializeCheck, typename Func::Type,
+ typename detail::AsyncHandlerTraits<
+ typename detail::HandlerTraits<HandlerT>::Type>::Type>::value,
+ "");
FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
LocalFunctionIds[Func::getPrototype()] = NewFnId;
@@ -1197,8 +1185,8 @@ protected:
// Unlock the pending results map to prevent recursive lock.
Lock.unlock();
abandonPendingResponses();
- return make_error<
- InvalidSequenceNumberForResponse<SequenceNumberT>>(SeqNo);
+ return make_error<InvalidSequenceNumberForResponse<SequenceNumberT>>(
+ SeqNo);
}
}
@@ -1241,7 +1229,7 @@ protected:
if (DoNegotiate) {
auto &Impl = static_cast<ImplT &>(*this);
if (auto RemoteIdOrErr =
- Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
+ Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
if (*RemoteIdOrErr == getInvalidFunctionId())
return make_error<CouldNotNegotiate>(Func::getPrototype());
@@ -1264,9 +1252,8 @@ protected:
return [this, Handler](ChannelT &Channel,
SequenceNumberT SeqNo) mutable -> Error {
// Start by deserializing the arguments.
- using ArgsTuple =
- typename detail::FunctionArgsTuple<
- typename detail::HandlerTraits<HandlerT>::Type>::Type;
+ using ArgsTuple = typename detail::RPCFunctionArgsTuple<
+ typename detail::HandlerTraits<HandlerT>::Type>::Type;
auto Args = std::make_shared<ArgsTuple>();
if (auto Err =
@@ -1298,9 +1285,9 @@ protected:
SequenceNumberT SeqNo) mutable -> Error {
// Start by deserializing the arguments.
using AHTraits = detail::AsyncHandlerTraits<
- typename detail::HandlerTraits<HandlerT>::Type>;
+ typename detail::HandlerTraits<HandlerT>::Type>;
using ArgsTuple =
- typename detail::FunctionArgsTuple<typename AHTraits::Type>::Type;
+ typename detail::RPCFunctionArgsTuple<typename AHTraits::Type>::Type;
auto Args = std::make_shared<ArgsTuple>();
if (auto Err =
@@ -1319,11 +1306,11 @@ protected:
using HTraits = detail::HandlerTraits<HandlerT>;
using FuncReturn = typename Func::ReturnType;
- auto Responder =
- [this, SeqNo](typename AHTraits::ResultType RetVal) -> Error {
- return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
- std::move(RetVal));
- };
+ auto Responder = [this,
+ SeqNo](typename AHTraits::ResultType RetVal) -> Error {
+ return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
+ std::move(RetVal));
+ };
return HTraits::unpackAndRunAsync(Handler, Responder, *Args);
};
@@ -1356,17 +1343,16 @@ class MultiThreadedRPCEndpoint
MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
ChannelT, FunctionIdT, SequenceNumberT> {
private:
- using BaseClass =
- detail::RPCEndpointBase<
- MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT>;
+ using BaseClass = detail::RPCEndpointBase<
+ MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT>;
public:
MultiThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
: BaseClass(C, LazyAutoNegotiation) {}
/// Add a handler for the given RPC function.
- /// This installs the given handler functor for the given RPC Function, and
+ /// This installs the given handler functor for the given RPCFunction, and
/// makes the RPC function available for negotiation/calling from the remote.
template <typename Func, typename HandlerT>
void addHandler(HandlerT Handler) {
@@ -1377,7 +1363,7 @@ public:
template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
addHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
}
template <typename Func, typename HandlerT>
@@ -1389,7 +1375,7 @@ public:
template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
addAsyncHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
}
/// Return type for non-blocking call primitives.
@@ -1405,7 +1391,7 @@ public:
/// result. In multi-threaded mode the appendCallNB method, which does not
/// return the sequence numeber, should be preferred.
template <typename Func, typename... ArgTs>
- Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &... Args) {
+ Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &...Args) {
using RTraits = detail::ResultTraits<typename Func::ReturnType>;
using ErrorReturn = typename RTraits::ErrorReturnType;
using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
@@ -1428,7 +1414,7 @@ public:
/// The same as appendCallNBWithSeq, except that it calls C.send() to
/// flush the channel after serializing the call.
template <typename Func, typename... ArgTs>
- Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &... Args) {
+ Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &...Args) {
auto Result = appendCallNB<Func>(Args...);
if (!Result)
return Result;
@@ -1449,7 +1435,7 @@ public:
template <typename Func, typename... ArgTs,
typename AltRetT = typename Func::ReturnType>
typename detail::ResultTraits<AltRetT>::ErrorReturnType
- callB(const ArgTs &... Args) {
+ callB(const ArgTs &...Args) {
if (auto FutureResOrErr = callNB<Func>(Args...))
return FutureResOrErr->get();
else
@@ -1472,10 +1458,9 @@ class SingleThreadedRPCEndpoint
SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
ChannelT, FunctionIdT, SequenceNumberT> {
private:
- using BaseClass =
- detail::RPCEndpointBase<
- SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT>;
+ using BaseClass = detail::RPCEndpointBase<
+ SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT>;
public:
SingleThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
@@ -1501,13 +1486,13 @@ public:
template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
addAsyncHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
}
template <typename Func, typename... ArgTs,
typename AltRetT = typename Func::ReturnType>
typename detail::ResultTraits<AltRetT>::ErrorReturnType
- callB(const ArgTs &... Args) {
+ callB(const ArgTs &...Args) {
bool ReceivedResponse = false;
using ResultType = typename detail::ResultTraits<AltRetT>::ErrorReturnType;
auto Result = detail::ResultTraits<AltRetT>::createBlankErrorReturnValue();
@@ -1547,13 +1532,12 @@ public:
};
/// Asynchronous dispatch for a function on an RPC endpoint.
-template <typename RPCClass, typename Func>
-class RPCAsyncDispatch {
+template <typename RPCClass, typename Func> class RPCAsyncDispatch {
public:
RPCAsyncDispatch(RPCClass &Endpoint) : Endpoint(Endpoint) {}
template <typename HandlerT, typename... ArgTs>
- Error operator()(HandlerT Handler, const ArgTs &... Args) const {
+ Error operator()(HandlerT Handler, const ArgTs &...Args) const {
return Endpoint.template appendCallAsync<Func>(std::move(Handler), Args...);
}
@@ -1571,7 +1555,6 @@ RPCAsyncDispatch<RPCEndpointT, Func> rpcAsyncDispatch(RPCEndpointT &Endpoint) {
/// waited on as a group.
class ParallelCallGroup {
public:
-
ParallelCallGroup() = default;
ParallelCallGroup(const ParallelCallGroup &) = delete;
ParallelCallGroup &operator=(const ParallelCallGroup &) = delete;
@@ -1579,7 +1562,7 @@ public:
/// Make as asynchronous call.
template <typename AsyncDispatcher, typename HandlerT, typename... ArgTs>
Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler,
- const ArgTs &... Args) {
+ const ArgTs &...Args) {
// Increment the count of outstanding calls. This has to happen before
// we invoke the call, as the handler may (depending on scheduling)
// be run immediately on another thread, and we don't want the decrement
@@ -1618,70 +1601,57 @@ private:
uint32_t NumOutstandingCalls = 0;
};
-/// Convenience class for grouping RPC Functions into APIs that can be
+/// Convenience class for grouping RPCFunctions into APIs that can be
/// negotiated as a block.
///
-template <typename... Funcs>
-class APICalls {
+template <typename... Funcs> class APICalls {
public:
-
/// Test whether this API contains Function F.
- template <typename F>
- class Contains {
+ template <typename F> class Contains {
public:
static const bool value = false;
};
/// Negotiate all functions in this API.
- template <typename RPCEndpoint>
- static Error negotiate(RPCEndpoint &R) {
+ template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
return Error::success();
}
};
-template <typename Func, typename... Funcs>
-class APICalls<Func, Funcs...> {
+template <typename Func, typename... Funcs> class APICalls<Func, Funcs...> {
public:
-
- template <typename F>
- class Contains {
+ template <typename F> class Contains {
public:
static const bool value = std::is_same<F, Func>::value |
APICalls<Funcs...>::template Contains<F>::value;
};
- template <typename RPCEndpoint>
- static Error negotiate(RPCEndpoint &R) {
+ template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
if (auto Err = R.template negotiateFunction<Func>())
return Err;
return APICalls<Funcs...>::negotiate(R);
}
-
};
template <typename... InnerFuncs, typename... Funcs>
class APICalls<APICalls<InnerFuncs...>, Funcs...> {
public:
-
- template <typename F>
- class Contains {
+ template <typename F> class Contains {
public:
static const bool value =
- APICalls<InnerFuncs...>::template Contains<F>::value |
- APICalls<Funcs...>::template Contains<F>::value;
+ APICalls<InnerFuncs...>::template Contains<F>::value |
+ APICalls<Funcs...>::template Contains<F>::value;
};
- template <typename RPCEndpoint>
- static Error negotiate(RPCEndpoint &R) {
+ template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
if (auto Err = APICalls<InnerFuncs...>::negotiate(R))
return Err;
return APICalls<Funcs...>::negotiate(R);
}
-
};
-} // end namespace rpc
+} // end namespace shared
} // end namespace orc
} // end namespace llvm
-#endif
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
index 35745993248c..2ee471939251 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
@@ -1,4 +1,4 @@
-//===- llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h ----------------*- C++ -*-===//
+//===- RawByteChannel.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
-#define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h"
+#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
@@ -20,9 +20,9 @@
namespace llvm {
namespace orc {
-namespace rpc {
+namespace shared {
-/// Interface for byte-streams to be used with RPC.
+/// Interface for byte-streams to be used with ORC Serialization.
class RawByteChannel {
public:
virtual ~RawByteChannel() = default;
@@ -115,8 +115,7 @@ class SerializationTraits<
public:
static Error serialize(ChannelT &C, bool V) {
uint8_t Tmp = V ? 1 : 0;
- if (auto Err =
- C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
+ if (auto Err = C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
return Err;
return Error::success();
}
@@ -135,7 +134,7 @@ class SerializationTraits<
ChannelT, std::string, StringRef,
std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
public:
- /// RPC channel serialization for std::strings.
+ /// Serialization channel serialization for std::strings.
static Error serialize(RawByteChannel &C, StringRef S) {
if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
return Err;
@@ -161,13 +160,13 @@ class SerializationTraits<
ChannelT, std::string, std::string,
std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
public:
- /// RPC channel serialization for std::strings.
+ /// Serialization channel serialization for std::strings.
static Error serialize(RawByteChannel &C, const std::string &S) {
return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
S);
}
- /// RPC channel deserialization for std::strings.
+ /// Serialization channel deserialization for std::strings.
static Error deserialize(RawByteChannel &C, std::string &S) {
uint64_t Count = 0;
if (auto Err = deserializeSeq(C, Count))
@@ -177,8 +176,8 @@ public:
}
};
-} // end namespace rpc
+} // end namespace shared
} // end namespace orc
} // end namespace llvm
-#endif // LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
index 2f37ab40c7f8..f2d07632bd5d 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
@@ -1,4 +1,4 @@
-//===- llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h --------------*- C++ -*-===//
+//===- Serialization.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,10 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
-#define LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
-#include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/Support/thread.h"
#include <map>
#include <mutex>
@@ -20,118 +22,104 @@
namespace llvm {
namespace orc {
-namespace rpc {
+namespace shared {
-template <typename T>
-class RPCTypeName;
+template <typename T> class SerializationTypeName;
/// TypeNameSequence is a utility for rendering sequences of types to a string
/// by rendering each type, separated by ", ".
-template <typename... ArgTs> class RPCTypeNameSequence {};
+template <typename... ArgTs> class SerializationTypeNameSequence {};
/// Render an empty TypeNameSequence to an ostream.
template <typename OStream>
-OStream &operator<<(OStream &OS, const RPCTypeNameSequence<> &V) {
+OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<> &V) {
return OS;
}
/// Render a TypeNameSequence of a single type to an ostream.
template <typename OStream, typename ArgT>
-OStream &operator<<(OStream &OS, const RPCTypeNameSequence<ArgT> &V) {
- OS << RPCTypeName<ArgT>::getName();
+OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<ArgT> &V) {
+ OS << SerializationTypeName<ArgT>::getName();
return OS;
}
/// Render a TypeNameSequence of more than one type to an ostream.
template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
-OStream&
-operator<<(OStream &OS, const RPCTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
- OS << RPCTypeName<ArgT1>::getName() << ", "
- << RPCTypeNameSequence<ArgT2, ArgTs...>();
+OStream &
+operator<<(OStream &OS,
+ const SerializationTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
+ OS << SerializationTypeName<ArgT1>::getName() << ", "
+ << SerializationTypeNameSequence<ArgT2, ArgTs...>();
return OS;
}
-template <>
-class RPCTypeName<void> {
+template <> class SerializationTypeName<void> {
public:
- static const char* getName() { return "void"; }
+ static const char *getName() { return "void"; }
};
-template <>
-class RPCTypeName<int8_t> {
+template <> class SerializationTypeName<int8_t> {
public:
- static const char* getName() { return "int8_t"; }
+ static const char *getName() { return "int8_t"; }
};
-template <>
-class RPCTypeName<uint8_t> {
+template <> class SerializationTypeName<uint8_t> {
public:
- static const char* getName() { return "uint8_t"; }
+ static const char *getName() { return "uint8_t"; }
};
-template <>
-class RPCTypeName<int16_t> {
+template <> class SerializationTypeName<int16_t> {
public:
- static const char* getName() { return "int16_t"; }
+ static const char *getName() { return "int16_t"; }
};
-template <>
-class RPCTypeName<uint16_t> {
+template <> class SerializationTypeName<uint16_t> {
public:
- static const char* getName() { return "uint16_t"; }
+ static const char *getName() { return "uint16_t"; }
};
-template <>
-class RPCTypeName<int32_t> {
+template <> class SerializationTypeName<int32_t> {
public:
- static const char* getName() { return "int32_t"; }
+ static const char *getName() { return "int32_t"; }
};
-template <>
-class RPCTypeName<uint32_t> {
+template <> class SerializationTypeName<uint32_t> {
public:
- static const char* getName() { return "uint32_t"; }
+ static const char *getName() { return "uint32_t"; }
};
-template <>
-class RPCTypeName<int64_t> {
+template <> class SerializationTypeName<int64_t> {
public:
- static const char* getName() { return "int64_t"; }
+ static const char *getName() { return "int64_t"; }
};
-template <>
-class RPCTypeName<uint64_t> {
+template <> class SerializationTypeName<uint64_t> {
public:
- static const char* getName() { return "uint64_t"; }
+ static const char *getName() { return "uint64_t"; }
};
-template <>
-class RPCTypeName<bool> {
+template <> class SerializationTypeName<bool> {
public:
- static const char* getName() { return "bool"; }
+ static const char *getName() { return "bool"; }
};
-template <>
-class RPCTypeName<std::string> {
+template <> class SerializationTypeName<std::string> {
public:
- static const char* getName() { return "std::string"; }
+ static const char *getName() { return "std::string"; }
};
-template <>
-class RPCTypeName<Error> {
+template <> class SerializationTypeName<Error> {
public:
- static const char* getName() { return "Error"; }
+ static const char *getName() { return "Error"; }
};
-template <typename T>
-class RPCTypeName<Expected<T>> {
+template <typename T> class SerializationTypeName<Expected<T>> {
public:
- static const char* getName() {
+ static const char *getName() {
static std::string Name = [] {
std::string Name;
- raw_string_ostream(Name) << "Expected<"
- << RPCTypeNameSequence<T>()
- << ">";
+ raw_string_ostream(Name)
+ << "Expected<" << SerializationTypeNameSequence<T>() << ">";
return Name;
}();
return Name.data();
@@ -139,67 +127,78 @@ public:
};
template <typename T1, typename T2>
-class RPCTypeName<std::pair<T1, T2>> {
+class SerializationTypeName<std::pair<T1, T2>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "std::pair<" << SerializationTypeNameSequence<T1, T2>() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+template <typename... ArgTs> class SerializationTypeName<std::tuple<ArgTs...>> {
public:
- static const char* getName() {
+ static const char *getName() {
static std::string Name = [] {
std::string Name;
- raw_string_ostream(Name) << "std::pair<" << RPCTypeNameSequence<T1, T2>()
- << ">";
+ raw_string_ostream(Name)
+ << "std::tuple<" << SerializationTypeNameSequence<ArgTs...>() << ">";
return Name;
}();
return Name.data();
}
};
-template <typename... ArgTs>
-class RPCTypeName<std::tuple<ArgTs...>> {
+template <typename T> class SerializationTypeName<Optional<T>> {
public:
- static const char* getName() {
+ static const char *getName() {
static std::string Name = [] {
std::string Name;
- raw_string_ostream(Name) << "std::tuple<"
- << RPCTypeNameSequence<ArgTs...>() << ">";
+ raw_string_ostream(Name)
+ << "Optional<" << SerializationTypeName<T>::getName() << ">";
return Name;
}();
return Name.data();
}
};
-template <typename T>
-class RPCTypeName<std::vector<T>> {
+template <typename T> class SerializationTypeName<std::vector<T>> {
public:
- static const char*getName() {
+ static const char *getName() {
static std::string Name = [] {
std::string Name;
- raw_string_ostream(Name) << "std::vector<" << RPCTypeName<T>::getName()
- << ">";
+ raw_string_ostream(Name)
+ << "std::vector<" << SerializationTypeName<T>::getName() << ">";
return Name;
}();
return Name.data();
}
};
-template <typename T> class RPCTypeName<std::set<T>> {
+template <typename T> class SerializationTypeName<std::set<T>> {
public:
static const char *getName() {
static std::string Name = [] {
std::string Name;
raw_string_ostream(Name)
- << "std::set<" << RPCTypeName<T>::getName() << ">";
+ << "std::set<" << SerializationTypeName<T>::getName() << ">";
return Name;
}();
return Name.data();
}
};
-template <typename K, typename V> class RPCTypeName<std::map<K, V>> {
+template <typename K, typename V> class SerializationTypeName<std::map<K, V>> {
public:
static const char *getName() {
static std::string Name = [] {
std::string Name;
raw_string_ostream(Name)
- << "std::map<" << RPCTypeNameSequence<K, V>() << ">";
+ << "std::map<" << SerializationTypeNameSequence<K, V>() << ">";
return Name;
}();
return Name.data();
@@ -242,8 +241,7 @@ template <typename ChannelT, typename WireType,
typename ConcreteType = WireType, typename = void>
class SerializationTraits;
-template <typename ChannelT>
-class SequenceTraits {
+template <typename ChannelT> class SequenceTraits {
public:
static Error emitSeparator(ChannelT &C) { return Error::success(); }
static Error consumeSeparator(ChannelT &C) { return Error::success(); }
@@ -258,11 +256,9 @@ public:
/// is a SerializationTraits specialization
/// SerializeTraits<ChannelT, ArgT, CArgT> with methods that can serialize the
/// caller argument to over-the-wire value.
-template <typename ChannelT, typename... ArgTs>
-class SequenceSerialization;
+template <typename ChannelT, typename... ArgTs> class SequenceSerialization;
-template <typename ChannelT>
-class SequenceSerialization<ChannelT> {
+template <typename ChannelT> class SequenceSerialization<ChannelT> {
public:
static Error serialize(ChannelT &C) { return Error::success(); }
static Error deserialize(ChannelT &C) { return Error::success(); }
@@ -271,15 +267,12 @@ public:
template <typename ChannelT, typename ArgT>
class SequenceSerialization<ChannelT, ArgT> {
public:
-
- template <typename CArgT>
- static Error serialize(ChannelT &C, CArgT &&CArg) {
+ template <typename CArgT> static Error serialize(ChannelT &C, CArgT &&CArg) {
return SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
C, std::forward<CArgT>(CArg));
}
- template <typename CArgT>
- static Error deserialize(ChannelT &C, CArgT &CArg) {
+ template <typename CArgT> static Error deserialize(ChannelT &C, CArgT &CArg) {
return SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg);
}
};
@@ -287,25 +280,22 @@ public:
template <typename ChannelT, typename ArgT, typename... ArgTs>
class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
public:
-
template <typename CArgT, typename... CArgTs>
- static Error serialize(ChannelT &C, CArgT &&CArg,
- CArgTs &&... CArgs) {
+ static Error serialize(ChannelT &C, CArgT &&CArg, CArgTs &&...CArgs) {
if (auto Err =
SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
C, std::forward<CArgT>(CArg)))
return Err;
if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
return Err;
- return SequenceSerialization<ChannelT, ArgTs...>::
- serialize(C, std::forward<CArgTs>(CArgs)...);
+ return SequenceSerialization<ChannelT, ArgTs...>::serialize(
+ C, std::forward<CArgTs>(CArgs)...);
}
template <typename CArgT, typename... CArgTs>
- static Error deserialize(ChannelT &C, CArgT &CArg,
- CArgTs &... CArgs) {
+ static Error deserialize(ChannelT &C, CArgT &CArg, CArgTs &...CArgs) {
if (auto Err =
- SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
+ SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
return Err;
if (auto Err = SequenceTraits<ChannelT>::consumeSeparator(C))
return Err;
@@ -314,25 +304,23 @@ public:
};
template <typename ChannelT, typename... ArgTs>
-Error serializeSeq(ChannelT &C, ArgTs &&... Args) {
+Error serializeSeq(ChannelT &C, ArgTs &&...Args) {
return SequenceSerialization<ChannelT, std::decay_t<ArgTs>...>::serialize(
C, std::forward<ArgTs>(Args)...);
}
template <typename ChannelT, typename... ArgTs>
-Error deserializeSeq(ChannelT &C, ArgTs &... Args) {
+Error deserializeSeq(ChannelT &C, ArgTs &...Args) {
return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
}
-template <typename ChannelT>
-class SerializationTraits<ChannelT, Error> {
+template <typename ChannelT> class SerializationTraits<ChannelT, Error> {
public:
-
using WrappedErrorSerializer =
- std::function<Error(ChannelT &C, const ErrorInfoBase&)>;
+ std::function<Error(ChannelT &C, const ErrorInfoBase &)>;
using WrappedErrorDeserializer =
- std::function<Error(ChannelT &C, Error &Err)>;
+ std::function<Error(ChannelT &C, Error &Err)>;
template <typename ErrorInfoT, typename SerializeFtor,
typename DeserializeFtor>
@@ -343,15 +331,14 @@ public:
const std::string *KeyName = nullptr;
{
- // We're abusing the stability of std::map here: We take a reference to the
- // key of the deserializers map to save us from duplicating the string in
- // the serializer. This should be changed to use a stringpool if we switch
- // to a map type that may move keys in memory.
+ // We're abusing the stability of std::map here: We take a reference to
+ // the key of the deserializers map to save us from duplicating the string
+ // in the serializer. This should be changed to use a stringpool if we
+ // switch to a map type that may move keys in memory.
std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
- auto I =
- Deserializers.insert(Deserializers.begin(),
- std::make_pair(std::move(Name),
- std::move(Deserialize)));
+ auto I = Deserializers.insert(
+ Deserializers.begin(),
+ std::make_pair(std::move(Name), std::move(Deserialize)));
KeyName = &I->first;
}
@@ -376,13 +363,12 @@ public:
if (!Err)
return serializeSeq(C, std::string());
- return handleErrors(std::move(Err),
- [&C](const ErrorInfoBase &EIB) {
- auto SI = Serializers.find(EIB.dynamicClassID());
- if (SI == Serializers.end())
- return serializeAsStringError(C, EIB);
- return (SI->second)(C, EIB);
- });
+ return handleErrors(std::move(Err), [&C](const ErrorInfoBase &EIB) {
+ auto SI = Serializers.find(EIB.dynamicClassID());
+ if (SI == Serializers.end())
+ return serializeAsStringError(C, EIB);
+ return (SI->second)(C, EIB);
+ });
}
static Error deserialize(ChannelT &C, Error &Err) {
@@ -404,7 +390,6 @@ public:
}
private:
-
static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
std::string ErrMsg;
{
@@ -417,7 +402,7 @@ private:
static std::recursive_mutex SerializersMutex;
static std::recursive_mutex DeserializersMutex;
- static std::map<const void*, WrappedErrorSerializer> Serializers;
+ static std::map<const void *, WrappedErrorSerializer> Serializers;
static std::map<std::string, WrappedErrorDeserializer> Deserializers;
};
@@ -428,14 +413,14 @@ template <typename ChannelT>
std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
template <typename ChannelT>
-std::map<const void*,
+std::map<const void *,
typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
-SerializationTraits<ChannelT, Error>::Serializers;
+ SerializationTraits<ChannelT, Error>::Serializers;
template <typename ChannelT>
-std::map<std::string,
- typename SerializationTraits<ChannelT, Error>::WrappedErrorDeserializer>
-SerializationTraits<ChannelT, Error>::Deserializers;
+std::map<std::string, typename SerializationTraits<
+ ChannelT, Error>::WrappedErrorDeserializer>
+ SerializationTraits<ChannelT, Error>::Deserializers;
/// Registers a serializer and deserializer for the given error type on the
/// given channel type.
@@ -444,32 +429,29 @@ template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
DeserializeFtor &&Deserialize) {
SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
- std::move(Name),
- std::forward<SerializeFtor>(Serialize),
- std::forward<DeserializeFtor>(Deserialize));
+ std::move(Name), std::forward<SerializeFtor>(Serialize),
+ std::forward<DeserializeFtor>(Deserialize));
}
/// Registers serialization/deserialization for StringError.
-template <typename ChannelT>
-void registerStringError() {
+template <typename ChannelT> void registerStringError() {
static bool AlreadyRegistered = false;
if (!AlreadyRegistered) {
registerErrorSerialization<ChannelT, StringError>(
- "StringError",
- [](ChannelT &C, const StringError &SE) {
- return serializeSeq(C, SE.getMessage());
- },
- [](ChannelT &C, Error &Err) -> Error {
- ErrorAsOutParameter EAO(&Err);
- std::string Msg;
- if (auto E2 = deserializeSeq(C, Msg))
- return E2;
- Err =
- make_error<StringError>(std::move(Msg),
- orcError(
- OrcErrorCode::UnknownErrorCodeFromRemote));
- return Error::success();
- });
+ "StringError",
+ [](ChannelT &C, const StringError &SE) {
+ return serializeSeq(C, SE.getMessage());
+ },
+ [](ChannelT &C, Error &Err) -> Error {
+ ErrorAsOutParameter EAO(&Err);
+ std::string Msg;
+ if (auto E2 = deserializeSeq(C, Msg))
+ return E2;
+ Err = make_error<StringError>(
+ std::move(Msg),
+ orcError(OrcErrorCode::UnknownErrorCodeFromRemote));
+ return Error::success();
+ });
AlreadyRegistered = true;
}
}
@@ -478,7 +460,6 @@ void registerStringError() {
template <typename ChannelT, typename T1, typename T2>
class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
public:
-
static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
if (ValOrErr) {
if (auto Err = serializeSeq(C, true))
@@ -509,7 +490,6 @@ public:
template <typename ChannelT, typename T1, typename T2>
class SerializationTraits<ChannelT, Expected<T1>, T2> {
public:
-
static Error serialize(ChannelT &C, T2 &&Val) {
return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
}
@@ -519,7 +499,6 @@ public:
template <typename ChannelT, typename T>
class SerializationTraits<ChannelT, Expected<T>, Error> {
public:
-
static Error serialize(ChannelT &C, Error &&Err) {
return serializeSeq(C, Expected<T>(std::move(Err)));
}
@@ -547,7 +526,6 @@ public:
template <typename ChannelT, typename... ArgTs>
class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
public:
-
/// RPC channel serialization for std::tuple.
static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
return serializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
@@ -574,11 +552,35 @@ private:
}
};
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, Optional<T>> {
+public:
+ /// Serialize an Optional<T>.
+ static Error serialize(ChannelT &C, const Optional<T> &O) {
+ if (auto Err = serializeSeq(C, O != None))
+ return Err;
+ if (O)
+ if (auto Err = serializeSeq(C, *O))
+ return Err;
+ return Error::success();
+ }
+
+ /// Deserialize an Optional<T>.
+ static Error deserialize(ChannelT &C, Optional<T> &O) {
+ bool HasValue = false;
+ if (auto Err = deserializeSeq(C, HasValue))
+ return Err;
+ if (HasValue)
+ if (auto Err = deserializeSeq(C, *O))
+ return Err;
+ return Error::success();
+ };
+};
+
/// SerializationTraits default specialization for std::vector.
template <typename ChannelT, typename T>
class SerializationTraits<ChannelT, std::vector<T>> {
public:
-
/// Serialize a std::vector<T> from std::vector<T>.
static Error serialize(ChannelT &C, const std::vector<T> &V) {
if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
@@ -609,6 +611,22 @@ public:
}
};
+/// Enable vector serialization from an ArrayRef.
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, std::vector<T>, ArrayRef<T>> {
+public:
+ static Error serialize(ChannelT &C, ArrayRef<T> V) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
+ return Err;
+
+ for (const auto &E : V)
+ if (auto Err = serializeSeq(C, E))
+ return Err;
+
+ return Error::success();
+ }
+};
+
template <typename ChannelT, typename T, typename T2>
class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
public:
@@ -695,8 +713,57 @@ public:
}
};
-} // end namespace rpc
+template <typename ChannelT, typename K, typename V, typename K2, typename V2>
+class SerializationTraits<ChannelT, std::map<K, V>, DenseMap<K2, V2>> {
+public:
+ /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
+ static Error serialize(ChannelT &C, const DenseMap<K2, V2> &M) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
+ return Err;
+
+ for (auto &E : M) {
+ if (auto Err =
+ SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
+ return Err;
+
+ if (auto Err =
+ SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
+ return Err;
+ }
+
+ return Error::success();
+ }
+
+ /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
+ static Error deserialize(ChannelT &C, DenseMap<K2, V2> &M) {
+ assert(M.empty() && "Expected default-constructed map to deserialize into");
+
+ uint64_t Count = 0;
+ if (auto Err = deserializeSeq(C, Count))
+ return Err;
+
+ while (Count-- != 0) {
+ std::pair<K2, V2> Val;
+ if (auto Err =
+ SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
+ return Err;
+
+ if (auto Err =
+ SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
+ return Err;
+
+ auto Added = M.insert(Val).second;
+ if (!Added)
+ return make_error<StringError>("Duplicate element in deserialized map",
+ orcError(OrcErrorCode::UnknownORCError));
+ }
+
+ return Error::success();
+ }
+};
+
+} // namespace shared
} // end namespace orc
} // end namespace llvm
-#endif // LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
+#endif // LLVM_EXECUTIONENGINE_ORC_RPC_RPCSERIALIZATION_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
new file mode 100644
index 000000000000..d01b3ef21f80
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
@@ -0,0 +1,165 @@
+//===--- TargetProcessControlTypes.h -- Shared Core/TPC types ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// TargetProcessControl types that are used by both the Orc and
+// OrcTargetProcess libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+
+#include <vector>
+
+namespace llvm {
+namespace orc {
+namespace tpctypes {
+
+template <typename T> struct UIntWrite {
+ UIntWrite() = default;
+ UIntWrite(JITTargetAddress Address, T Value)
+ : Address(Address), Value(Value) {}
+
+ JITTargetAddress Address = 0;
+ T Value = 0;
+};
+
+/// Describes a write to a uint8_t.
+using UInt8Write = UIntWrite<uint8_t>;
+
+/// Describes a write to a uint16_t.
+using UInt16Write = UIntWrite<uint16_t>;
+
+/// Describes a write to a uint32_t.
+using UInt32Write = UIntWrite<uint32_t>;
+
+/// Describes a write to a uint64_t.
+using UInt64Write = UIntWrite<uint64_t>;
+
+/// Describes a write to a buffer.
+/// For use with TargetProcessControl::MemoryAccess objects.
+struct BufferWrite {
+ BufferWrite() = default;
+ BufferWrite(JITTargetAddress Address, StringRef Buffer)
+ : Address(Address), Buffer(Buffer) {}
+
+ JITTargetAddress Address = 0;
+ StringRef Buffer;
+};
+
+/// A handle used to represent a loaded dylib in the target process.
+using DylibHandle = JITTargetAddress;
+
+using LookupResult = std::vector<JITTargetAddress>;
+
+/// Either a uint8_t array or a uint8_t*.
+union CWrapperFunctionResultData {
+ uint8_t Value[8];
+ uint8_t *ValuePtr;
+};
+
+/// C ABI compatible wrapper function result.
+///
+/// This can be safely returned from extern "C" functions, but should be used
+/// to construct a WrapperFunctionResult for safety.
+struct CWrapperFunctionResult {
+ uint64_t Size;
+ CWrapperFunctionResultData Data;
+ void (*Destroy)(CWrapperFunctionResultData Data, uint64_t Size);
+};
+
+/// C++ wrapper function result: Same as CWrapperFunctionResult but
+/// auto-releases memory.
+class WrapperFunctionResult {
+public:
+ /// Create a default WrapperFunctionResult.
+ WrapperFunctionResult() { zeroInit(R); }
+
+ /// Create a WrapperFunctionResult from a CWrapperFunctionResult. This
+ /// instance takes ownership of the result object and will automatically
+ /// call the Destroy member upon destruction.
+ WrapperFunctionResult(CWrapperFunctionResult R) : R(R) {}
+
+ WrapperFunctionResult(const WrapperFunctionResult &) = delete;
+ WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete;
+
+ WrapperFunctionResult(WrapperFunctionResult &&Other) {
+ zeroInit(R);
+ std::swap(R, Other.R);
+ }
+
+ WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) {
+ CWrapperFunctionResult Tmp;
+ zeroInit(Tmp);
+ std::swap(Tmp, Other.R);
+ std::swap(R, Tmp);
+ return *this;
+ }
+
+ ~WrapperFunctionResult() {
+ if (R.Destroy)
+ R.Destroy(R.Data, R.Size);
+ }
+
+ /// Relinquish ownership of and return the CWrapperFunctionResult.
+ CWrapperFunctionResult release() {
+ CWrapperFunctionResult Tmp;
+ zeroInit(Tmp);
+ std::swap(R, Tmp);
+ return Tmp;
+ }
+
+ /// Get an ArrayRef covering the data in the result.
+ ArrayRef<uint8_t> getData() const {
+ if (R.Size <= 8)
+ return ArrayRef<uint8_t>(R.Data.Value, R.Size);
+ return ArrayRef<uint8_t>(R.Data.ValuePtr, R.Size);
+ }
+
+ /// Create a WrapperFunctionResult from the given integer, provided its
+ /// size is no greater than 64 bits.
+ template <typename T,
+ typename _ = std::enable_if_t<std::is_integral<T>::value &&
+ sizeof(T) <= sizeof(uint64_t)>>
+ static WrapperFunctionResult from(T Value) {
+ CWrapperFunctionResult R;
+ R.Size = sizeof(T);
+ memcpy(&R.Data.Value, Value, R.Size);
+ R.Destroy = nullptr;
+ return R;
+ }
+
+ /// Create a WrapperFunctionResult from the given string.
+ static WrapperFunctionResult from(StringRef S);
+
+ /// Always free Data.ValuePtr by calling free on it.
+ static void destroyWithFree(CWrapperFunctionResultData Data, uint64_t Size);
+
+ /// Always free Data.ValuePtr by calling delete[] on it.
+ static void destroyWithDeleteArray(CWrapperFunctionResultData Data,
+ uint64_t Size);
+
+private:
+ static void zeroInit(CWrapperFunctionResult &R) {
+ R.Size = 0;
+ R.Data.ValuePtr = nullptr;
+ R.Destroy = nullptr;
+ }
+
+ CWrapperFunctionResult R;
+};
+
+} // end namespace tpctypes
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
index d8213d3b35e8..a138f60a7756 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
@@ -18,14 +18,10 @@
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/Debug.h"
-
#include <mutex>
#include <type_traits>
#include <utility>
-#include <vector>
namespace llvm {
namespace orc {
@@ -185,7 +181,8 @@ public:
: IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer),
S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {}
- void emit(MaterializationResponsibility R, ThreadSafeModule TSM);
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
private:
TargetAndLikelies
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
new file mode 100644
index 000000000000..ed4f6080bb4e
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
@@ -0,0 +1,66 @@
+//===------------ TPCDynamicLibrarySearchGenerator.h ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Support loading and searching of dynamic libraries in a target process via
+// the TargetProcessControl class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+
+namespace llvm {
+namespace orc {
+
+class TPCDynamicLibrarySearchGenerator : public DefinitionGenerator {
+public:
+ using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>;
+
+ /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
+ /// library with the given handle.
+ ///
+ /// If the Allow predicate is given then only symbols matching the predicate
+ /// will be searched for. If the predicate is not given then all symbols will
+ /// be searched for.
+ TPCDynamicLibrarySearchGenerator(TargetProcessControl &TPC,
+ tpctypes::DylibHandle H,
+ SymbolPredicate Allow = SymbolPredicate())
+ : TPC(TPC), H(H), Allow(std::move(Allow)) {}
+
+ /// Permanently loads the library at the given path and, on success, returns
+ /// a DynamicLibrarySearchGenerator that will search it for symbol definitions
+ /// in the library. On failure returns the reason the library failed to load.
+ static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
+ Load(TargetProcessControl &TPC, const char *LibraryPath,
+ SymbolPredicate Allow = SymbolPredicate());
+
+ /// Creates a TPCDynamicLibrarySearchGenerator that searches for symbols in
+ /// the target process.
+ static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
+ GetForTargetProcess(TargetProcessControl &TPC,
+ SymbolPredicate Allow = SymbolPredicate()) {
+ return Load(TPC, nullptr, std::move(Allow));
+ }
+
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &Symbols) override;
+
+private:
+ TargetProcessControl &TPC;
+ tpctypes::DylibHandle H;
+ SymbolPredicate Allow;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h
new file mode 100644
index 000000000000..519f818907f9
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h
@@ -0,0 +1,54 @@
+//===-- TPCEHFrameRegistrar.h - TPC based eh-frame registration -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// TargetProcessControl based eh-frame registration.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
+
+#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+
+namespace llvm {
+namespace orc {
+
+/// Register/Deregisters EH frames in a remote process via a
+/// TargetProcessControl instance.
+class TPCEHFrameRegistrar : public jitlink::EHFrameRegistrar {
+public:
+ /// Create from a TargetProcessControl instance alone. This will use
+ /// the TPC's lookupSymbols method to find the registration/deregistration
+ /// funciton addresses by name.
+ static Expected<std::unique_ptr<TPCEHFrameRegistrar>>
+ Create(TargetProcessControl &TPC);
+
+ /// Create a TPCEHFrameRegistrar with the given TargetProcessControl
+ /// object and registration/deregistration function addresses.
+ TPCEHFrameRegistrar(TargetProcessControl &TPC,
+ JITTargetAddress RegisterEHFrameWrapperFnAddr,
+ JITTargetAddress DeregisterEHFRameWrapperFnAddr)
+ : TPC(TPC), RegisterEHFrameWrapperFnAddr(RegisterEHFrameWrapperFnAddr),
+ DeregisterEHFrameWrapperFnAddr(DeregisterEHFRameWrapperFnAddr) {}
+
+ Error registerEHFrames(JITTargetAddress EHFrameSectionAddr,
+ size_t EHFrameSectionSize) override;
+ Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr,
+ size_t EHFrameSectionSize) override;
+
+private:
+ TargetProcessControl &TPC;
+ JITTargetAddress RegisterEHFrameWrapperFnAddr;
+ JITTargetAddress DeregisterEHFrameWrapperFnAddr;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
new file mode 100644
index 000000000000..e7abd7fb90df
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
@@ -0,0 +1,222 @@
+//===--- TPCIndirectionUtils.h - TPC based indirection utils ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Indirection utilities (stubs, trampolines, lazy call-throughs) that use the
+// TargetProcessControl API to interact with the target process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
+
+#include <mutex>
+
+namespace llvm {
+namespace orc {
+
+class TargetProcessControl;
+
+/// Provides TargetProcessControl based indirect stubs, trampoline pool and
+/// lazy call through manager.
+class TPCIndirectionUtils {
+ friend class TPCIndirectionUtilsAccess;
+
+public:
+ /// ABI support base class. Used to write resolver, stub, and trampoline
+ /// blocks.
+ class ABISupport {
+ protected:
+ ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
+ unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
+ : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
+ StubSize(StubSize),
+ StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
+ ResolverCodeSize(ResolverCodeSize) {}
+
+ public:
+ virtual ~ABISupport();
+
+ unsigned getPointerSize() const { return PointerSize; }
+ unsigned getTrampolineSize() const { return TrampolineSize; }
+ unsigned getStubSize() const { return StubSize; }
+ unsigned getStubToPointerMaxDisplacement() const {
+ return StubToPointerMaxDisplacement;
+ }
+ unsigned getResolverCodeSize() const { return ResolverCodeSize; }
+
+ virtual void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddr,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) const = 0;
+
+ virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTragetAddr,
+ JITTargetAddress ResolverAddr,
+ unsigned NumTrampolines) const = 0;
+
+ virtual void
+ writeIndirectStubsBlock(char *StubsBlockWorkingMem,
+ JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress,
+ unsigned NumStubs) const = 0;
+
+ private:
+ unsigned PointerSize = 0;
+ unsigned TrampolineSize = 0;
+ unsigned StubSize = 0;
+ unsigned StubToPointerMaxDisplacement = 0;
+ unsigned ResolverCodeSize = 0;
+ };
+
+ /// Create using the given ABI class.
+ template <typename ORCABI>
+ static std::unique_ptr<TPCIndirectionUtils>
+ CreateWithABI(TargetProcessControl &TPC);
+
+ /// Create based on the TargetProcessControl triple.
+ static Expected<std::unique_ptr<TPCIndirectionUtils>>
+ Create(TargetProcessControl &TPC);
+
+ /// Return a reference to the TargetProcessControl object.
+ TargetProcessControl &getTargetProcessControl() const { return TPC; }
+
+ /// Return a reference to the ABISupport object for this instance.
+ ABISupport &getABISupport() const { return *ABI; }
+
+ /// Release memory for resources held by this instance. This *must* be called
+ /// prior to destruction of the class.
+ Error cleanup();
+
+ /// Write resolver code to the target process and return its address.
+ /// This must be called before any call to createTrampolinePool or
+ /// createLazyCallThroughManager.
+ Expected<JITTargetAddress>
+ writeResolverBlock(JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr);
+
+ /// Returns the address of the Resolver block. Returns zero if the
+ /// writeResolverBlock method has not previously been called.
+ JITTargetAddress getResolverBlockAddress() const { return ResolverBlockAddr; }
+
+ /// Create an IndirectStubsManager for the target process.
+ std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
+
+ /// Create a TrampolinePool for the target process.
+ TrampolinePool &getTrampolinePool();
+
+ /// Create a LazyCallThroughManager.
+ /// This function should only be called once.
+ LazyCallThroughManager &
+ createLazyCallThroughManager(ExecutionSession &ES,
+ JITTargetAddress ErrorHandlerAddr);
+
+ /// Create a LazyCallThroughManager for the target process.
+ LazyCallThroughManager &getLazyCallThroughManager() {
+ assert(LCTM && "createLazyCallThroughManager must be called first");
+ return *LCTM;
+ }
+
+private:
+ using Allocation = jitlink::JITLinkMemoryManager::Allocation;
+
+ struct IndirectStubInfo {
+ IndirectStubInfo() = default;
+ IndirectStubInfo(JITTargetAddress StubAddress,
+ JITTargetAddress PointerAddress)
+ : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
+ JITTargetAddress StubAddress = 0;
+ JITTargetAddress PointerAddress = 0;
+ };
+
+ using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
+
+ /// Create a TPCIndirectionUtils instance.
+ TPCIndirectionUtils(TargetProcessControl &TPC,
+ std::unique_ptr<ABISupport> ABI);
+
+ Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
+
+ std::mutex TPCUIMutex;
+ TargetProcessControl &TPC;
+ std::unique_ptr<ABISupport> ABI;
+ JITTargetAddress ResolverBlockAddr;
+ std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> ResolverBlock;
+ std::unique_ptr<TrampolinePool> TP;
+ std::unique_ptr<LazyCallThroughManager> LCTM;
+
+ std::vector<IndirectStubInfo> AvailableIndirectStubs;
+ std::vector<std::unique_ptr<Allocation>> IndirectStubAllocs;
+};
+
+/// This will call writeResolver on the given TPCIndirectionUtils instance
+/// to set up re-entry via a function that will directly return the trampoline
+/// landing address.
+///
+/// The TPCIndirectionUtils' LazyCallThroughManager must have been previously
+/// created via TPCIndirectionUtils::createLazyCallThroughManager.
+///
+/// The TPCIndirectionUtils' writeResolver method must not have been previously
+/// called.
+///
+/// This function is experimental and likely subject to revision.
+Error setUpInProcessLCTMReentryViaTPCIU(TPCIndirectionUtils &TPCIU);
+
+namespace detail {
+
+template <typename ORCABI>
+class ABISupportImpl : public TPCIndirectionUtils::ABISupport {
+public:
+ ABISupportImpl()
+ : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
+ ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
+ ORCABI::ResolverCodeSize) {}
+
+ void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddr,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) const override {
+ ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
+ ReentryFnAddr, ReentryCtxAddr);
+ }
+
+ void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddr,
+ JITTargetAddress ResolverAddr,
+ unsigned NumTrampolines) const override {
+ ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
+ TrampolineBlockTargetAddr, ResolverAddr,
+ NumTrampolines);
+ }
+
+ void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
+ JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress,
+ unsigned NumStubs) const override {
+ ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
+ StubsBlockTargetAddress,
+ PointersBlockTargetAddress, NumStubs);
+ }
+};
+
+} // end namespace detail
+
+template <typename ORCABI>
+std::unique_ptr<TPCIndirectionUtils>
+TPCIndirectionUtils::CreateWithABI(TargetProcessControl &TPC) {
+ return std::unique_ptr<TPCIndirectionUtils>(new TPCIndirectionUtils(
+ TPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
+}
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h
new file mode 100644
index 000000000000..253e06ba0ba1
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h
@@ -0,0 +1,620 @@
+//===-- OrcRPCTPCServer.h -- OrcRPCTargetProcessControl Server --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// OrcRPCTargetProcessControl server class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
+
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Process.h"
+
+#include <atomic>
+
+namespace llvm {
+namespace orc {
+
+namespace orcrpctpc {
+
+enum WireProtectionFlags : uint8_t {
+ WPF_None = 0,
+ WPF_Read = 1U << 0,
+ WPF_Write = 1U << 1,
+ WPF_Exec = 1U << 2,
+ LLVM_MARK_AS_BITMASK_ENUM(WPF_Exec)
+};
+
+/// Convert from sys::Memory::ProtectionFlags
+inline WireProtectionFlags
+toWireProtectionFlags(sys::Memory::ProtectionFlags PF) {
+ WireProtectionFlags WPF = WPF_None;
+ if (PF & sys::Memory::MF_READ)
+ WPF |= WPF_Read;
+ if (PF & sys::Memory::MF_WRITE)
+ WPF |= WPF_Write;
+ if (PF & sys::Memory::MF_EXEC)
+ WPF |= WPF_Exec;
+ return WPF;
+}
+
+inline sys::Memory::ProtectionFlags
+fromWireProtectionFlags(WireProtectionFlags WPF) {
+ int PF = 0;
+ if (WPF & WPF_Read)
+ PF |= sys::Memory::MF_READ;
+ if (WPF & WPF_Write)
+ PF |= sys::Memory::MF_WRITE;
+ if (WPF & WPF_Exec)
+ PF |= sys::Memory::MF_EXEC;
+ return static_cast<sys::Memory::ProtectionFlags>(PF);
+}
+
+struct ReserveMemRequestElement {
+ WireProtectionFlags Prot = WPF_None;
+ uint64_t Size = 0;
+ uint64_t Alignment = 0;
+};
+
+using ReserveMemRequest = std::vector<ReserveMemRequestElement>;
+
+struct ReserveMemResultElement {
+ WireProtectionFlags Prot = WPF_None;
+ JITTargetAddress Address = 0;
+ uint64_t AllocatedSize = 0;
+};
+
+using ReserveMemResult = std::vector<ReserveMemResultElement>;
+
+struct ReleaseOrFinalizeMemRequestElement {
+ WireProtectionFlags Prot = WPF_None;
+ JITTargetAddress Address = 0;
+ uint64_t Size = 0;
+};
+
+using ReleaseOrFinalizeMemRequest =
+ std::vector<ReleaseOrFinalizeMemRequestElement>;
+
+} // end namespace orcrpctpc
+
+namespace shared {
+
+template <> class SerializationTypeName<tpctypes::UInt8Write> {
+public:
+ static const char *getName() { return "UInt8Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt16Write> {
+public:
+ static const char *getName() { return "UInt16Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt32Write> {
+public:
+ static const char *getName() { return "UInt32Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt64Write> {
+public:
+ static const char *getName() { return "UInt64Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::BufferWrite> {
+public:
+ static const char *getName() { return "BufferWrite"; }
+};
+
+template <> class SerializationTypeName<orcrpctpc::ReserveMemRequestElement> {
+public:
+ static const char *getName() { return "ReserveMemRequestElement"; }
+};
+
+template <> class SerializationTypeName<orcrpctpc::ReserveMemResultElement> {
+public:
+ static const char *getName() { return "ReserveMemResultElement"; }
+};
+
+template <>
+class SerializationTypeName<orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
+public:
+ static const char *getName() { return "ReleaseOrFinalizeMemRequestElement"; }
+};
+
+template <> class SerializationTypeName<tpctypes::WrapperFunctionResult> {
+public:
+ static const char *getName() { return "WrapperFunctionResult"; }
+};
+
+template <typename ChannelT, typename WriteT>
+class SerializationTraits<
+ ChannelT, WriteT, WriteT,
+ std::enable_if_t<std::is_same<WriteT, tpctypes::UInt8Write>::value ||
+ std::is_same<WriteT, tpctypes::UInt16Write>::value ||
+ std::is_same<WriteT, tpctypes::UInt32Write>::value ||
+ std::is_same<WriteT, tpctypes::UInt64Write>::value>> {
+public:
+ static Error serialize(ChannelT &C, const WriteT &W) {
+ return serializeSeq(C, W.Address, W.Value);
+ }
+ static Error deserialize(ChannelT &C, WriteT &W) {
+ return deserializeSeq(C, W.Address, W.Value);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+ ChannelT, tpctypes::BufferWrite, tpctypes::BufferWrite,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+ static Error serialize(ChannelT &C, const tpctypes::BufferWrite &W) {
+ uint64_t Size = W.Buffer.size();
+ if (auto Err = serializeSeq(C, W.Address, Size))
+ return Err;
+
+ return C.appendBytes(W.Buffer.data(), Size);
+ }
+ static Error deserialize(ChannelT &C, tpctypes::BufferWrite &W) {
+ JITTargetAddress Address;
+ uint64_t Size;
+
+ if (auto Err = deserializeSeq(C, Address, Size))
+ return Err;
+
+ char *Buffer = jitTargetAddressToPointer<char *>(Address);
+
+ if (auto Err = C.readBytes(Buffer, Size))
+ return Err;
+
+ W = {Address, StringRef(Buffer, Size)};
+ return Error::success();
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT, orcrpctpc::ReserveMemRequestElement> {
+public:
+ static Error serialize(ChannelT &C,
+ const orcrpctpc::ReserveMemRequestElement &E) {
+ return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Size, E.Alignment);
+ }
+
+ static Error deserialize(ChannelT &C,
+ orcrpctpc::ReserveMemRequestElement &E) {
+ return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Size,
+ E.Alignment);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT, orcrpctpc::ReserveMemResultElement> {
+public:
+ static Error serialize(ChannelT &C,
+ const orcrpctpc::ReserveMemResultElement &E) {
+ return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address,
+ E.AllocatedSize);
+ }
+
+ static Error deserialize(ChannelT &C, orcrpctpc::ReserveMemResultElement &E) {
+ return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
+ E.AllocatedSize);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT,
+ orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
+public:
+ static Error
+ serialize(ChannelT &C,
+ const orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
+ return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address, E.Size);
+ }
+
+ static Error deserialize(ChannelT &C,
+ orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
+ return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
+ E.Size);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+ ChannelT, tpctypes::WrapperFunctionResult, tpctypes::WrapperFunctionResult,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+ static Error serialize(ChannelT &C,
+ const tpctypes::WrapperFunctionResult &E) {
+ auto Data = E.getData();
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(Data.size())))
+ return Err;
+ if (Data.size() == 0)
+ return Error::success();
+ return C.appendBytes(reinterpret_cast<const char *>(Data.data()),
+ Data.size());
+ }
+
+ static Error deserialize(ChannelT &C, tpctypes::WrapperFunctionResult &E) {
+ tpctypes::CWrapperFunctionResult R;
+
+ R.Size = 0;
+ R.Data.ValuePtr = nullptr;
+ R.Destroy = nullptr;
+
+ if (auto Err = deserializeSeq(C, R.Size))
+ return Err;
+ if (R.Size == 0)
+ return Error::success();
+ R.Data.ValuePtr = new uint8_t[R.Size];
+ if (auto Err =
+ C.readBytes(reinterpret_cast<char *>(R.Data.ValuePtr), R.Size)) {
+ R.Destroy = tpctypes::WrapperFunctionResult::destroyWithDeleteArray;
+ return Err;
+ }
+
+ E = tpctypes::WrapperFunctionResult(R);
+ return Error::success();
+ }
+};
+
+} // end namespace shared
+
+namespace orcrpctpc {
+
+using RemoteSymbolLookupSet = std::vector<std::pair<std::string, bool>>;
+using RemoteLookupRequest =
+ std::pair<tpctypes::DylibHandle, RemoteSymbolLookupSet>;
+
+class GetTargetTriple
+ : public shared::RPCFunction<GetTargetTriple, std::string()> {
+public:
+ static const char *getName() { return "GetTargetTriple"; }
+};
+
+class GetPageSize : public shared::RPCFunction<GetPageSize, uint64_t()> {
+public:
+ static const char *getName() { return "GetPageSize"; }
+};
+
+class ReserveMem
+ : public shared::RPCFunction<ReserveMem, Expected<ReserveMemResult>(
+ ReserveMemRequest)> {
+public:
+ static const char *getName() { return "ReserveMem"; }
+};
+
+class FinalizeMem
+ : public shared::RPCFunction<FinalizeMem,
+ Error(ReleaseOrFinalizeMemRequest)> {
+public:
+ static const char *getName() { return "FinalizeMem"; }
+};
+
+class ReleaseMem
+ : public shared::RPCFunction<ReleaseMem,
+ Error(ReleaseOrFinalizeMemRequest)> {
+public:
+ static const char *getName() { return "ReleaseMem"; }
+};
+
+class WriteUInt8s
+ : public shared::RPCFunction<WriteUInt8s,
+ Error(std::vector<tpctypes::UInt8Write>)> {
+public:
+ static const char *getName() { return "WriteUInt8s"; }
+};
+
+class WriteUInt16s
+ : public shared::RPCFunction<WriteUInt16s,
+ Error(std::vector<tpctypes::UInt16Write>)> {
+public:
+ static const char *getName() { return "WriteUInt16s"; }
+};
+
+class WriteUInt32s
+ : public shared::RPCFunction<WriteUInt32s,
+ Error(std::vector<tpctypes::UInt32Write>)> {
+public:
+ static const char *getName() { return "WriteUInt32s"; }
+};
+
+class WriteUInt64s
+ : public shared::RPCFunction<WriteUInt64s,
+ Error(std::vector<tpctypes::UInt64Write>)> {
+public:
+ static const char *getName() { return "WriteUInt64s"; }
+};
+
+class WriteBuffers
+ : public shared::RPCFunction<WriteBuffers,
+ Error(std::vector<tpctypes::BufferWrite>)> {
+public:
+ static const char *getName() { return "WriteBuffers"; }
+};
+
+class LoadDylib
+ : public shared::RPCFunction<LoadDylib, Expected<tpctypes::DylibHandle>(
+ std::string DylibPath)> {
+public:
+ static const char *getName() { return "LoadDylib"; }
+};
+
+class LookupSymbols
+ : public shared::RPCFunction<LookupSymbols,
+ Expected<std::vector<tpctypes::LookupResult>>(
+ std::vector<RemoteLookupRequest>)> {
+public:
+ static const char *getName() { return "LookupSymbols"; }
+};
+
+class RunMain
+ : public shared::RPCFunction<RunMain,
+ int32_t(JITTargetAddress MainAddr,
+ std::vector<std::string> Args)> {
+public:
+ static const char *getName() { return "RunMain"; }
+};
+
+class RunWrapper
+ : public shared::RPCFunction<RunWrapper,
+ tpctypes::WrapperFunctionResult(
+ JITTargetAddress, std::vector<uint8_t>)> {
+public:
+ static const char *getName() { return "RunWrapper"; }
+};
+
+class CloseConnection : public shared::RPCFunction<CloseConnection, void()> {
+public:
+ static const char *getName() { return "CloseConnection"; }
+};
+
+} // end namespace orcrpctpc
+
+/// TargetProcessControl for a process connected via an ORC RPC Endpoint.
+template <typename RPCEndpointT> class OrcRPCTPCServer {
+public:
+ /// Create an OrcRPCTPCServer from the given endpoint.
+ OrcRPCTPCServer(RPCEndpointT &EP) : EP(EP) {
+ using ThisT = OrcRPCTPCServer<RPCEndpointT>;
+
+ TripleStr = sys::getProcessTriple();
+ PageSize = sys::Process::getPageSizeEstimate();
+
+ EP.template addHandler<orcrpctpc::GetTargetTriple>(*this,
+ &ThisT::getTargetTriple);
+ EP.template addHandler<orcrpctpc::GetPageSize>(*this, &ThisT::getPageSize);
+
+ EP.template addHandler<orcrpctpc::ReserveMem>(*this, &ThisT::reserveMemory);
+ EP.template addHandler<orcrpctpc::FinalizeMem>(*this,
+ &ThisT::finalizeMemory);
+ EP.template addHandler<orcrpctpc::ReleaseMem>(*this, &ThisT::releaseMemory);
+
+ EP.template addHandler<orcrpctpc::WriteUInt8s>(
+ handleWriteUInt<tpctypes::UInt8Write>);
+ EP.template addHandler<orcrpctpc::WriteUInt16s>(
+ handleWriteUInt<tpctypes::UInt16Write>);
+ EP.template addHandler<orcrpctpc::WriteUInt32s>(
+ handleWriteUInt<tpctypes::UInt32Write>);
+ EP.template addHandler<orcrpctpc::WriteUInt64s>(
+ handleWriteUInt<tpctypes::UInt64Write>);
+ EP.template addHandler<orcrpctpc::WriteBuffers>(handleWriteBuffer);
+
+ EP.template addHandler<orcrpctpc::LoadDylib>(*this, &ThisT::loadDylib);
+ EP.template addHandler<orcrpctpc::LookupSymbols>(*this,
+ &ThisT::lookupSymbols);
+
+ EP.template addHandler<orcrpctpc::RunMain>(*this, &ThisT::runMain);
+ EP.template addHandler<orcrpctpc::RunWrapper>(*this, &ThisT::runWrapper);
+
+ EP.template addHandler<orcrpctpc::CloseConnection>(*this,
+ &ThisT::closeConnection);
+ }
+
+ /// Set the ProgramName to be used as the first argv element when running
+ /// functions via runAsMain.
+ void setProgramName(Optional<std::string> ProgramName = None) {
+ this->ProgramName = std::move(ProgramName);
+ }
+
+ /// Get the RPC endpoint for this server.
+ RPCEndpointT &getEndpoint() { return EP; }
+
+ /// Run the server loop.
+ Error run() {
+ while (!Finished) {
+ if (auto Err = EP.handleOne())
+ return Err;
+ }
+ return Error::success();
+ }
+
+private:
+ std::string getTargetTriple() { return TripleStr; }
+ uint64_t getPageSize() { return PageSize; }
+
+ template <typename WriteT>
+ static void handleWriteUInt(const std::vector<WriteT> &Ws) {
+ using ValueT = decltype(std::declval<WriteT>().Value);
+ for (auto &W : Ws)
+ *jitTargetAddressToPointer<ValueT *>(W.Address) = W.Value;
+ }
+
+ std::string getProtStr(orcrpctpc::WireProtectionFlags WPF) {
+ std::string Result;
+ Result += (WPF & orcrpctpc::WPF_Read) ? 'R' : '-';
+ Result += (WPF & orcrpctpc::WPF_Write) ? 'W' : '-';
+ Result += (WPF & orcrpctpc::WPF_Exec) ? 'X' : '-';
+ return Result;
+ }
+
+ static void handleWriteBuffer(const std::vector<tpctypes::BufferWrite> &Ws) {
+ for (auto &W : Ws) {
+ memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
+ W.Buffer.size());
+ }
+ }
+
+ Expected<orcrpctpc::ReserveMemResult>
+ reserveMemory(const orcrpctpc::ReserveMemRequest &Request) {
+ orcrpctpc::ReserveMemResult Allocs;
+ auto PF = sys::Memory::MF_READ | sys::Memory::MF_WRITE;
+
+ uint64_t TotalSize = 0;
+
+ for (const auto &E : Request) {
+ uint64_t Size = alignTo(E.Size, PageSize);
+ uint16_t Align = E.Alignment;
+
+ if ((Align > PageSize) || (PageSize % Align))
+ return make_error<StringError>(
+ "Page alignmen does not satisfy requested alignment",
+ inconvertibleErrorCode());
+
+ TotalSize += Size;
+ }
+
+ // Allocate memory slab.
+ std::error_code EC;
+ auto MB = sys::Memory::allocateMappedMemory(TotalSize, nullptr, PF, EC);
+ if (EC)
+ return make_error<StringError>("Unable to allocate memory: " +
+ EC.message(),
+ inconvertibleErrorCode());
+
+ // Zero-fill the whole thing.
+ memset(MB.base(), 0, MB.allocatedSize());
+
+ // Carve up sections to return.
+ uint64_t SectionBase = 0;
+ for (const auto &E : Request) {
+ uint64_t SectionSize = alignTo(E.Size, PageSize);
+ Allocs.push_back({E.Prot,
+ pointerToJITTargetAddress(MB.base()) + SectionBase,
+ SectionSize});
+ SectionBase += SectionSize;
+ }
+
+ return Allocs;
+ }
+
+ Error finalizeMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &FMR) {
+ for (const auto &E : FMR) {
+ sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
+
+ auto PF = orcrpctpc::fromWireProtectionFlags(E.Prot);
+ if (auto EC =
+ sys::Memory::protectMappedMemory(MB, static_cast<unsigned>(PF)))
+ return make_error<StringError>("error protecting memory: " +
+ EC.message(),
+ inconvertibleErrorCode());
+ }
+ return Error::success();
+ }
+
+ Error releaseMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &RMR) {
+ for (const auto &E : RMR) {
+ sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
+
+ if (auto EC = sys::Memory::releaseMappedMemory(MB))
+ return make_error<StringError>("error release memory: " + EC.message(),
+ inconvertibleErrorCode());
+ }
+ return Error::success();
+ }
+
+ Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path) {
+ std::string ErrMsg;
+ const char *DLPath = !Path.empty() ? Path.c_str() : nullptr;
+ auto DL = sys::DynamicLibrary::getPermanentLibrary(DLPath, &ErrMsg);
+ if (!DL.isValid())
+ return make_error<StringError>(std::move(ErrMsg),
+ inconvertibleErrorCode());
+
+ tpctypes::DylibHandle H = Dylibs.size();
+ Dylibs[H] = std::move(DL);
+ return H;
+ }
+
+ Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(const std::vector<orcrpctpc::RemoteLookupRequest> &Request) {
+ std::vector<tpctypes::LookupResult> Result;
+
+ for (const auto &E : Request) {
+ auto I = Dylibs.find(E.first);
+ if (I == Dylibs.end())
+ return make_error<StringError>("Unrecognized handle",
+ inconvertibleErrorCode());
+ auto &DL = I->second;
+ Result.push_back({});
+
+ for (const auto &KV : E.second) {
+ auto &SymString = KV.first;
+ bool WeakReference = KV.second;
+
+ const char *Sym = SymString.c_str();
+#ifdef __APPLE__
+ if (*Sym == '_')
+ ++Sym;
+#endif
+
+ void *Addr = DL.getAddressOfSymbol(Sym);
+ if (!Addr && !WeakReference)
+ return make_error<StringError>(Twine("Missing definition for ") + Sym,
+ inconvertibleErrorCode());
+
+ Result.back().push_back(pointerToJITTargetAddress(Addr));
+ }
+ }
+
+ return Result;
+ }
+
+ int32_t runMain(JITTargetAddress MainFnAddr,
+ const std::vector<std::string> &Args) {
+ Optional<StringRef> ProgramNameOverride;
+ if (ProgramName)
+ ProgramNameOverride = *ProgramName;
+
+ return runAsMain(
+ jitTargetAddressToFunction<int (*)(int, char *[])>(MainFnAddr), Args,
+ ProgramNameOverride);
+ }
+
+ tpctypes::WrapperFunctionResult
+ runWrapper(JITTargetAddress WrapperFnAddr,
+ const std::vector<uint8_t> &ArgBuffer) {
+ using WrapperFnTy = tpctypes::CWrapperFunctionResult (*)(
+ const uint8_t *Data, uint64_t Size);
+ auto *WrapperFn = jitTargetAddressToFunction<WrapperFnTy>(WrapperFnAddr);
+ return WrapperFn(ArgBuffer.data(), ArgBuffer.size());
+ }
+
+ void closeConnection() { Finished = true; }
+
+ std::string TripleStr;
+ uint64_t PageSize = 0;
+ Optional<std::string> ProgramName;
+ RPCEndpointT &EP;
+ std::atomic<bool> Finished{false};
+ DenseMap<tpctypes::DylibHandle, sys::DynamicLibrary> Dylibs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
new file mode 100644
index 000000000000..811c50e3ce4d
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
@@ -0,0 +1,41 @@
+//===----- RegisterEHFrames.h -- Register EH frame sections -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Support for dynamically registering and deregistering eh-frame sections
+// in-process via libunwind.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// Register frames in the given eh-frame section with libunwind.
+Error registerEHFrameSection(const void *EHFrameSectionAddr,
+ size_t EHFrameSectionSize);
+
+/// Unregister frames in the given eh-frame section with libunwind.
+Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
+ size_t EHFrameSectionSize);
+
+} // end namespace orc
+} // end namespace llvm
+
+extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
+llvm_orc_registerEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
+
+extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
+llvm_orc_deregisterEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h
new file mode 100644
index 000000000000..1d2f6d2be089
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h
@@ -0,0 +1,38 @@
+//===-- TargetExecutionUtils.h - Utils for execution in target --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for execution in the target process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+namespace orc {
+
+/// Run a main function, returning the result.
+///
+/// If the optional ProgramName argument is given then it will be inserted
+/// before the strings in Args as the first argument to the called function.
+///
+/// It is legal to have an empty argument list and no program name, however
+/// many main functions will expect a name argument at least, and will fail
+/// if none is provided.
+int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args,
+ Optional<StringRef> ProgramName = None);
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
new file mode 100644
index 000000000000..b60b1ca6e372
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
@@ -0,0 +1,218 @@
+//===--- TargetProcessControl.h - Target process control APIs ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for interacting with target processes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+#include <future>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// TargetProcessControl supports interaction with a JIT target process.
+class TargetProcessControl {
+public:
+ /// APIs for manipulating memory in the target process.
+ class MemoryAccess {
+ public:
+ /// Callback function for asynchronous writes.
+ using WriteResultFn = unique_function<void(Error)>;
+
+ virtual ~MemoryAccess();
+
+ virtual void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ Error writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt8s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt16s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt32s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt64s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeBuffers(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+ };
+
+ /// A pair of a dylib and a set of symbols to be looked up.
+ struct LookupRequest {
+ LookupRequest(tpctypes::DylibHandle Handle, const SymbolLookupSet &Symbols)
+ : Handle(Handle), Symbols(Symbols) {}
+ tpctypes::DylibHandle Handle;
+ const SymbolLookupSet &Symbols;
+ };
+
+ virtual ~TargetProcessControl();
+
+ /// Intern a symbol name in the SymbolStringPool.
+ SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); }
+
+ /// Return a shared pointer to the SymbolStringPool for this instance.
+ std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; }
+
+ /// Return the Triple for the target process.
+ const Triple &getTargetTriple() const { return TargetTriple; }
+
+ /// Get the page size for the target process.
+ unsigned getPageSize() const { return PageSize; }
+
+ /// Return a MemoryAccess object for the target process.
+ MemoryAccess &getMemoryAccess() const { return *MemAccess; }
+
+ /// Return a JITLinkMemoryManager for the target process.
+ jitlink::JITLinkMemoryManager &getMemMgr() const { return *MemMgr; }
+
+ /// Load the dynamic library at the given path and return a handle to it.
+ /// If LibraryPath is null this function will return the global handle for
+ /// the target process.
+ virtual Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) = 0;
+
+ /// Search for symbols in the target process.
+ ///
+ /// The result of the lookup is a 2-dimentional array of target addresses
+ /// that correspond to the lookup order. If a required symbol is not
+ /// found then this method will return an error. If a weakly referenced
+ /// symbol is not found then it be assigned a '0' value in the result.
+ /// that correspond to the lookup order.
+ virtual Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(ArrayRef<LookupRequest> Request) = 0;
+
+ /// Run function with a main-like signature.
+ virtual Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+ ArrayRef<std::string> Args) = 0;
+
+ /// Run a wrapper function with signature:
+ ///
+ /// \code{.cpp}
+ /// CWrapperFunctionResult fn(uint8_t *Data, uint64_t Size);
+ /// \endcode{.cpp}
+ ///
+ virtual Expected<tpctypes::WrapperFunctionResult>
+ runWrapper(JITTargetAddress WrapperFnAddr, ArrayRef<uint8_t> ArgBuffer) = 0;
+
+ /// Disconnect from the target process.
+ ///
+ /// This should be called after the JIT session is shut down.
+ virtual Error disconnect() = 0;
+
+protected:
+ TargetProcessControl(std::shared_ptr<SymbolStringPool> SSP)
+ : SSP(std::move(SSP)) {}
+
+ std::shared_ptr<SymbolStringPool> SSP;
+ Triple TargetTriple;
+ unsigned PageSize = 0;
+ MemoryAccess *MemAccess = nullptr;
+ jitlink::JITLinkMemoryManager *MemMgr = nullptr;
+};
+
+/// A TargetProcessControl implementation targeting the current process.
+class SelfTargetProcessControl : public TargetProcessControl,
+ private TargetProcessControl::MemoryAccess {
+public:
+ SelfTargetProcessControl(
+ std::shared_ptr<SymbolStringPool> SSP, Triple TargetTriple,
+ unsigned PageSize, std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
+
+ /// Create a SelfTargetProcessControl with the given memory manager.
+ /// If no memory manager is given a jitlink::InProcessMemoryManager will
+ /// be used by default.
+ static Expected<std::unique_ptr<SelfTargetProcessControl>>
+ Create(std::shared_ptr<SymbolStringPool> SSP,
+ std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr = nullptr);
+
+ Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
+
+ Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(ArrayRef<LookupRequest> Request) override;
+
+ Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+ ArrayRef<std::string> Args) override;
+
+ Expected<tpctypes::WrapperFunctionResult>
+ runWrapper(JITTargetAddress WrapperFnAddr,
+ ArrayRef<uint8_t> ArgBuffer) override;
+
+ Error disconnect() override;
+
+private:
+ void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
+ char GlobalManglingPrefix = 0;
+ std::vector<std::unique_ptr<sys::DynamicLibrary>> DynamicLibraries;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
index 58c96737e580..82f2b7464953 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
@@ -162,7 +162,7 @@ using GVModifier = std::function<void(GlobalValue &)>;
/// Clones the given module on to a new context.
ThreadSafeModule
-cloneToNewContext(ThreadSafeModule &TSMW,
+cloneToNewContext(const ThreadSafeModule &TSMW,
GVPredicate ShouldCloneDef = GVPredicate(),
GVModifier UpdateClonedDefSource = GVModifier());
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
index 1b3ce1127e4a..9b83092e653f 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -271,11 +271,11 @@ private:
object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
bool ProcessAllSections,
- unique_function<Error(const object::ObjectFile &Obj,
- std::unique_ptr<LoadedObjectInfo>,
+ unique_function<Error(const object::ObjectFile &Obj, LoadedObjectInfo &,
std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded,
- unique_function<void(object::OwningBinary<object::ObjectFile> O, Error)>
+ unique_function<void(object::OwningBinary<object::ObjectFile> O,
+ std::unique_ptr<LoadedObjectInfo>, Error)>
OnEmitted);
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
@@ -298,10 +298,11 @@ void jitLinkForORC(
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
bool ProcessAllSections,
unique_function<Error(const object::ObjectFile &Obj,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo>,
+ RuntimeDyld::LoadedObjectInfo &,
std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded,
- unique_function<void(object::OwningBinary<object::ObjectFile>, Error)>
+ unique_function<void(object::OwningBinary<object::ObjectFile>,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
OnEmitted);
} // end namespace llvm