Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:54

0001 //===---- SimpleRemoteEPC.h - Simple remote executor control ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Simple remote executor process control.
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   /// A setup object containing callbacks to construct a memory manager and
0036   /// memory access object. Both are optional. If not specified,
0037   /// EPCGenericJITLinkMemoryManager and EPCGenericMemoryAccess will be used.
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   /// Create a SimpleRemoteEPC using the given transport type and args.
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 } // end namespace orc
0147 } // end namespace llvm
0148 
0149 #endif // LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H