File indexing completed on 2026-05-10 08:43:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
0014 #define LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
0015
0016 #include "llvm/ADT/DenseMap.h"
0017 #include "llvm/ADT/FunctionExtras.h"
0018 #include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
0019 #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
0020 #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
0021 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
0022 #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
0023 #include "llvm/Support/Error.h"
0024 #include "llvm/Support/MSVCErrorWorkarounds.h"
0025
0026 #include <future>
0027
0028 namespace llvm {
0029 namespace orc {
0030
0031 class SimpleRemoteEPC : public ExecutorProcessControl,
0032 public SimpleRemoteEPCTransportClient,
0033 private DylibManager {
0034 public:
0035
0036
0037
0038 struct Setup {
0039 using CreateMemoryManagerFn =
0040 Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>(
0041 SimpleRemoteEPC &);
0042 using CreateMemoryAccessFn =
0043 Expected<std::unique_ptr<MemoryAccess>>(SimpleRemoteEPC &);
0044
0045 unique_function<CreateMemoryManagerFn> CreateMemoryManager;
0046 unique_function<CreateMemoryAccessFn> CreateMemoryAccess;
0047 };
0048
0049
0050 template <typename TransportT, typename... TransportTCtorArgTs>
0051 static Expected<std::unique_ptr<SimpleRemoteEPC>>
0052 Create(std::unique_ptr<TaskDispatcher> D, Setup S,
0053 TransportTCtorArgTs &&...TransportTCtorArgs) {
0054 std::unique_ptr<SimpleRemoteEPC> SREPC(
0055 new SimpleRemoteEPC(std::make_shared<SymbolStringPool>(),
0056 std::move(D)));
0057 auto T = TransportT::Create(
0058 *SREPC, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
0059 if (!T)
0060 return T.takeError();
0061 SREPC->T = std::move(*T);
0062 if (auto Err = SREPC->setup(std::move(S)))
0063 return joinErrors(std::move(Err), SREPC->disconnect());
0064 return std::move(SREPC);
0065 }
0066
0067 SimpleRemoteEPC(const SimpleRemoteEPC &) = delete;
0068 SimpleRemoteEPC &operator=(const SimpleRemoteEPC &) = delete;
0069 SimpleRemoteEPC(SimpleRemoteEPC &&) = delete;
0070 SimpleRemoteEPC &operator=(SimpleRemoteEPC &&) = delete;
0071 ~SimpleRemoteEPC();
0072
0073 Expected<int32_t> runAsMain(ExecutorAddr MainFnAddr,
0074 ArrayRef<std::string> Args) override;
0075
0076 Expected<int32_t> runAsVoidFunction(ExecutorAddr VoidFnAddr) override;
0077
0078 Expected<int32_t> runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override;
0079
0080 void callWrapperAsync(ExecutorAddr WrapperFnAddr,
0081 IncomingWFRHandler OnComplete,
0082 ArrayRef<char> ArgBuffer) override;
0083
0084 Error disconnect() override;
0085
0086 Expected<HandleMessageAction>
0087 handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
0088 SimpleRemoteEPCArgBytesVector ArgBytes) override;
0089
0090 void handleDisconnect(Error Err) override;
0091
0092 private:
0093 SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP,
0094 std::unique_ptr<TaskDispatcher> D)
0095 : ExecutorProcessControl(std::move(SSP), std::move(D)) {
0096 this->DylibMgr = this;
0097 }
0098
0099 static Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
0100 createDefaultMemoryManager(SimpleRemoteEPC &SREPC);
0101 static Expected<std::unique_ptr<MemoryAccess>>
0102 createDefaultMemoryAccess(SimpleRemoteEPC &SREPC);
0103
0104 Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
0105 ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
0106
0107 Error handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
0108 SimpleRemoteEPCArgBytesVector ArgBytes);
0109 Error setup(Setup S);
0110
0111 Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
0112 SimpleRemoteEPCArgBytesVector ArgBytes);
0113 void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
0114 SimpleRemoteEPCArgBytesVector ArgBytes);
0115 Error handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes);
0116
0117 uint64_t getNextSeqNo() { return NextSeqNo++; }
0118 void releaseSeqNo(uint64_t SeqNo) {}
0119
0120 Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
0121
0122 void lookupSymbolsAsync(ArrayRef<LookupRequest> Request,
0123 SymbolLookupCompleteFn F) override;
0124
0125 using PendingCallWrapperResultsMap =
0126 DenseMap<uint64_t, IncomingWFRHandler>;
0127
0128 std::mutex SimpleRemoteEPCMutex;
0129 std::condition_variable DisconnectCV;
0130 bool Disconnected = false;
0131 Error DisconnectErr = Error::success();
0132
0133 std::unique_ptr<SimpleRemoteEPCTransport> T;
0134 std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
0135 std::unique_ptr<MemoryAccess> OwnedMemAccess;
0136
0137 std::unique_ptr<EPCGenericDylibManager> EPCDylibMgr;
0138 ExecutorAddr RunAsMainAddr;
0139 ExecutorAddr RunAsVoidFunctionAddr;
0140 ExecutorAddr RunAsIntFunctionAddr;
0141
0142 uint64_t NextSeqNo = 0;
0143 PendingCallWrapperResultsMap PendingCallWrapperResults;
0144 };
0145
0146 }
0147 }
0148
0149 #endif