[llvm] 2269a94 - Revert 5629afea910 and bb27e456435 while I look into bot failures.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 11 02:02:32 PDT 2021
Author: Lang Hames
Date: 2021-09-11T19:02:11+10:00
New Revision: 2269a941a450a0d395161cfb792be58870b2875b
URL: https://github.com/llvm/llvm-project/commit/2269a941a450a0d395161cfb792be58870b2875b
DIFF: https://github.com/llvm/llvm-project/commit/2269a941a450a0d395161cfb792be58870b2875b.diff
LOG: Revert 5629afea910 and bb27e456435 while I look into bot failures.
This reverts commit 5629afea9109d3b72064cbe70e1ca91ffb9dc0a2 ("[ORC] Add missing
include."), and bb27e4564355243e479cab40885d6e0f7f640572 ("[ORC] Add
SimpleRemoteEPC: ExecutorProcessControl over SPS + abstract transport.").
The SimpleRemoteEPC patch currently assumes availability of threads, and needs
to be rewritten with LLVM_ENABLE_THREADS guards.
Added:
llvm/lib/ExecutionEngine/Orc/EPCGenericMemoryAccess.cpp
Modified:
llvm/include/llvm/ExecutionEngine/Orc/Core.h
llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h
llvm/include/llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h
llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp
llvm/lib/ExecutionEngine/Orc/Shared/CMakeLists.txt
llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
llvm/tools/llvm-jitlink/llvm-jitlink.cpp
llvm/tools/llvm-jitlink/llvm-jitlink.h
Removed:
llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h
llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h
llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h
llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp
llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp
llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp
################################################################################
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
index 062b1f3e93e63..331a921c8abea 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -1302,8 +1302,7 @@ class ExecutionSession {
/// object.
ExecutionSession(std::unique_ptr<ExecutorProcessControl> EPC);
- /// End the session. Closes all JITDylibs and disconnects from the
- /// executor.
+ /// End the session. Closes all JITDylibs.
Error endSession();
/// Get the ExecutorProcessControl object associated with this
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h
index 48007129fd9f9..0dd1e6a7562a5 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h
@@ -38,6 +38,11 @@ class EPCGenericJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
EPCGenericJITLinkMemoryManager(ExecutorProcessControl &EPC, FuncAddrs FAs)
: EPC(EPC), FAs(FAs) {}
+ /// Create using the standard memory allocation function names from the
+ /// ORCTargetProcess library.
+ static Expected<std::unique_ptr<EPCGenericJITLinkMemoryManager>>
+ CreateUsingOrcRTFuncs(ExecutorProcessControl &EPC);
+
Expected<std::unique_ptr<Allocation>>
allocate(const jitlink::JITLinkDylib *JD,
const SegmentsRequestMap &Request) override;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h
index 80a84ce9d0132..fe9d1c13881cb 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h
@@ -39,6 +39,11 @@ class EPCGenericMemoryAccess : public ExecutorProcessControl::MemoryAccess {
EPCGenericMemoryAccess(ExecutorProcessControl &EPC, FuncAddrs FAs)
: EPC(EPC), FAs(FAs) {}
+ /// Create using the standard memory access function names from the
+ /// ORCTargetProcess library.
+ static Expected<std::unique_ptr<EPCGenericMemoryAccess>>
+ CreateUsingOrcRTFuncs(ExecutorProcessControl &EPC);
+
void writeUInt8sAsync(ArrayRef<tpctypes::UInt8Write> Ws,
WriteResultFn OnWriteComplete) override {
using namespace shared;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h
deleted file mode 100644
index 7d1df1632b367..0000000000000
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h
+++ /dev/null
@@ -1,250 +0,0 @@
-//===--- SimpleRemoteEPCUtils.h - Utils for Simple Remote EPC ---*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Message definitions and other utilities for SimpleRemoteEPC and
-// SimpleRemoteEPCServer.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
-#define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
-#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
-#include "llvm/Support/Error.h"
-
-#include <mutex>
-#include <string>
-#include <thread>
-
-namespace llvm {
-namespace orc {
-
-namespace SimpleRemoteEPCDefaultBootstrapSymbolNames {
-extern const char *ExecutorSessionObjectName;
-extern const char *DispatchFnName;
-} // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
-
-enum class SimpleRemoteEPCOpcode : uint8_t {
- FirstOpC,
- Setup = FirstOpC,
- Hangup,
- Result,
- CallWrapper,
- LastOpC = CallWrapper
-};
-
-struct SimpleRemoteEPCExecutorInfo {
- std::string TargetTriple;
- uint64_t PageSize;
- StringMap<ExecutorAddress> BootstrapSymbols;
-
- Expected<ExecutorAddress> getBootstrapSymbol(StringRef Name) const {
- auto I = BootstrapSymbols.find(Name);
- if (I == BootstrapSymbols.end())
- return make_error<StringError>("Symbol \"" + Name +
- "\" not found in "
- "bootstrap symbols map",
- inconvertibleErrorCode());
- return I->second;
- }
-
- Error getBootstrapSymbols(
- ArrayRef<std::pair<ExecutorAddress &, StringRef>> Pairs) const {
- for (auto &KV : Pairs) {
- if (auto A = getBootstrapSymbol(KV.second))
- KV.first = *A;
- else
- return A.takeError();
- }
- return Error::success();
- }
-};
-
-using SimpleRemoteEPCArgBytesVector = SmallVector<char, 128>;
-
-class SimpleRemoteEPCTransportClient {
-public:
- enum HandleMessageAction { ContinueSession, EndSession };
-
- virtual ~SimpleRemoteEPCTransportClient();
-
- /// Handle receipt of a message.
- ///
- /// Returns an Error if the message cannot be handled, 'EndSession' if the
- /// client will not accept any further messages, and 'ContinueSession'
- /// otherwise.
- virtual Expected<HandleMessageAction>
- handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) = 0;
-
- /// Handle a disconnection from the underlying transport. No further messages
- /// should be sent to handleMessage after this is called.
- /// Err may contain an Error value indicating unexpected disconnection. This
- /// allows clients to log such errors, but no attempt should be made at
- /// recovery (which should be handled inside the transport class, if it is
- /// supported at all).
- virtual void handleDisconnect(Error Err) = 0;
-};
-
-class SimpleRemoteEPCTransport {
-public:
- virtual ~SimpleRemoteEPCTransport();
-
- /// Send a SimpleRemoteEPC message.
- ///
- /// This function may be called concurrently. Subclasses should implement
- /// locking if required for the underlying transport.
- virtual Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddress TagAddr,
- ArrayRef<char> ArgBytes) = 0;
-
- /// Trigger disconnection from the transport. The implementation should
- /// respond by calling handleDisconnect on the client once disconnection
- /// is complete.
- virtual void disconnect() = 0;
-};
-
-/// Uses read/write on FileDescriptors for transport.
-class FDSimpleRemoteEPCTransport : public SimpleRemoteEPCTransport {
-public:
- /// Create a FDSimpleRemoteEPCTransport using the given FDs for
- /// reading (InFD) and writing (OutFD).
- static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
- Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD);
-
- /// Create a FDSimpleRemoteEPCTransport using the given FD for both
- /// reading and writing.
- static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
- Create(SimpleRemoteEPCTransportClient &C, int FD) {
- return Create(C, FD, FD);
- }
-
- ~FDSimpleRemoteEPCTransport() override;
-
- Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddress TagAddr, ArrayRef<char> ArgBytes) override;
-
- void disconnect() override;
-
-private:
- FDSimpleRemoteEPCTransport(SimpleRemoteEPCTransportClient &C, int InFD,
- int OutFD);
-
- Error readBytes(char *Dst, size_t Size, bool *IsEOF = nullptr);
- int writeBytes(const char *Src, size_t Size);
- void listenLoop();
-
- std::mutex M;
- SimpleRemoteEPCTransportClient &C;
- std::thread ListenerThread;
- int InFD, OutFD;
-};
-
-struct RemoteSymbolLookupSetElement {
- std::string Name;
- bool Required;
-};
-
-using RemoteSymbolLookupSet = std::vector<RemoteSymbolLookupSetElement>;
-
-struct RemoteSymbolLookup {
- uint64_t H;
- RemoteSymbolLookupSet Symbols;
-};
-
-namespace shared {
-
-using SPSRemoteSymbolLookupSetElement = SPSTuple<SPSString, bool>;
-
-using SPSRemoteSymbolLookupSet = SPSSequence<SPSRemoteSymbolLookupSetElement>;
-
-using SPSRemoteSymbolLookup = SPSTuple<uint64_t, SPSRemoteSymbolLookupSet>;
-
-/// Tuple containing target triple, page size, and bootstrap symbols.
-using SPSSimpleRemoteEPCExecutorInfo =
- SPSTuple<SPSString, uint64_t,
- SPSSequence<SPSTuple<SPSString, SPSExecutorAddress>>>;
-
-template <>
-class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
- RemoteSymbolLookupSetElement> {
-public:
- static size_t size(const RemoteSymbolLookupSetElement &V) {
- return SPSArgList<SPSString, bool>::size(V.Name, V.Required);
- }
-
- static size_t serialize(SPSOutputBuffer &OB,
- const RemoteSymbolLookupSetElement &V) {
- return SPSArgList<SPSString, bool>::serialize(OB, V.Name, V.Required);
- }
-
- static size_t deserialize(SPSInputBuffer &IB,
- RemoteSymbolLookupSetElement &V) {
- return SPSArgList<SPSString, bool>::deserialize(IB, V.Name, V.Required);
- }
-};
-
-template <>
-class SPSSerializationTraits<SPSRemoteSymbolLookup, RemoteSymbolLookup> {
-public:
- static size_t size(const RemoteSymbolLookup &V) {
- return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::size(V.H, V.Symbols);
- }
-
- static size_t serialize(SPSOutputBuffer &OB, const RemoteSymbolLookup &V) {
- return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::serialize(OB, V.H,
- V.Symbols);
- }
-
- static size_t deserialize(SPSInputBuffer &IB, RemoteSymbolLookup &V) {
- return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::deserialize(
- IB, V.H, V.Symbols);
- }
-};
-
-template <>
-class SPSSerializationTraits<SPSSimpleRemoteEPCExecutorInfo,
- SimpleRemoteEPCExecutorInfo> {
-public:
- static size_t size(const SimpleRemoteEPCExecutorInfo &SI) {
- return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::size(
- SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
- }
-
- static bool serialize(SPSOutputBuffer &OB,
- const SimpleRemoteEPCExecutorInfo &SI) {
- return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::serialize(
- OB, SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
- }
-
- static bool deserialize(SPSInputBuffer &IB, SimpleRemoteEPCExecutorInfo &SI) {
- return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::deserialize(
- IB, SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
- }
-};
-
-using SPSRunAsMainSignature = int64_t(SPSExecutorAddress,
- SPSSequence<SPSString>);
-
-using SPSLoadDylibSignature =
- SPSExpected<SPSExecutorAddress>(SPSExecutorAddress, SPSString, uint64_t);
-
-using SPSLookupSymbolsSignature =
- SPSExpected<SPSSequence<SPSSequence<SPSExecutorAddress>>>(
- SPSExecutorAddress, SPSSequence<SPSRemoteSymbolLookup>);
-
-} // end namespace shared
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h b/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h
deleted file mode 100644
index 252474abecbd4..0000000000000
--- a/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h
+++ /dev/null
@@ -1,136 +0,0 @@
-//===---- SimpleRemoteEPC.h - Simple remote executor 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Simple remote executor process control.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
-#define LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
-#include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
-#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
-#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MSVCErrorWorkarounds.h"
-
-#include <future>
-
-namespace llvm {
-namespace orc {
-
-class SimpleRemoteEPC : public ExecutorProcessControl,
- public SimpleRemoteEPCTransportClient {
-public:
- /// Create a SimpleRemoteEPC using the given transport type and args.
- template <typename TransportT, typename... TransportTCtorArgTs>
- static Expected<std::unique_ptr<SimpleRemoteEPC>>
- Create(TransportTCtorArgTs &&...TransportTCtorArgs) {
- std::unique_ptr<SimpleRemoteEPC> SREPC(
- new SimpleRemoteEPC(std::make_shared<SymbolStringPool>()));
-
- // Prepare for setup packet.
- std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP;
- auto EIF = EIP.get_future();
- SREPC->prepareToReceiveSetupMessage(EIP);
- auto T = TransportT::Create(
- *SREPC, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
- if (!T)
- return T.takeError();
- auto EI = EIF.get();
- if (!EI) {
- (*T)->disconnect();
- return EI.takeError();
- }
- if (auto Err = SREPC->setup(std::move(*T), std::move(*EI)))
- return joinErrors(std::move(Err), SREPC->disconnect());
- return std::move(SREPC);
- }
-
- SimpleRemoteEPC(const SimpleRemoteEPC &) = delete;
- SimpleRemoteEPC &operator=(const SimpleRemoteEPC &) = delete;
- SimpleRemoteEPC(SimpleRemoteEPC &&) = delete;
- SimpleRemoteEPC &operator=(SimpleRemoteEPC &) = delete;
- ~SimpleRemoteEPC();
-
- /// Called at the end of the construction process to set up the instance.
- ///
- /// Override to set up custom memory manager and/or memory access objects.
- /// This method must be called at the *end* of the subclass's
- /// implementation.
- virtual Error setup(std::unique_ptr<SimpleRemoteEPCTransport> T,
- const SimpleRemoteEPCExecutorInfo &EI);
-
- 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;
-
- void callWrapperAsync(SendResultFunction OnComplete,
- JITTargetAddress WrapperFnAddr,
- ArrayRef<char> ArgBuffer) override;
-
- Error disconnect() override;
-
- Expected<HandleMessageAction>
- handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) override;
-
- void handleDisconnect(Error Err) override;
-
-protected:
- void setMemoryManager(std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
- void setMemoryAccess(std::unique_ptr<MemoryAccess> MemAccess);
-
-private:
- SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP)
- : ExecutorProcessControl(std::move(SSP)) {}
-
- Error setupDefaultMemoryManager(const SimpleRemoteEPCExecutorInfo &EI);
- Error setupDefaultMemoryAccess(const SimpleRemoteEPCExecutorInfo &EI);
-
- Error handleSetup(uint64_t SeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes);
- void prepareToReceiveSetupMessage(
- std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> &ExecInfoP);
-
- Error handleResult(uint64_t SeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes);
- void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes);
-
- uint64_t getNextSeqNo() { return NextSeqNo++; }
- void releaseSeqNo(uint64_t SeqNo) {}
-
- using PendingCallWrapperResultsMap = DenseMap<uint64_t, SendResultFunction>;
-
- std::atomic_bool Disconnected{false};
- std::mutex SimpleRemoteEPCMutex;
- std::unique_ptr<SimpleRemoteEPCTransport> T;
- std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
- std::unique_ptr<MemoryAccess> OwnedMemAccess;
-
- ExecutorAddress LoadDylibAddr;
- ExecutorAddress LookupSymbolsAddr;
- ExecutorAddress RunAsMainAddr;
-
- uint64_t NextSeqNo = 0;
- PendingCallWrapperResultsMap PendingCallWrapperResults;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h
deleted file mode 100644
index 838e04c9ca1de..0000000000000
--- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h
+++ /dev/null
@@ -1,146 +0,0 @@
-//===---- SimpleRemoteEPCServer.h - EPC over abstract 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
-//
-//===----------------------------------------------------------------------===//
-//
-// EPC over simple abstract channel.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
-#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
-#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
-#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/Error.h"
-
-#include <condition_variable>
-#include <future>
-#include <memory>
-#include <mutex>
-
-namespace llvm {
-namespace orc {
-
-/// A simple EPC server implementation.
-class SimpleRemoteEPCServer : public SimpleRemoteEPCTransportClient {
-public:
- using ReportErrorFunction = unique_function<void(Error)>;
-
- class Dispatcher {
- public:
- virtual ~Dispatcher();
- virtual void dispatch(unique_function<void()> Work) = 0;
- virtual void shutdown() = 0;
- };
-
- class ThreadDispatcher : public Dispatcher {
- public:
- void dispatch(unique_function<void()> Work) override;
- void shutdown() override;
-
- private:
- std::mutex DispatchMutex;
- bool Running = true;
- size_t Outstanding = 0;
- std::condition_variable OutstandingCV;
- };
-
- static StringMap<ExecutorAddress> defaultBootstrapSymbols();
-
- template <typename TransportT, typename... TransportTCtorArgTs>
- static Expected<std::unique_ptr<SimpleRemoteEPCServer>>
- Create(std::unique_ptr<Dispatcher> D,
- StringMap<ExecutorAddress> BootstrapSymbols,
- TransportTCtorArgTs &&...TransportTCtorArgs) {
- auto SREPCServer = std::make_unique<SimpleRemoteEPCServer>();
- SREPCServer->D = std::move(D);
- SREPCServer->ReportError = [](Error Err) {
- logAllUnhandledErrors(std::move(Err), errs(), "SimpleRemoteEPCServer ");
- };
- auto T = TransportT::Create(
- *SREPCServer, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
- if (!T)
- return T.takeError();
- SREPCServer->T = std::move(*T);
- if (auto Err = SREPCServer->sendSetupMessage(std::move(BootstrapSymbols)))
- return std::move(Err);
- return std::move(SREPCServer);
- }
-
- /// Set an error reporter for this server.
- void setErrorReporter(ReportErrorFunction ReportError) {
- this->ReportError = std::move(ReportError);
- }
-
- /// Call to handle an incoming message.
- ///
- /// Returns 'Disconnect' if the message is a 'detach' message from the remote
- /// otherwise returns 'Continue'. If the server has moved to an error state,
- /// returns an error, which should be reported and treated as a 'Disconnect'.
- Expected<HandleMessageAction>
- handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) override;
-
- Error waitForDisconnect();
-
- void handleDisconnect(Error Err) override;
-
-private:
- Error sendSetupMessage(StringMap<ExecutorAddress> BootstrapSymbols);
-
- Error handleResult(uint64_t SeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes);
- void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes);
-
- static shared::detail::CWrapperFunctionResult
- loadDylibWrapper(const char *ArgData, size_t ArgSize);
-
- static shared::detail::CWrapperFunctionResult
- lookupSymbolsWrapper(const char *ArgData, size_t ArgSize);
-
- Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path,
- uint64_t Mode);
-
- Expected<std::vector<std::vector<ExecutorAddress>>>
- lookupSymbols(const std::vector<RemoteSymbolLookup> &L);
-
- shared::WrapperFunctionResult
- doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
-
- static shared::detail::CWrapperFunctionResult
- jitDispatchEntry(void *DispatchCtx, const void *FnTag, const char *ArgData,
- size_t ArgSize);
-
- uint64_t getNextSeqNo() { return NextSeqNo++; }
- void releaseSeqNo(uint64_t) {}
-
- using PendingJITDispatchResultsMap =
- DenseMap<uint64_t, std::promise<shared::WrapperFunctionResult> *>;
-
- std::mutex ServerStateMutex;
- std::condition_variable ShutdownCV;
- enum { ServerRunning, ServerShuttingDown, ServerShutDown } RunState;
- Error ShutdownErr = Error::success();
- std::unique_ptr<SimpleRemoteEPCTransport> T;
- std::unique_ptr<Dispatcher> D;
- ReportErrorFunction ReportError;
-
- uint64_t NextSeqNo = 0;
- PendingJITDispatchResultsMap PendingJITDispatchResults;
- std::vector<sys::DynamicLibrary> Dylibs;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
index 8e8e0d3ea7941..982a93cc60c0b 100644
--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
@@ -8,6 +8,7 @@ add_llvm_component_library(LLVMOrcJIT
EPCDebugObjectRegistrar.cpp
EPCEHFrameRegistrar.cpp
EPCGenericJITLinkMemoryManager.cpp
+ EPCGenericMemoryAccess.cpp
EPCIndirectionUtils.cpp
ExecutionUtils.cpp
IndirectionUtils.cpp
@@ -26,7 +27,6 @@ add_llvm_component_library(LLVMOrcJIT
OrcABISupport.cpp
OrcV2CBindings.cpp
RTDyldObjectLinkingLayer.cpp
- SimpleRemoteEPC.cpp
Speculation.cpp
SpeculateAnalyses.cpp
ExecutorProcessControl.cpp
diff --git a/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp b/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp
index 5303b7cf2e5a5..ac6de224c9c5f 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp
@@ -86,6 +86,32 @@ class EPCGenericJITLinkMemoryManager::Alloc
SegInfoMap Segs;
};
+/// Create from a ExecutorProcessControl instance.
+Expected<std::unique_ptr<EPCGenericJITLinkMemoryManager>>
+EPCGenericJITLinkMemoryManager::CreateUsingOrcRTFuncs(
+ ExecutorProcessControl &EPC) {
+
+ auto H = EPC.loadDylib("");
+ if (!H)
+ return H.takeError();
+
+ StringRef GlobalPrefix = "";
+ if (EPC.getTargetTriple().isOSBinFormatMachO())
+ GlobalPrefix = "_";
+
+ FuncAddrs FAs;
+ if (auto Err = lookupAndRecordAddrs(
+ EPC, *H,
+ {{EPC.intern((GlobalPrefix + "__orc_rt_reserve").str()), &FAs.Reserve},
+ {EPC.intern((GlobalPrefix + "__orc_rt_finalize").str()),
+ &FAs.Finalize},
+ {EPC.intern((GlobalPrefix + "__orc_rt_deallocate").str()),
+ &FAs.Deallocate}}))
+ return std::move(Err);
+
+ return std::make_unique<EPCGenericJITLinkMemoryManager>(EPC, std::move(FAs));
+}
+
Expected<std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>>
EPCGenericJITLinkMemoryManager::allocate(const jitlink::JITLinkDylib *JD,
const SegmentsRequestMap &Request) {
diff --git a/llvm/lib/ExecutionEngine/Orc/EPCGenericMemoryAccess.cpp b/llvm/lib/ExecutionEngine/Orc/EPCGenericMemoryAccess.cpp
new file mode 100644
index 0000000000000..e4ecd479e22d2
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/EPCGenericMemoryAccess.cpp
@@ -0,0 +1,46 @@
+//===----- EPCGenericMemoryAccess.cpp - Generic EPC MemoryAccess impl -----===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
+#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
+
+namespace llvm {
+namespace orc {
+
+/// Create from a ExecutorProcessControl instance.
+Expected<std::unique_ptr<EPCGenericMemoryAccess>>
+EPCGenericMemoryAccess::CreateUsingOrcRTFuncs(ExecutorProcessControl &EPC) {
+
+ auto H = EPC.loadDylib("");
+ if (!H)
+ return H.takeError();
+
+ StringRef GlobalPrefix = "";
+ if (EPC.getTargetTriple().isOSBinFormatMachO())
+ GlobalPrefix = "_";
+
+ FuncAddrs FAs;
+ if (auto Err = lookupAndRecordAddrs(
+ EPC, *H,
+ {{EPC.intern((GlobalPrefix + "__orc_rt_write_uint8s_wrapper").str()),
+ &FAs.WriteUInt8s},
+ {EPC.intern((GlobalPrefix + "__orc_rt_write_uint16s_wrapper").str()),
+ &FAs.WriteUInt16s},
+ {EPC.intern((GlobalPrefix + "__orc_rt_write_uint32s_wrapper").str()),
+ &FAs.WriteUInt32s},
+ {EPC.intern((GlobalPrefix + "__orc_rt_write_uint64s_wrapper").str()),
+ &FAs.WriteUInt64s},
+ {EPC.intern((GlobalPrefix + "__orc_rt_write_buffers_wrapper").str()),
+ &FAs.WriteBuffers}}))
+ return std::move(Err);
+
+ return std::make_unique<EPCGenericMemoryAccess>(EPC, std::move(FAs));
+}
+
+} // end namespace orc
+} // end namespace llvm
diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/Shared/CMakeLists.txt
index 74805720678c9..dddfda1a89539 100644
--- a/llvm/lib/ExecutionEngine/Orc/Shared/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/Shared/CMakeLists.txt
@@ -1,7 +1,6 @@
add_llvm_component_library(LLVMOrcShared
OrcError.cpp
RPCError.cpp
- SimpleRemoteEPCUtils.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/Orc
diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp
deleted file mode 100644
index a9a77ae688318..0000000000000
--- a/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-//===------ SimpleRemoteEPCUtils.cpp - Utils for Simple Remote EPC --------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Message definitions and other utilities for SimpleRemoteEPC and
-// SimpleRemoteEPCServer.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/FormatVariadic.h"
-
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-namespace {
-
-struct FDMsgHeader {
- static constexpr unsigned MsgSizeOffset = 0;
- static constexpr unsigned OpCOffset = MsgSizeOffset + sizeof(uint64_t);
- static constexpr unsigned SeqNoOffset = OpCOffset + sizeof(uint64_t);
- static constexpr unsigned TagAddrOffset = SeqNoOffset + sizeof(uint64_t);
- static constexpr unsigned Size = TagAddrOffset + sizeof(uint64_t);
-};
-
-} // namespace
-
-namespace llvm {
-namespace orc {
-namespace SimpleRemoteEPCDefaultBootstrapSymbolNames {
-
-const char *ExecutorSessionObjectName =
- "__llvm_orc_SimpleRemoteEPC_dispatch_ctx";
-const char *DispatchFnName = "__llvm_orc_SimpleRemoteEPC_dispatch_fn";
-
-} // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
-
-SimpleRemoteEPCTransportClient::~SimpleRemoteEPCTransportClient() {}
-SimpleRemoteEPCTransport::~SimpleRemoteEPCTransport() {}
-
-Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
-FDSimpleRemoteEPCTransport::Create(SimpleRemoteEPCTransportClient &C, int InFD,
- int OutFD) {
- if (InFD == -1)
- return make_error<StringError>("Invalid input file descriptor " +
- Twine(InFD),
- inconvertibleErrorCode());
- if (OutFD == -1)
- return make_error<StringError>("Invalid output file descriptor " +
- Twine(OutFD),
- inconvertibleErrorCode());
- std::unique_ptr<FDSimpleRemoteEPCTransport> FDT(
- new FDSimpleRemoteEPCTransport(C, InFD, OutFD));
- return FDT;
-}
-
-FDSimpleRemoteEPCTransport::FDSimpleRemoteEPCTransport(
- SimpleRemoteEPCTransportClient &C, int InFD, int OutFD)
- : C(C), InFD(InFD), OutFD(OutFD) {
- ListenerThread = std::thread([this]() { listenLoop(); });
-}
-
-FDSimpleRemoteEPCTransport::~FDSimpleRemoteEPCTransport() {
- ListenerThread.join();
-}
-
-Error FDSimpleRemoteEPCTransport::sendMessage(SimpleRemoteEPCOpcode OpC,
- uint64_t SeqNo,
- ExecutorAddress TagAddr,
- ArrayRef<char> ArgBytes) {
- char HeaderBuffer[FDMsgHeader::Size];
-
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::MsgSizeOffset)) =
- FDMsgHeader::Size + ArgBytes.size();
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::OpCOffset)) =
- static_cast<uint64_t>(OpC);
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::SeqNoOffset)) = SeqNo;
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::TagAddrOffset)) =
- TagAddr.getValue();
-
- std::lock_guard<std::mutex> Lock(M);
- if (OutFD == -1)
- return make_error<StringError>("FD-transport disconnected",
- inconvertibleErrorCode());
- if (int ErrNo = writeBytes(HeaderBuffer, FDMsgHeader::Size))
- return errorCodeToError(std::error_code(ErrNo, std::generic_category()));
- if (int ErrNo = writeBytes(ArgBytes.data(), ArgBytes.size()))
- return errorCodeToError(std::error_code(ErrNo, std::generic_category()));
- return Error::success();
-}
-
-void FDSimpleRemoteEPCTransport::disconnect() {
- int CloseInFD = -1, CloseOutFD = -1;
- {
- std::lock_guard<std::mutex> Lock(M);
- std::swap(InFD, CloseInFD);
- std::swap(OutFD, CloseOutFD);
- }
-
- // If CloseOutFD == CloseInFD then set CloseOutFD to -1 up-front so that we
- // don't double-close.
- if (CloseOutFD == CloseInFD)
- CloseOutFD = -1;
-
- // Close InFD.
- if (CloseInFD != -1)
- while (close(CloseInFD) == -1) {
- if (errno == EBADF)
- break;
- }
-
- // Close OutFD.
- if (CloseOutFD != -1) {
- while (close(CloseOutFD) == -1) {
- if (errno == EBADF)
- break;
- }
- }
-}
-
-static Error makeUnexpectedEOFError() {
- return make_error<StringError>("Unexpected end-of-file",
- inconvertibleErrorCode());
-}
-
-Error FDSimpleRemoteEPCTransport::readBytes(char *Dst, size_t Size,
- bool *IsEOF) {
- 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 (Read == 0) {
- if (Completed == 0 && IsEOF) {
- *IsEOF = true;
- return Error::success();
- } else
- return makeUnexpectedEOFError();
- } else if (ErrNo == EAGAIN || ErrNo == EINTR)
- continue;
- else {
- std::lock_guard<std::mutex> Lock(M);
- if (InFD == -1 && IsEOF) { // Disconnected locally. Pretend this is EOF.
- *IsEOF = true;
- return Error::success();
- }
- return errorCodeToError(
- std::error_code(ErrNo, std::generic_category()));
- }
- }
- Completed += Read;
- }
- return Error::success();
-}
-
-int FDSimpleRemoteEPCTransport::writeBytes(const char *Src, size_t Size) {
- 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 ErrNo;
- }
- Completed += Written;
- }
- return 0;
-}
-
-void FDSimpleRemoteEPCTransport::listenLoop() {
- Error Err = Error::success();
- do {
-
- char HeaderBuffer[FDMsgHeader::Size];
- // Read the header buffer.
- {
- bool IsEOF;
- if (auto Err2 = readBytes(HeaderBuffer, FDMsgHeader::Size, &IsEOF)) {
- Err = joinErrors(std::move(Err), std::move(Err2));
- break;
- }
- if (IsEOF)
- break;
- }
-
- // Decode header buffer.
- uint64_t MsgSize;
- SimpleRemoteEPCOpcode OpC;
- uint64_t SeqNo;
- ExecutorAddress TagAddr;
-
- MsgSize =
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::MsgSizeOffset));
- OpC = static_cast<SimpleRemoteEPCOpcode>(static_cast<uint64_t>(
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::OpCOffset))));
- SeqNo =
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::SeqNoOffset));
- TagAddr.setValue(
- *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::TagAddrOffset)));
-
- if (MsgSize < FDMsgHeader::Size) {
- Err = joinErrors(std::move(Err),
- make_error<StringError>("Mesasge size too small",
- inconvertibleErrorCode()));
- break;
- }
-
- // Read the argument bytes.
- SimpleRemoteEPCArgBytesVector ArgBytes;
- ArgBytes.resize(MsgSize - FDMsgHeader::Size);
- if (auto Err2 = readBytes(ArgBytes.data(), ArgBytes.size())) {
- Err = joinErrors(std::move(Err), std::move(Err2));
- break;
- }
-
- if (auto Action = C.handleMessage(OpC, SeqNo, TagAddr, ArgBytes)) {
- if (*Action == SimpleRemoteEPCTransportClient::EndSession)
- break;
- } else {
- Err = joinErrors(std::move(Err), Action.takeError());
- break;
- }
- } while (true);
-
- C.handleDisconnect(std::move(Err));
-}
-
-} // end namespace orc
-} // end namespace llvm
diff --git a/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp b/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp
deleted file mode 100644
index d60a6a2d06904..0000000000000
--- a/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-//===------- SimpleRemoteEPC.cpp -- Simple remote executor control --------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
-#include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
-#include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
-#include "llvm/Support/FormatVariadic.h"
-
-#define DEBUG_TYPE "orc"
-
-namespace llvm {
-namespace orc {
-namespace shared {
-
-template <>
-class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
- SymbolLookupSet::value_type> {
-public:
- static size_t size(const SymbolLookupSet::value_type &V) {
- return SPSArgList<SPSString, bool>::size(
- *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
- }
-
- static bool serialize(SPSOutputBuffer &OB,
- const SymbolLookupSet::value_type &V) {
- return SPSArgList<SPSString, bool>::serialize(
- OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
- }
-};
-
-template <>
-class TrivialSPSSequenceSerialization<SPSRemoteSymbolLookupSetElement,
- SymbolLookupSet> {
-public:
- static constexpr bool available = true;
-};
-
-template <>
-class SPSSerializationTraits<SPSRemoteSymbolLookup,
- ExecutorProcessControl::LookupRequest> {
- using MemberSerialization =
- SPSArgList<SPSExecutorAddress, SPSRemoteSymbolLookupSet>;
-
-public:
- static size_t size(const ExecutorProcessControl::LookupRequest &LR) {
- return MemberSerialization::size(ExecutorAddress(LR.Handle), LR.Symbols);
- }
-
- static bool serialize(SPSOutputBuffer &OB,
- const ExecutorProcessControl::LookupRequest &LR) {
- return MemberSerialization::serialize(OB, ExecutorAddress(LR.Handle),
- LR.Symbols);
- }
-};
-
-} // end namespace shared
-
-SimpleRemoteEPC::~SimpleRemoteEPC() {
- assert(Disconnected && "Destroyed without disconnection");
-}
-
-Error SimpleRemoteEPC::setup(std::unique_ptr<SimpleRemoteEPCTransport> T,
- const SimpleRemoteEPCExecutorInfo &EI) {
- using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;
- LLVM_DEBUG({
- dbgs() << "SimpleRemoteEPC received setup message:\n"
- << " Triple: " << EI.TargetTriple << "\n"
- << " Page size: " << EI.PageSize << "\n"
- << " Bootstrap symbols:\n";
- for (const auto &KV : EI.BootstrapSymbols)
- dbgs() << " " << KV.first() << ": "
- << formatv("{0:x16}", KV.second.getValue()) << "\n";
- });
- this->T = std::move(T);
- TargetTriple = Triple(EI.TargetTriple);
- PageSize = EI.PageSize;
-
- if (auto Err = EI.getBootstrapSymbols(
- {{JDI.JITDispatchContextAddress, ExecutorSessionObjectName},
- {JDI.JITDispatchFunctionAddress, DispatchFnName},
- {LoadDylibAddr, "__llvm_orc_load_dylib"},
- {LookupSymbolsAddr, "__llvm_orc_lookup_symbols"},
- {RunAsMainAddr, "__llvm_orc_run_as_main"}}))
- return Err;
-
- if (!MemMgr)
- if (auto Err = setupDefaultMemoryManager(EI))
- return Err;
- if (!MemAccess)
- if (auto Err = setupDefaultMemoryAccess(EI))
- return Err;
-
- return Error::success();
-}
-
-Expected<tpctypes::DylibHandle>
-SimpleRemoteEPC::loadDylib(const char *DylibPath) {
- Expected<tpctypes::DylibHandle> H((tpctypes::DylibHandle()));
- if (auto Err = callSPSWrapper<shared::SPSLoadDylibSignature>(
- LoadDylibAddr.getValue(), H, JDI.JITDispatchContextAddress,
- StringRef(DylibPath), (uint64_t)0))
- return std::move(Err);
- return H;
-}
-
-Expected<std::vector<tpctypes::LookupResult>>
-SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) {
- Expected<std::vector<tpctypes::LookupResult>> R(
- (std::vector<tpctypes::LookupResult>()));
-
- if (auto Err = callSPSWrapper<shared::SPSLookupSymbolsSignature>(
- LookupSymbolsAddr.getValue(), R, JDI.JITDispatchContextAddress,
- Request))
- return std::move(Err);
- return R;
-}
-
-Expected<int32_t> SimpleRemoteEPC::runAsMain(JITTargetAddress MainFnAddr,
- ArrayRef<std::string> Args) {
- int64_t Result = 0;
- if (auto Err = callSPSWrapper<shared::SPSRunAsMainSignature>(
- RunAsMainAddr.getValue(), Result, ExecutorAddress(MainFnAddr), Args))
- return std::move(Err);
- return Result;
-}
-
-void SimpleRemoteEPC::callWrapperAsync(SendResultFunction OnComplete,
- JITTargetAddress WrapperFnAddr,
- ArrayRef<char> ArgBuffer) {
- uint64_t SeqNo;
- {
- std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
- SeqNo = getNextSeqNo();
- assert(!PendingCallWrapperResults.count(SeqNo) && "SeqNo already in use");
- PendingCallWrapperResults[SeqNo] = std::move(OnComplete);
- }
-
- if (auto Err = T->sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo,
- ExecutorAddress(WrapperFnAddr), ArgBuffer)) {
- getExecutionSession().reportError(std::move(Err));
- }
-}
-
-Error SimpleRemoteEPC::disconnect() {
- Disconnected = true;
- T->disconnect();
- return Error::success();
-}
-
-Expected<SimpleRemoteEPCTransportClient::HandleMessageAction>
-SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) {
- using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>;
- if (static_cast<UT>(OpC) < static_cast<UT>(SimpleRemoteEPCOpcode::FirstOpC) ||
- static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC))
- return make_error<StringError>("Unexpected opcode",
- inconvertibleErrorCode());
-
- switch (OpC) {
- case SimpleRemoteEPCOpcode::Setup:
- if (auto Err = handleSetup(SeqNo, TagAddr, std::move(ArgBytes)))
- return std::move(Err);
- break;
- case SimpleRemoteEPCOpcode::Hangup:
- // FIXME: Put EPC into 'detached' state.
- return SimpleRemoteEPCTransportClient::EndSession;
- case SimpleRemoteEPCOpcode::Result:
- if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))
- return std::move(Err);
- break;
- case SimpleRemoteEPCOpcode::CallWrapper:
- handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes));
- break;
- }
- return ContinueSession;
-}
-
-void SimpleRemoteEPC::handleDisconnect(Error Err) {
- PendingCallWrapperResultsMap TmpPending;
-
- {
- std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
- std::swap(TmpPending, PendingCallWrapperResults);
- }
-
- for (auto &KV : TmpPending)
- KV.second(
- shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
-
- if (Err) {
- // FIXME: Move ReportError to EPC.
- if (ES)
- ES->reportError(std::move(Err));
- else
- logAllUnhandledErrors(std::move(Err), errs(), "SimpleRemoteEPC: ");
- }
-}
-
-void SimpleRemoteEPC::setMemoryManager(
- std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {
- OwnedMemMgr = std::move(MemMgr);
- this->MemMgr = OwnedMemMgr.get();
-}
-
-void SimpleRemoteEPC::setMemoryAccess(std::unique_ptr<MemoryAccess> MemAccess) {
- OwnedMemAccess = std::move(MemAccess);
- this->MemAccess = OwnedMemAccess.get();
-}
-
-Error SimpleRemoteEPC::setupDefaultMemoryManager(
- const SimpleRemoteEPCExecutorInfo &EI) {
-
- EPCGenericJITLinkMemoryManager::FuncAddrs FAs;
-
- if (auto Err = EI.getBootstrapSymbols(
- {{FAs.Reserve, "__llvm_orc_memory_reserve"},
- {FAs.Finalize, "__llvm_orc_memory_finalize"},
- {FAs.Deallocate, "__llvm_orc_memory_deallocate"}}))
- return Err;
-
- setMemoryManager(
- std::make_unique<EPCGenericJITLinkMemoryManager>(*this, FAs));
- return Error::success();
-}
-
-Error SimpleRemoteEPC::setupDefaultMemoryAccess(
- const SimpleRemoteEPCExecutorInfo &EI) {
-
- return Error::success();
-}
-
-Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) {
- if (SeqNo != 0)
- return make_error<StringError>("Setup packet SeqNo not zero",
- inconvertibleErrorCode());
-
- if (TagAddr)
- return make_error<StringError>("Setup packet TagAddr not zero",
- inconvertibleErrorCode());
-
- std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
- auto I = PendingCallWrapperResults.find(0);
- assert(PendingCallWrapperResults.size() == 1 &&
- I != PendingCallWrapperResults.end() &&
- "Setup message handler not connectly set up");
- auto SetupMsgHandler = std::move(I->second);
- PendingCallWrapperResults.erase(I);
-
- auto WFR =
- shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
- SetupMsgHandler(std::move(WFR));
- return Error::success();
-}
-
-void SimpleRemoteEPC::prepareToReceiveSetupMessage(
- std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> &ExecInfoP) {
- PendingCallWrapperResults[0] =
- [&](shared::WrapperFunctionResult SetupMsgBytes) {
- if (const char *ErrMsg = SetupMsgBytes.getOutOfBandError()) {
- ExecInfoP.set_value(
- make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
- return;
- }
- using SPSSerialize =
- shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>;
- shared::SPSInputBuffer IB(SetupMsgBytes.data(), SetupMsgBytes.size());
- SimpleRemoteEPCExecutorInfo EI;
- if (SPSSerialize::deserialize(IB, EI))
- ExecInfoP.set_value(EI);
- else
- ExecInfoP.set_value(make_error<StringError>(
- "Could not deserialize setup message", inconvertibleErrorCode()));
- };
-}
-
-Error SimpleRemoteEPC::handleResult(uint64_t SeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) {
- SendResultFunction SendResult;
-
- if (TagAddr)
- return make_error<StringError>("Unexpected TagAddr in result message",
- inconvertibleErrorCode());
-
- {
- std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
- auto I = PendingCallWrapperResults.find(SeqNo);
- if (I == PendingCallWrapperResults.end())
- return make_error<StringError>("No call for sequence number " +
- Twine(SeqNo),
- inconvertibleErrorCode());
- SendResult = std::move(I->second);
- PendingCallWrapperResults.erase(I);
- releaseSeqNo(SeqNo);
- }
-
- auto WFR =
- shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
- SendResult(std::move(WFR));
- return Error::success();
-}
-
-void SimpleRemoteEPC::handleCallWrapper(
- uint64_t RemoteSeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) {
- assert(ES && "No ExecutionSession attached");
- ES->runJITDispatchHandler(
- [this, RemoteSeqNo](shared::WrapperFunctionResult WFR) {
- if (auto Err =
- T->sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo,
- ExecutorAddress(), {WFR.data(), WFR.size()}))
- getExecutionSession().reportError(std::move(Err));
- },
- TagAddr.getValue(), ArgBytes);
-}
-
-} // end namespace orc
-} // end namespace llvm
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
index 548bf947974ab..b04c09c502445 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
@@ -1,7 +1,6 @@
add_llvm_component_library(LLVMOrcTargetProcess
JITLoaderGDB.cpp
RegisterEHFrames.cpp
- SimpleRemoteEPCServer.cpp
TargetExecutionUtils.cpp
ADDITIONAL_HEADER_DIRS
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp
deleted file mode 100644
index e1b00630c3414..0000000000000
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-//===------- SimpleEPCServer.cpp - EPC over simple abstract channel -------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h"
-
-#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Process.h"
-
-#define DEBUG_TYPE "orc"
-
-using namespace llvm::orc::shared;
-
-namespace llvm {
-namespace orc {
-
-static llvm::orc::shared::detail::CWrapperFunctionResult
-reserveWrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<SPSOrcTargetProcessAllocate>::handle(
- ArgData, ArgSize,
- [](uint64_t Size) -> Expected<ExecutorAddress> {
- std::error_code EC;
- auto MB = sys::Memory::allocateMappedMemory(
- Size, 0, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC);
- if (EC)
- return errorCodeToError(EC);
- return ExecutorAddress::fromPtr(MB.base());
- })
- .release();
-}
-
-static llvm::orc::shared::detail::CWrapperFunctionResult
-finalizeWrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<SPSOrcTargetProcessFinalize>::handle(
- ArgData, ArgSize,
- [](const tpctypes::FinalizeRequest &FR) -> Error {
- for (auto &Seg : FR) {
- char *Mem = Seg.Addr.toPtr<char *>();
- memcpy(Mem, Seg.Content.data(), Seg.Content.size());
- memset(Mem + Seg.Content.size(), 0,
- Seg.Size - Seg.Content.size());
- assert(Seg.Size <= std::numeric_limits<size_t>::max());
- if (auto EC = sys::Memory::protectMappedMemory(
- {Mem, static_cast<size_t>(Seg.Size)},
- tpctypes::fromWireProtectionFlags(Seg.Prot)))
- return errorCodeToError(EC);
- if (Seg.Prot & tpctypes::WPF_Exec)
- sys::Memory::InvalidateInstructionCache(Mem, Seg.Size);
- }
- return Error::success();
- })
- .release();
-}
-
-static llvm::orc::shared::detail::CWrapperFunctionResult
-deallocateWrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<SPSOrcTargetProcessDeallocate>::handle(
- ArgData, ArgSize,
- [](ExecutorAddress Base, uint64_t Size) -> Error {
- sys::MemoryBlock MB(Base.toPtr<void *>(), Size);
- if (auto EC = sys::Memory::releaseMappedMemory(MB))
- return errorCodeToError(EC);
- return Error::success();
- })
- .release();
-}
-
-template <typename WriteT, typename SPSWriteT>
-static llvm::orc::shared::detail::CWrapperFunctionResult
-writeUIntsWrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<void(SPSSequence<SPSWriteT>)>::handle(
- ArgData, ArgSize,
- [](std::vector<WriteT> Ws) {
- for (auto &W : Ws)
- *jitTargetAddressToPointer<decltype(W.Value) *>(W.Address) =
- W.Value;
- })
- .release();
-}
-
-static llvm::orc::shared::detail::CWrapperFunctionResult
-writeBuffersWrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<void(SPSSequence<SPSMemoryAccessBufferWrite>)>::handle(
- ArgData, ArgSize,
- [](std::vector<tpctypes::BufferWrite> Ws) {
- for (auto &W : Ws)
- memcpy(jitTargetAddressToPointer<char *>(W.Address),
- W.Buffer.data(), W.Buffer.size());
- })
- .release();
-}
-
-static llvm::orc::shared::detail::CWrapperFunctionResult
-runAsMainWrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<SPSRunAsMainSignature>::handle(
- ArgData, ArgSize,
- [](ExecutorAddress MainAddr,
- std::vector<std::string> Args) -> int64_t {
- return runAsMain(MainAddr.toPtr<int (*)(int, char *[])>(), Args);
- })
- .release();
-}
-
-SimpleRemoteEPCServer::Dispatcher::~Dispatcher() {}
-
-void SimpleRemoteEPCServer::ThreadDispatcher::dispatch(
- unique_function<void()> Work) {
- {
- std::lock_guard<std::mutex> Lock(DispatchMutex);
- if (!Running)
- return;
- ++Outstanding;
- }
-
- std::thread([this, Work = std::move(Work)]() mutable {
- Work();
- std::lock_guard<std::mutex> Lock(DispatchMutex);
- --Outstanding;
- OutstandingCV.notify_all();
- }).detach();
-}
-
-void SimpleRemoteEPCServer::ThreadDispatcher::shutdown() {
- std::unique_lock<std::mutex> Lock(DispatchMutex);
- Running = false;
- OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; });
-}
-
-StringMap<ExecutorAddress> SimpleRemoteEPCServer::defaultBootstrapSymbols() {
- StringMap<ExecutorAddress> DBS;
-
- DBS["__llvm_orc_memory_reserve"] = ExecutorAddress::fromPtr(&reserveWrapper);
- DBS["__llvm_orc_memory_finalize"] =
- ExecutorAddress::fromPtr(&finalizeWrapper);
- DBS["__llvm_orc_memory_deallocate"] =
- ExecutorAddress::fromPtr(&deallocateWrapper);
- DBS["__llvm_orc_memory_write_uint8s"] = ExecutorAddress::fromPtr(
- &writeUIntsWrapper<tpctypes::UInt8Write,
- shared::SPSMemoryAccessUInt8Write>);
- DBS["__llvm_orc_memory_write_uint16s"] = ExecutorAddress::fromPtr(
- &writeUIntsWrapper<tpctypes::UInt16Write,
- shared::SPSMemoryAccessUInt16Write>);
- DBS["__llvm_orc_memory_write_uint32s"] = ExecutorAddress::fromPtr(
- &writeUIntsWrapper<tpctypes::UInt32Write,
- shared::SPSMemoryAccessUInt32Write>);
- DBS["__llvm_orc_memory_write_uint64s"] = ExecutorAddress::fromPtr(
- &writeUIntsWrapper<tpctypes::UInt64Write,
- shared::SPSMemoryAccessUInt64Write>);
- DBS["__llvm_orc_memory_write_buffers"] =
- ExecutorAddress::fromPtr(&writeBuffersWrapper);
- DBS["__llvm_orc_run_as_main"] = ExecutorAddress::fromPtr(&runAsMainWrapper);
- DBS["__llvm_orc_load_dylib"] = ExecutorAddress::fromPtr(&loadDylibWrapper);
- DBS["__llvm_orc_lookup_symbols"] =
- ExecutorAddress::fromPtr(&lookupSymbolsWrapper);
- return DBS;
-}
-
-Expected<SimpleRemoteEPCTransportClient::HandleMessageAction>
-SimpleRemoteEPCServer::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) {
- using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>;
- if (static_cast<UT>(OpC) < static_cast<UT>(SimpleRemoteEPCOpcode::FirstOpC) ||
- static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC))
- return make_error<StringError>("Unexpected opcode",
- inconvertibleErrorCode());
-
- // TODO: Clean detach message?
- switch (OpC) {
- case SimpleRemoteEPCOpcode::Setup:
- return make_error<StringError>("Unexpected Setup opcode",
- inconvertibleErrorCode());
- case SimpleRemoteEPCOpcode::Hangup:
- return SimpleRemoteEPCTransportClient::EndSession;
- case SimpleRemoteEPCOpcode::Result:
- if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))
- return std::move(Err);
- break;
- case SimpleRemoteEPCOpcode::CallWrapper:
- handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes));
- break;
- }
- return ContinueSession;
-}
-
-Error SimpleRemoteEPCServer::waitForDisconnect() {
- std::unique_lock<std::mutex> Lock(ServerStateMutex);
- ShutdownCV.wait(Lock, [this]() { return RunState == ServerShutDown; });
- return std::move(ShutdownErr);
-}
-
-void SimpleRemoteEPCServer::handleDisconnect(Error Err) {
- PendingJITDispatchResultsMap TmpPending;
-
- {
- std::lock_guard<std::mutex> Lock(ServerStateMutex);
- std::swap(TmpPending, PendingJITDispatchResults);
- RunState = ServerShuttingDown;
- }
-
- // Send out-of-band errors to any waiting threads.
- for (auto &KV : TmpPending)
- KV.second->set_value(
- shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
-
- // TODO: Free attached resources.
- // 1. Close libraries in DylibHandles.
-
- // Wait for dispatcher to clear.
- D->shutdown();
-
- std::lock_guard<std::mutex> Lock(ServerStateMutex);
- ShutdownErr = joinErrors(std::move(ShutdownErr), std::move(Err));
- RunState = ServerShutDown;
- ShutdownCV.notify_all();
-}
-
-Error SimpleRemoteEPCServer::sendSetupMessage(
- StringMap<ExecutorAddress> BootstrapSymbols) {
-
- using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;
-
- std::vector<char> SetupPacket;
- SimpleRemoteEPCExecutorInfo EI;
- EI.TargetTriple = sys::getProcessTriple();
- if (auto PageSize = sys::Process::getPageSize())
- EI.PageSize = *PageSize;
- else
- return PageSize.takeError();
- EI.BootstrapSymbols = std::move(BootstrapSymbols);
-
- assert(!EI.BootstrapSymbols.count(ExecutorSessionObjectName) &&
- "Dispatch context name should not be set");
- assert(!EI.BootstrapSymbols.count(DispatchFnName) &&
- "Dispatch function name should not be set");
- EI.BootstrapSymbols[ExecutorSessionObjectName] =
- ExecutorAddress::fromPtr(this);
- EI.BootstrapSymbols[DispatchFnName] =
- ExecutorAddress::fromPtr(jitDispatchEntry);
-
- using SPSSerialize =
- shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>;
- auto SetupPacketBytes =
- shared::WrapperFunctionResult::allocate(SPSSerialize::size(EI));
- shared::SPSOutputBuffer OB(SetupPacketBytes.data(), SetupPacketBytes.size());
- if (!SPSSerialize::serialize(OB, EI))
- return make_error<StringError>("Could not send setup packet",
- inconvertibleErrorCode());
-
- return T->sendMessage(SimpleRemoteEPCOpcode::Setup, 0, ExecutorAddress(),
- {SetupPacketBytes.data(), SetupPacketBytes.size()});
-}
-
-Error SimpleRemoteEPCServer::handleResult(
- uint64_t SeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) {
- std::promise<shared::WrapperFunctionResult> *P = nullptr;
- {
- std::lock_guard<std::mutex> Lock(ServerStateMutex);
- auto I = PendingJITDispatchResults.find(SeqNo);
- if (I == PendingJITDispatchResults.end())
- return make_error<StringError>("No call for sequence number " +
- Twine(SeqNo),
- inconvertibleErrorCode());
- P = I->second;
- PendingJITDispatchResults.erase(I);
- releaseSeqNo(SeqNo);
- }
- auto R = shared::WrapperFunctionResult::allocate(ArgBytes.size());
- memcpy(R.data(), ArgBytes.data(), ArgBytes.size());
- P->set_value(std::move(R));
- return Error::success();
-}
-
-void SimpleRemoteEPCServer::handleCallWrapper(
- uint64_t RemoteSeqNo, ExecutorAddress TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) {
- D->dispatch([this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() {
- using WrapperFnTy =
- shared::detail::CWrapperFunctionResult (*)(const char *, size_t);
- auto *Fn = TagAddr.toPtr<WrapperFnTy>();
- shared::WrapperFunctionResult ResultBytes(
- Fn(ArgBytes.data(), ArgBytes.size()));
- if (auto Err = T->sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo,
- ExecutorAddress(),
- {ResultBytes.data(), ResultBytes.size()}))
- ReportError(std::move(Err));
- });
-}
-
-shared::detail::CWrapperFunctionResult
-SimpleRemoteEPCServer::loadDylibWrapper(const char *ArgData, size_t ArgSize) {
- return shared::WrapperFunction<shared::SPSLoadDylibSignature>::handle(
- ArgData, ArgSize,
- [](ExecutorAddress ExecutorSessionObj, std::string Path,
- uint64_t Flags) -> Expected<uint64_t> {
- return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>()
- ->loadDylib(Path, Flags);
- })
- .release();
-}
-
-shared::detail::CWrapperFunctionResult
-SimpleRemoteEPCServer::lookupSymbolsWrapper(const char *ArgData,
- size_t ArgSize) {
- return shared::WrapperFunction<shared::SPSLookupSymbolsSignature>::handle(
- ArgData, ArgSize,
- [](ExecutorAddress ExecutorSessionObj,
- std::vector<RemoteSymbolLookup> Lookup) {
- return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>()
- ->lookupSymbols(Lookup);
- })
- .release();
-}
-
-Expected<tpctypes::DylibHandle>
-SimpleRemoteEPCServer::loadDylib(const std::string &Path, uint64_t Mode) {
- std::string ErrMsg;
- const char *P = Path.empty() ? nullptr : Path.c_str();
- auto DL = sys::DynamicLibrary::getPermanentLibrary(P, &ErrMsg);
- if (!DL.isValid())
- return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
- std::lock_guard<std::mutex> Lock(ServerStateMutex);
- uint64_t Id = Dylibs.size();
- Dylibs.push_back(std::move(DL));
- return Id;
-}
-
-Expected<std::vector<std::vector<ExecutorAddress>>>
-SimpleRemoteEPCServer::lookupSymbols(const std::vector<RemoteSymbolLookup> &L) {
- std::vector<std::vector<ExecutorAddress>> Result;
-
- for (const auto &E : L) {
- if (E.H >= Dylibs.size())
- return make_error<StringError>("Unrecognized handle",
- inconvertibleErrorCode());
- auto &DL = Dylibs[E.H];
- Result.push_back({});
-
- for (const auto &Sym : E.Symbols) {
-
- const char *DemangledSymName = Sym.Name.c_str();
-#ifdef __APPLE__
- if (*DemangledSymName == '_')
- ++DemangledSymName;
-#endif
-
- void *Addr = DL.getAddressOfSymbol(DemangledSymName);
- if (!Addr && Sym.Required)
- return make_error<StringError>(Twine("Missing definition for ") +
- DemangledSymName,
- inconvertibleErrorCode());
-
- Result.back().push_back(ExecutorAddress::fromPtr(Addr));
- }
- }
-
- return std::move(Result);
-}
-
-shared::WrapperFunctionResult
-SimpleRemoteEPCServer::doJITDispatch(const void *FnTag, const char *ArgData,
- size_t ArgSize) {
- uint64_t SeqNo;
- std::promise<shared::WrapperFunctionResult> ResultP;
- auto ResultF = ResultP.get_future();
- {
- std::lock_guard<std::mutex> Lock(ServerStateMutex);
- if (RunState != ServerRunning)
- return shared::WrapperFunctionResult::createOutOfBandError(
- "jit_dispatch not available (EPC server shut down)");
-
- SeqNo = getNextSeqNo();
- assert(!PendingJITDispatchResults.count(SeqNo) && "SeqNo already in use");
- PendingJITDispatchResults[SeqNo] = &ResultP;
- }
-
- if (auto Err =
- T->sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo,
- ExecutorAddress::fromPtr(FnTag), {ArgData, ArgSize}))
- ReportError(std::move(Err));
-
- return ResultF.get();
-}
-
-shared::detail::CWrapperFunctionResult
-SimpleRemoteEPCServer::jitDispatchEntry(void *DispatchCtx, const void *FnTag,
- const char *ArgData, size_t ArgSize) {
- return reinterpret_cast<SimpleRemoteEPCServer *>(DispatchCtx)
- ->doJITDispatch(FnTag, ArgData, ArgSize)
- .release();
-}
-
-} // end namespace orc
-} // end namespace llvm
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
index bed443bc374b5..7f197a50c3902 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
@@ -13,8 +13,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
@@ -90,6 +90,8 @@ int openListener(std::string Host, std::string PortStr) {
static constexpr int ConnectionQueueLen = 1;
listen(SockFD, ConnectionQueueLen);
+ outs() << "Listening at " << Host << ":" << PortStr << "\n";
+
#if defined(_AIX)
assert(Hi_32(AI->ai_addrlen) == 0 && "Field is a size_t on 64-bit AIX");
socklen_t AddrLen = Lo_32(AI->ai_addrlen);
@@ -131,15 +133,24 @@ int main(int argc, char *argv[]) {
"' is not a valid integer");
InFD = OutFD = openListener(Host.str(), PortStr.str());
+ outs() << "Connection established. Running OrcRPCTPCServer...\n";
} else
printErrorAndExit("invalid specifier type \"" + SpecifierType + "\"");
}
- auto Server =
- ExitOnErr(SimpleRemoteEPCServer::Create<FDSimpleRemoteEPCTransport>(
- std::make_unique<SimpleRemoteEPCServer::ThreadDispatcher>(),
- SimpleRemoteEPCServer::defaultBootstrapSymbols(), InFD, OutFD));
+ ExitOnErr.setBanner(std::string(argv[0]) + ":");
+
+ using JITLinkExecutorEndpoint =
+ shared::SingleThreadedRPCEndpoint<shared::FDRawByteChannel>;
+
+ shared::registerStringError<shared::FDRawByteChannel>();
+
+ shared::FDRawByteChannel C(InFD, OutFD);
+ JITLinkExecutorEndpoint EP(C, true);
+ OrcRPCTPCServer<JITLinkExecutorEndpoint> Server(EP);
+ Server.setProgramName(std::string("llvm-jitlink-executor"));
+
+ ExitOnErr(Server.run());
- ExitOnErr(Server->waitForDisconnect());
return 0;
}
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 2e4b9cfc0d7f7..dd97bafbdfe2f 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -635,7 +635,8 @@ static Error loadDylibs(Session &S) {
return Error::success();
}
-static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
+Expected<std::unique_ptr<ExecutorProcessControl>>
+LLVMJITLinkRemoteExecutorProcessControl::LaunchExecutor() {
#ifndef LLVM_ON_UNIX
// FIXME: Add support for Windows.
return make_error<StringError>("-" + OutOfProcessExecutor.ArgStr +
@@ -643,6 +644,8 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
inconvertibleErrorCode());
#else
+ shared::registerStringError<LLVMJITLinkChannel>();
+
constexpr int ReadEnd = 0;
constexpr int WriteEnd = 1;
@@ -694,8 +697,24 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
close(ToExecutor[ReadEnd]);
close(FromExecutor[WriteEnd]);
- return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
+ // Return an RPC channel connected to our end of the pipes.
+ auto SSP = std::make_shared<SymbolStringPool>();
+ auto Channel = std::make_unique<shared::FDRawByteChannel>(
FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
+ auto Endpoint = std::make_unique<LLVMJITLinkRPCEndpoint>(*Channel, true);
+
+ auto ReportError = [](Error Err) {
+ logAllUnhandledErrors(std::move(Err), errs(), "");
+ };
+
+ Error Err = Error::success();
+ std::unique_ptr<LLVMJITLinkRemoteExecutorProcessControl> REPC(
+ new LLVMJITLinkRemoteExecutorProcessControl(
+ std::move(SSP), std::move(Channel), std::move(Endpoint),
+ std::move(ReportError), Err));
+ if (Err)
+ return std::move(Err);
+ return std::move(REPC);
#endif
}
@@ -745,7 +764,8 @@ static Expected<int> connectTCPSocket(std::string Host, std::string PortStr) {
}
#endif
-static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {
+Expected<std::unique_ptr<ExecutorProcessControl>>
+LLVMJITLinkRemoteExecutorProcessControl::ConnectToExecutor() {
#ifndef LLVM_ON_UNIX
// FIXME: Add TCP support for Windows.
return make_error<StringError>("-" + OutOfProcessExecutorConnect.ArgStr +
@@ -753,6 +773,8 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {
inconvertibleErrorCode());
#else
+ shared::registerStringError<LLVMJITLinkChannel>();
+
StringRef Host, PortStr;
std::tie(Host, PortStr) = StringRef(OutOfProcessExecutorConnect).split(':');
if (Host.empty())
@@ -772,10 +794,37 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {
if (!SockFD)
return SockFD.takeError();
- return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(*SockFD, *SockFD);
+ auto SSP = std::make_shared<SymbolStringPool>();
+ auto Channel = std::make_unique<shared::FDRawByteChannel>(*SockFD, *SockFD);
+ auto Endpoint = std::make_unique<LLVMJITLinkRPCEndpoint>(*Channel, true);
+
+ auto ReportError = [](Error Err) {
+ logAllUnhandledErrors(std::move(Err), errs(), "");
+ };
+
+ Error Err = Error::success();
+ std::unique_ptr<LLVMJITLinkRemoteExecutorProcessControl> REPC(
+ new LLVMJITLinkRemoteExecutorProcessControl(
+ std::move(SSP), std::move(Channel), std::move(Endpoint),
+ std::move(ReportError), Err));
+ if (Err)
+ return std::move(Err);
+ return std::move(REPC);
#endif
}
+Error LLVMJITLinkRemoteExecutorProcessControl::disconnect() {
+ std::promise<MSVCPError> P;
+ auto F = P.get_future();
+ auto Err = closeConnection([&](Error Err) -> Error {
+ P.set_value(std::move(Err));
+ Finished = true;
+ return Error::success();
+ });
+ ListenerThread.join();
+ return joinErrors(std::move(Err), F.get());
+}
+
class PhonyExternalsGenerator : public DefinitionGenerator {
public:
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
@@ -797,13 +846,14 @@ Expected<std::unique_ptr<Session>> Session::Create(Triple TT) {
std::unique_ptr<ExecutorProcessControl> EPC;
if (OutOfProcessExecutor.getNumOccurrences()) {
/// If -oop-executor is passed then launch the executor.
- if (auto REPC = launchExecutor())
+ if (auto REPC = LLVMJITLinkRemoteExecutorProcessControl::LaunchExecutor())
EPC = std::move(*REPC);
else
return REPC.takeError();
} else if (OutOfProcessExecutorConnect.getNumOccurrences()) {
/// If -oop-executor-connect is passed then connect to the executor.
- if (auto REPC = connectToExecutor())
+ if (auto REPC =
+ LLVMJITLinkRemoteExecutorProcessControl::ConnectToExecutor())
EPC = std::move(*REPC);
else
return REPC.takeError();
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h
index 0a4654a8c864a..acb64a9a39ca3 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.h
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h
@@ -19,9 +19,9 @@
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h"
#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
-#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Regex.h"
@@ -48,6 +48,66 @@ class LLVMJITLinkObjectLinkingLayer : public orc::ObjectLinkingLayer {
Session &S;
};
+using LLVMJITLinkChannel = orc::shared::FDRawByteChannel;
+using LLVMJITLinkRPCEndpoint =
+ orc::shared::MultiThreadedRPCEndpoint<LLVMJITLinkChannel>;
+using LLVMJITLinkRemoteMemoryAccess =
+ orc::OrcRPCEPCMemoryAccess<LLVMJITLinkRPCEndpoint>;
+
+class LLVMJITLinkRemoteExecutorProcessControl
+ : public orc::OrcRPCExecutorProcessControlBase<LLVMJITLinkRPCEndpoint> {
+public:
+ using BaseT = orc::OrcRPCExecutorProcessControlBase<LLVMJITLinkRPCEndpoint>;
+ static Expected<std::unique_ptr<ExecutorProcessControl>> LaunchExecutor();
+
+ static Expected<std::unique_ptr<ExecutorProcessControl>> ConnectToExecutor();
+
+ Error disconnect() override;
+
+private:
+ using LLVMJITLinkRemoteMemoryAccess =
+ orc::OrcRPCEPCMemoryAccess<LLVMJITLinkRemoteExecutorProcessControl>;
+
+ using LLVMJITLinkRemoteMemoryManager = orc::OrcRPCEPCJITLinkMemoryManager<
+ LLVMJITLinkRemoteExecutorProcessControl>;
+
+ LLVMJITLinkRemoteExecutorProcessControl(
+ std::shared_ptr<orc::SymbolStringPool> SSP,
+ std::unique_ptr<LLVMJITLinkChannel> Channel,
+ std::unique_ptr<LLVMJITLinkRPCEndpoint> Endpoint,
+ ErrorReporter ReportError, Error &Err)
+ : BaseT(std::move(SSP), *Endpoint, std::move(ReportError)),
+ Channel(std::move(Channel)), Endpoint(std::move(Endpoint)) {
+ ErrorAsOutParameter _(&Err);
+
+ ListenerThread = std::thread([&]() {
+ while (!Finished) {
+ if (auto Err = this->Endpoint->handleOne()) {
+ reportError(std::move(Err));
+ return;
+ }
+ }
+ });
+
+ if (auto Err2 = initializeORCRPCEPCBase()) {
+ Err = joinErrors(std::move(Err2), disconnect());
+ return;
+ }
+
+ OwnedMemAccess = std::make_unique<LLVMJITLinkRemoteMemoryAccess>(*this);
+ MemAccess = OwnedMemAccess.get();
+ OwnedMemMgr = std::make_unique<LLVMJITLinkRemoteMemoryManager>(*this);
+ MemMgr = OwnedMemMgr.get();
+ }
+
+ std::unique_ptr<LLVMJITLinkChannel> Channel;
+ std::unique_ptr<LLVMJITLinkRPCEndpoint> Endpoint;
+ std::unique_ptr<ExecutorProcessControl::MemoryAccess> OwnedMemAccess;
+ std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
+ std::atomic<bool> Finished{false};
+ std::thread ListenerThread;
+};
+
struct Session {
orc::ExecutionSession ES;
orc::JITDylib *MainJD = nullptr;
More information about the llvm-commits
mailing list