[ORC] Use a Setup object for SimpleRemoteEPC construction.

SimpleRemoteEPC notionally allowed subclasses to override the
createMemoryManager and createMemoryAccess methods to use custom objects, but
could not actually be subclassed in practice (The construction process in
SimpleRemoteEPC::Create could not be re-used).

Instead of subclassing, this commit adds a SimpleRemoteEPC::Setup class that
can be used by clients to set up the memory manager and memory access members.
A default-constructed Setup object results in no change from previous behavior
(EPCGeneric* memory manager and memory access objects used by default).
This commit is contained in:
Lang Hames
2021-10-13 16:22:28 -07:00
parent 8d2736d9dd
commit 4fcc0ac15e
4 changed files with 41 additions and 19 deletions

View File

@@ -31,10 +31,24 @@ namespace orc {
class SimpleRemoteEPC : public ExecutorProcessControl,
public SimpleRemoteEPCTransportClient {
public:
/// A setup object containing callbacks to construct a memory manager and
/// memory access object. Both are optional. If not specified,
/// EPCGenericJITLinkMemoryManager and EPCGenericMemoryAccess will be used.
struct Setup {
using CreateMemoryManagerFn =
Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>(
SimpleRemoteEPC &);
using CreateMemoryAccessFn =
Expected<std::unique_ptr<MemoryAccess>>(SimpleRemoteEPC &);
unique_function<CreateMemoryManagerFn> CreateMemoryManager;
unique_function<CreateMemoryAccessFn> CreateMemoryAccess;
};
/// Create a SimpleRemoteEPC using the given transport type and args.
template <typename TransportT, typename... TransportTCtorArgTs>
static Expected<std::unique_ptr<SimpleRemoteEPC>>
Create(std::unique_ptr<TaskDispatcher> D,
Create(std::unique_ptr<TaskDispatcher> D, Setup S,
TransportTCtorArgTs &&...TransportTCtorArgs) {
std::unique_ptr<SimpleRemoteEPC> SREPC(
new SimpleRemoteEPC(std::make_shared<SymbolStringPool>(),
@@ -44,7 +58,7 @@ public:
if (!T)
return T.takeError();
SREPC->T = std::move(*T);
if (auto Err = SREPC->setup())
if (auto Err = SREPC->setup(std::move(S)))
return joinErrors(std::move(Err), SREPC->disconnect());
return std::move(SREPC);
}
@@ -75,22 +89,22 @@ public:
void handleDisconnect(Error Err) override;
protected:
virtual Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
createMemoryManager();
virtual Expected<std::unique_ptr<MemoryAccess>> createMemoryAccess();
private:
SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP,
std::unique_ptr<TaskDispatcher> D)
: ExecutorProcessControl(std::move(SSP), std::move(D)) {}
static Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
createDefaultMemoryManager(SimpleRemoteEPC &SREPC);
static Expected<std::unique_ptr<MemoryAccess>>
createDefaultMemoryAccess(SimpleRemoteEPC &SREPC);
Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
Error handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
SimpleRemoteEPCArgBytesVector ArgBytes);
Error setup();
Error setup(Setup S);
Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
SimpleRemoteEPCArgBytesVector ArgBytes);

View File

@@ -180,9 +180,9 @@ void SimpleRemoteEPC::handleDisconnect(Error Err) {
}
Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
SimpleRemoteEPC::createMemoryManager() {
SimpleRemoteEPC::createDefaultMemoryManager(SimpleRemoteEPC &SREPC) {
EPCGenericJITLinkMemoryManager::SymbolAddrs SAs;
if (auto Err = getBootstrapSymbols(
if (auto Err = SREPC.getBootstrapSymbols(
{{SAs.Allocator, rt::SimpleExecutorMemoryManagerInstanceName},
{SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
{SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
@@ -190,12 +190,11 @@ SimpleRemoteEPC::createMemoryManager() {
rt::SimpleExecutorMemoryManagerDeallocateWrapperName}}))
return std::move(Err);
return std::make_unique<EPCGenericJITLinkMemoryManager>(*this, SAs);
return std::make_unique<EPCGenericJITLinkMemoryManager>(SREPC, SAs);
}
Expected<std::unique_ptr<ExecutorProcessControl::MemoryAccess>>
SimpleRemoteEPC::createMemoryAccess() {
SimpleRemoteEPC::createDefaultMemoryAccess(SimpleRemoteEPC &SREPC) {
return nullptr;
}
@@ -260,7 +259,7 @@ Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
return Error::success();
}
Error SimpleRemoteEPC::setup() {
Error SimpleRemoteEPC::setup(Setup S) {
using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;
std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP;
@@ -322,13 +321,21 @@ Error SimpleRemoteEPC::setup() {
else
return DM.takeError();
if (auto MemMgr = createMemoryManager()) {
// Set a default CreateMemoryManager if none is specified.
if (!S.CreateMemoryManager)
S.CreateMemoryManager = createDefaultMemoryManager;
if (auto MemMgr = S.CreateMemoryManager(*this)) {
OwnedMemMgr = std::move(*MemMgr);
this->MemMgr = OwnedMemMgr.get();
} else
return MemMgr.takeError();
if (auto MemAccess = createMemoryAccess()) {
// Set a default CreateMemoryAccess if none is specified.
if (!S.CreateMemoryAccess)
S.CreateMemoryAccess = createDefaultMemoryAccess;
if (auto MemAccess = S.CreateMemoryAccess(*this)) {
OwnedMemAccess = std::move(*MemAccess);
this->MemAccess = OwnedMemAccess.get();
} else

View File

@@ -1151,6 +1151,6 @@ Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote() {
// Return a SimpleRemoteEPC instance connected to our end of the pipes.
return orc::SimpleRemoteEPC::Create<orc::FDSimpleRemoteEPCTransport>(
std::make_unique<llvm::orc::InPlaceTaskDispatcher>(),
PipeFD[1][0], PipeFD[0][1]);
llvm::orc::SimpleRemoteEPC::Setup(), PipeFD[1][0], PipeFD[0][1]);
#endif
}

View File

@@ -798,7 +798,7 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
std::make_unique<DynamicThreadPoolTaskDispatcher>(),
FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
SimpleRemoteEPC::Setup(), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
#endif
}
@@ -883,7 +883,8 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {
return SockFD.takeError();
return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
std::make_unique<DynamicThreadPoolTaskDispatcher>(), *SockFD, *SockFD);
std::make_unique<DynamicThreadPoolTaskDispatcher>(),
SimpleRemoteEPC::Setup(), *SockFD, *SockFD);
#endif
}