1bb72f073SLang Hames //===------- SimpleRemoteEPC.cpp -- Simple remote executor control --------===//
2bb72f073SLang Hames //
3bb72f073SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bb72f073SLang Hames // See https://llvm.org/LICENSE.txt for license information.
5bb72f073SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bb72f073SLang Hames //
7bb72f073SLang Hames //===----------------------------------------------------------------------===//
8bb72f073SLang Hames 
9bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
10bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
11bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
122c8e7849SLang Hames #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
13bb72f073SLang Hames #include "llvm/Support/FormatVariadic.h"
14bb72f073SLang Hames 
15bb72f073SLang Hames #define DEBUG_TYPE "orc"
16bb72f073SLang Hames 
17bb72f073SLang Hames namespace llvm {
18bb72f073SLang Hames namespace orc {
19bb72f073SLang Hames 
~SimpleRemoteEPC()20bb72f073SLang Hames SimpleRemoteEPC::~SimpleRemoteEPC() {
21320832ccSLang Hames #ifndef NDEBUG
22320832ccSLang Hames   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
23bb72f073SLang Hames   assert(Disconnected && "Destroyed without disconnection");
24320832ccSLang Hames #endif // NDEBUG
25bb72f073SLang Hames }
26bb72f073SLang Hames 
27bb72f073SLang Hames Expected<tpctypes::DylibHandle>
loadDylib(const char * DylibPath)28bb72f073SLang Hames SimpleRemoteEPC::loadDylib(const char *DylibPath) {
29a2c1cf09SLang Hames   return DylibMgr->open(DylibPath, 0);
30bb72f073SLang Hames }
31bb72f073SLang Hames 
32bb72f073SLang Hames Expected<std::vector<tpctypes::LookupResult>>
lookupSymbols(ArrayRef<LookupRequest> Request)33bb72f073SLang Hames SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) {
34a2c1cf09SLang Hames   std::vector<tpctypes::LookupResult> Result;
35bb72f073SLang Hames 
36a2c1cf09SLang Hames   for (auto &Element : Request) {
37a2c1cf09SLang Hames     if (auto R = DylibMgr->lookup(Element.Handle, Element.Symbols)) {
38a2c1cf09SLang Hames       Result.push_back({});
39a2c1cf09SLang Hames       Result.back().reserve(R->size());
40a2c1cf09SLang Hames       for (auto Addr : *R)
41a2c1cf09SLang Hames         Result.back().push_back(Addr.getValue());
42a2c1cf09SLang Hames     } else
43a2c1cf09SLang Hames       return R.takeError();
44a2c1cf09SLang Hames   }
45a2c1cf09SLang Hames   return std::move(Result);
46bb72f073SLang Hames }
47bb72f073SLang Hames 
runAsMain(ExecutorAddr MainFnAddr,ArrayRef<std::string> Args)4821a06254SLang Hames Expected<int32_t> SimpleRemoteEPC::runAsMain(ExecutorAddr MainFnAddr,
49bb72f073SLang Hames                                              ArrayRef<std::string> Args) {
50bb72f073SLang Hames   int64_t Result = 0;
512c8e7849SLang Hames   if (auto Err = callSPSWrapper<rt::SPSRunAsMainSignature>(
5221a06254SLang Hames           RunAsMainAddr, Result, ExecutorAddr(MainFnAddr), Args))
53bb72f073SLang Hames     return std::move(Err);
54bb72f073SLang Hames   return Result;
55bb72f073SLang Hames }
56bb72f073SLang Hames 
callWrapperAsync(ExecutorAddr WrapperFnAddr,IncomingWFRHandler OnComplete,ArrayRef<char> ArgBuffer)57da7f993aSLang Hames void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr,
584d7cea3dSLang Hames                                        IncomingWFRHandler OnComplete,
59bb72f073SLang Hames                                        ArrayRef<char> ArgBuffer) {
60bb72f073SLang Hames   uint64_t SeqNo;
61bb72f073SLang Hames   {
62bb72f073SLang Hames     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
63bb72f073SLang Hames     SeqNo = getNextSeqNo();
64bb72f073SLang Hames     assert(!PendingCallWrapperResults.count(SeqNo) && "SeqNo already in use");
65bb72f073SLang Hames     PendingCallWrapperResults[SeqNo] = std::move(OnComplete);
66bb72f073SLang Hames   }
67bb72f073SLang Hames 
68175c1a39SLang Hames   if (auto Err = sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo,
6921a06254SLang Hames                              WrapperFnAddr, ArgBuffer)) {
7017a0858fSLang Hames     IncomingWFRHandler H;
7117a0858fSLang Hames 
7217a0858fSLang Hames     // We just registered OnComplete, but there may be a race between this
7317a0858fSLang Hames     // thread returning from sendMessage and handleDisconnect being called from
7417a0858fSLang Hames     // the transport's listener thread. If handleDisconnect gets there first
7517a0858fSLang Hames     // then it will have failed 'H' for us. If we get there first (or if
7617a0858fSLang Hames     // handleDisconnect already ran) then we need to take care of it.
7717a0858fSLang Hames     {
7817a0858fSLang Hames       std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
7917a0858fSLang Hames       auto I = PendingCallWrapperResults.find(SeqNo);
8017a0858fSLang Hames       if (I != PendingCallWrapperResults.end()) {
8117a0858fSLang Hames         H = std::move(I->second);
8217a0858fSLang Hames         PendingCallWrapperResults.erase(I);
8317a0858fSLang Hames       }
8417a0858fSLang Hames     }
8517a0858fSLang Hames 
8617a0858fSLang Hames     if (H)
8717a0858fSLang Hames       H(shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
8817a0858fSLang Hames 
89bb72f073SLang Hames     getExecutionSession().reportError(std::move(Err));
90bb72f073SLang Hames   }
91bb72f073SLang Hames }
92bb72f073SLang Hames 
disconnect()93bb72f073SLang Hames Error SimpleRemoteEPC::disconnect() {
94bb72f073SLang Hames   T->disconnect();
952815ed57SLang Hames   D->shutdown();
96320832ccSLang Hames   std::unique_lock<std::mutex> Lock(SimpleRemoteEPCMutex);
97320832ccSLang Hames   DisconnectCV.wait(Lock, [this] { return Disconnected; });
98320832ccSLang Hames   return std::move(DisconnectErr);
99bb72f073SLang Hames }
100bb72f073SLang Hames 
101bb72f073SLang Hames Expected<SimpleRemoteEPCTransportClient::HandleMessageAction>
handleMessage(SimpleRemoteEPCOpcode OpC,uint64_t SeqNo,ExecutorAddr TagAddr,SimpleRemoteEPCArgBytesVector ArgBytes)102bb72f073SLang Hames SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
103ef391df2SLang Hames                                ExecutorAddr TagAddr,
104bb72f073SLang Hames                                SimpleRemoteEPCArgBytesVector ArgBytes) {
105175c1a39SLang Hames 
106175c1a39SLang Hames   LLVM_DEBUG({
107175c1a39SLang Hames     dbgs() << "SimpleRemoteEPC::handleMessage: opc = ";
108175c1a39SLang Hames     switch (OpC) {
109175c1a39SLang Hames     case SimpleRemoteEPCOpcode::Setup:
110175c1a39SLang Hames       dbgs() << "Setup";
111175c1a39SLang Hames       assert(SeqNo == 0 && "Non-zero SeqNo for Setup?");
112175c1a39SLang Hames       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Setup?");
113175c1a39SLang Hames       break;
114175c1a39SLang Hames     case SimpleRemoteEPCOpcode::Hangup:
115175c1a39SLang Hames       dbgs() << "Hangup";
116175c1a39SLang Hames       assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");
117175c1a39SLang Hames       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Hangup?");
118175c1a39SLang Hames       break;
119175c1a39SLang Hames     case SimpleRemoteEPCOpcode::Result:
120175c1a39SLang Hames       dbgs() << "Result";
121175c1a39SLang Hames       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Result?");
122175c1a39SLang Hames       break;
123175c1a39SLang Hames     case SimpleRemoteEPCOpcode::CallWrapper:
124175c1a39SLang Hames       dbgs() << "CallWrapper";
125175c1a39SLang Hames       break;
126175c1a39SLang Hames     }
127175c1a39SLang Hames     dbgs() << ", seqno = " << SeqNo
128175c1a39SLang Hames            << ", tag-addr = " << formatv("{0:x}", TagAddr.getValue())
129175c1a39SLang Hames            << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())
130175c1a39SLang Hames            << " bytes\n";
131175c1a39SLang Hames   });
132175c1a39SLang Hames 
133bb72f073SLang Hames   using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>;
134d11a0c5dSLang Hames   if (static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC))
135bb72f073SLang Hames     return make_error<StringError>("Unexpected opcode",
136bb72f073SLang Hames                                    inconvertibleErrorCode());
137bb72f073SLang Hames 
138bb72f073SLang Hames   switch (OpC) {
139bb72f073SLang Hames   case SimpleRemoteEPCOpcode::Setup:
140bb72f073SLang Hames     if (auto Err = handleSetup(SeqNo, TagAddr, std::move(ArgBytes)))
141bb72f073SLang Hames       return std::move(Err);
142bb72f073SLang Hames     break;
143bb72f073SLang Hames   case SimpleRemoteEPCOpcode::Hangup:
144a6c95063SStefan Gränitz     T->disconnect();
145a6c95063SStefan Gränitz     if (auto Err = handleHangup(std::move(ArgBytes)))
146a6c95063SStefan Gränitz       return std::move(Err);
147a6c95063SStefan Gränitz     return EndSession;
148bb72f073SLang Hames   case SimpleRemoteEPCOpcode::Result:
149bb72f073SLang Hames     if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))
150bb72f073SLang Hames       return std::move(Err);
151bb72f073SLang Hames     break;
152bb72f073SLang Hames   case SimpleRemoteEPCOpcode::CallWrapper:
153bb72f073SLang Hames     handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes));
154bb72f073SLang Hames     break;
155bb72f073SLang Hames   }
156bb72f073SLang Hames   return ContinueSession;
157bb72f073SLang Hames }
158bb72f073SLang Hames 
handleDisconnect(Error Err)159bb72f073SLang Hames void SimpleRemoteEPC::handleDisconnect(Error Err) {
160175c1a39SLang Hames   LLVM_DEBUG({
161175c1a39SLang Hames     dbgs() << "SimpleRemoteEPC::handleDisconnect: "
162175c1a39SLang Hames            << (Err ? "failure" : "success") << "\n";
163175c1a39SLang Hames   });
164175c1a39SLang Hames 
165bb72f073SLang Hames   PendingCallWrapperResultsMap TmpPending;
166bb72f073SLang Hames 
167bb72f073SLang Hames   {
168bb72f073SLang Hames     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
169bb72f073SLang Hames     std::swap(TmpPending, PendingCallWrapperResults);
170bb72f073SLang Hames   }
171bb72f073SLang Hames 
172bb72f073SLang Hames   for (auto &KV : TmpPending)
173bb72f073SLang Hames     KV.second(
174bb72f073SLang Hames         shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
175bb72f073SLang Hames 
176320832ccSLang Hames   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
177320832ccSLang Hames   DisconnectErr = joinErrors(std::move(DisconnectErr), std::move(Err));
178320832ccSLang Hames   Disconnected = true;
179320832ccSLang Hames   DisconnectCV.notify_all();
180bb72f073SLang Hames }
181bb72f073SLang Hames 
182b64fc0afSLang Hames Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
createDefaultMemoryManager(SimpleRemoteEPC & SREPC)1834fcc0ac1SLang Hames SimpleRemoteEPC::createDefaultMemoryManager(SimpleRemoteEPC &SREPC) {
18478b083dbSLang Hames   EPCGenericJITLinkMemoryManager::SymbolAddrs SAs;
1854fcc0ac1SLang Hames   if (auto Err = SREPC.getBootstrapSymbols(
18678b083dbSLang Hames           {{SAs.Allocator, rt::SimpleExecutorMemoryManagerInstanceName},
18778b083dbSLang Hames            {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
18878b083dbSLang Hames            {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
18978b083dbSLang Hames            {SAs.Deallocate,
19078b083dbSLang Hames             rt::SimpleExecutorMemoryManagerDeallocateWrapperName}}))
191b64fc0afSLang Hames     return std::move(Err);
192bb72f073SLang Hames 
1934fcc0ac1SLang Hames   return std::make_unique<EPCGenericJITLinkMemoryManager>(SREPC, SAs);
194bb72f073SLang Hames }
195bb72f073SLang Hames 
196b64fc0afSLang Hames Expected<std::unique_ptr<ExecutorProcessControl::MemoryAccess>>
createDefaultMemoryAccess(SimpleRemoteEPC & SREPC)1974fcc0ac1SLang Hames SimpleRemoteEPC::createDefaultMemoryAccess(SimpleRemoteEPC &SREPC) {
198b64fc0afSLang Hames   return nullptr;
199bb72f073SLang Hames }
200bb72f073SLang Hames 
sendMessage(SimpleRemoteEPCOpcode OpC,uint64_t SeqNo,ExecutorAddr TagAddr,ArrayRef<char> ArgBytes)201175c1a39SLang Hames Error SimpleRemoteEPC::sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
202175c1a39SLang Hames                                    ExecutorAddr TagAddr,
203175c1a39SLang Hames                                    ArrayRef<char> ArgBytes) {
204175c1a39SLang Hames   assert(OpC != SimpleRemoteEPCOpcode::Setup &&
205175c1a39SLang Hames          "SimpleRemoteEPC sending Setup message? That's the wrong direction.");
206175c1a39SLang Hames 
207175c1a39SLang Hames   LLVM_DEBUG({
208175c1a39SLang Hames     dbgs() << "SimpleRemoteEPC::sendMessage: opc = ";
209175c1a39SLang Hames     switch (OpC) {
210175c1a39SLang Hames     case SimpleRemoteEPCOpcode::Hangup:
211175c1a39SLang Hames       dbgs() << "Hangup";
212175c1a39SLang Hames       assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");
213175c1a39SLang Hames       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Hangup?");
214175c1a39SLang Hames       break;
215175c1a39SLang Hames     case SimpleRemoteEPCOpcode::Result:
216175c1a39SLang Hames       dbgs() << "Result";
217175c1a39SLang Hames       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Result?");
218175c1a39SLang Hames       break;
219175c1a39SLang Hames     case SimpleRemoteEPCOpcode::CallWrapper:
220175c1a39SLang Hames       dbgs() << "CallWrapper";
221175c1a39SLang Hames       break;
222175c1a39SLang Hames     default:
223175c1a39SLang Hames       llvm_unreachable("Invalid opcode");
224175c1a39SLang Hames     }
225175c1a39SLang Hames     dbgs() << ", seqno = " << SeqNo
226175c1a39SLang Hames            << ", tag-addr = " << formatv("{0:x}", TagAddr.getValue())
227175c1a39SLang Hames            << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())
228175c1a39SLang Hames            << " bytes\n";
229175c1a39SLang Hames   });
230175c1a39SLang Hames   auto Err = T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes);
231175c1a39SLang Hames   LLVM_DEBUG({
232175c1a39SLang Hames     if (Err)
233175c1a39SLang Hames       dbgs() << "  \\--> SimpleRemoteEPC::sendMessage failed\n";
234175c1a39SLang Hames   });
235175c1a39SLang Hames   return Err;
236175c1a39SLang Hames }
237175c1a39SLang Hames 
handleSetup(uint64_t SeqNo,ExecutorAddr TagAddr,SimpleRemoteEPCArgBytesVector ArgBytes)238ef391df2SLang Hames Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
239bb72f073SLang Hames                                    SimpleRemoteEPCArgBytesVector ArgBytes) {
240bb72f073SLang Hames   if (SeqNo != 0)
241bb72f073SLang Hames     return make_error<StringError>("Setup packet SeqNo not zero",
242bb72f073SLang Hames                                    inconvertibleErrorCode());
243bb72f073SLang Hames 
244bb72f073SLang Hames   if (TagAddr)
245bb72f073SLang Hames     return make_error<StringError>("Setup packet TagAddr not zero",
246bb72f073SLang Hames                                    inconvertibleErrorCode());
247bb72f073SLang Hames 
248bb72f073SLang Hames   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
249bb72f073SLang Hames   auto I = PendingCallWrapperResults.find(0);
250bb72f073SLang Hames   assert(PendingCallWrapperResults.size() == 1 &&
251bb72f073SLang Hames          I != PendingCallWrapperResults.end() &&
252bb72f073SLang Hames          "Setup message handler not connectly set up");
253bb72f073SLang Hames   auto SetupMsgHandler = std::move(I->second);
254bb72f073SLang Hames   PendingCallWrapperResults.erase(I);
255bb72f073SLang Hames 
256bb72f073SLang Hames   auto WFR =
257bb72f073SLang Hames       shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
258bb72f073SLang Hames   SetupMsgHandler(std::move(WFR));
259bb72f073SLang Hames   return Error::success();
260bb72f073SLang Hames }
261bb72f073SLang Hames 
setup(Setup S)2624fcc0ac1SLang Hames Error SimpleRemoteEPC::setup(Setup S) {
2634b37462aSLang Hames   using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;
2644b37462aSLang Hames 
2654b37462aSLang Hames   std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP;
2664b37462aSLang Hames   auto EIF = EIP.get_future();
2674b37462aSLang Hames 
2684b37462aSLang Hames   // Prepare a handler for the setup packet.
269bb72f073SLang Hames   PendingCallWrapperResults[0] =
2704d7cea3dSLang Hames     RunInPlace()(
271bb72f073SLang Hames       [&](shared::WrapperFunctionResult SetupMsgBytes) {
272bb72f073SLang Hames         if (const char *ErrMsg = SetupMsgBytes.getOutOfBandError()) {
2734b37462aSLang Hames           EIP.set_value(
274bb72f073SLang Hames               make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
275bb72f073SLang Hames           return;
276bb72f073SLang Hames         }
277bb72f073SLang Hames         using SPSSerialize =
278bb72f073SLang Hames             shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>;
279bb72f073SLang Hames         shared::SPSInputBuffer IB(SetupMsgBytes.data(), SetupMsgBytes.size());
280bb72f073SLang Hames         SimpleRemoteEPCExecutorInfo EI;
281bb72f073SLang Hames         if (SPSSerialize::deserialize(IB, EI))
2824b37462aSLang Hames           EIP.set_value(EI);
283bb72f073SLang Hames         else
2844b37462aSLang Hames           EIP.set_value(make_error<StringError>(
285bb72f073SLang Hames               "Could not deserialize setup message", inconvertibleErrorCode()));
2864d7cea3dSLang Hames       });
2874b37462aSLang Hames 
2884b37462aSLang Hames   // Start the transport.
2894b37462aSLang Hames   if (auto Err = T->start())
2904b37462aSLang Hames     return Err;
2914b37462aSLang Hames 
2924b37462aSLang Hames   // Wait for setup packet to arrive.
2934b37462aSLang Hames   auto EI = EIF.get();
2944b37462aSLang Hames   if (!EI) {
2954b37462aSLang Hames     T->disconnect();
2964b37462aSLang Hames     return EI.takeError();
297bb72f073SLang Hames   }
298bb72f073SLang Hames 
299b64fc0afSLang Hames   LLVM_DEBUG({
300b64fc0afSLang Hames     dbgs() << "SimpleRemoteEPC received setup message:\n"
3014b37462aSLang Hames            << "  Triple: " << EI->TargetTriple << "\n"
3024b37462aSLang Hames            << "  Page size: " << EI->PageSize << "\n"
303b64fc0afSLang Hames            << "  Bootstrap symbols:\n";
3044b37462aSLang Hames     for (const auto &KV : EI->BootstrapSymbols)
305b64fc0afSLang Hames       dbgs() << "    " << KV.first() << ": "
306b64fc0afSLang Hames              << formatv("{0:x16}", KV.second.getValue()) << "\n";
307b64fc0afSLang Hames   });
3084b37462aSLang Hames   TargetTriple = Triple(EI->TargetTriple);
3094b37462aSLang Hames   PageSize = EI->PageSize;
3104b37462aSLang Hames   BootstrapSymbols = std::move(EI->BootstrapSymbols);
311b64fc0afSLang Hames 
312b64fc0afSLang Hames   if (auto Err = getBootstrapSymbols(
313ef391df2SLang Hames           {{JDI.JITDispatchContext, ExecutorSessionObjectName},
314ef391df2SLang Hames            {JDI.JITDispatchFunction, DispatchFnName},
3152c8e7849SLang Hames            {RunAsMainAddr, rt::RunAsMainWrapperName}}))
316b64fc0afSLang Hames     return Err;
317b64fc0afSLang Hames 
318a2c1cf09SLang Hames   if (auto DM =
319a2c1cf09SLang Hames           EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this))
320a2c1cf09SLang Hames     DylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM));
321a2c1cf09SLang Hames   else
322a2c1cf09SLang Hames     return DM.takeError();
323a2c1cf09SLang Hames 
3244fcc0ac1SLang Hames   // Set a default CreateMemoryManager if none is specified.
3254fcc0ac1SLang Hames   if (!S.CreateMemoryManager)
3264fcc0ac1SLang Hames     S.CreateMemoryManager = createDefaultMemoryManager;
3274fcc0ac1SLang Hames 
3284fcc0ac1SLang Hames   if (auto MemMgr = S.CreateMemoryManager(*this)) {
329b64fc0afSLang Hames     OwnedMemMgr = std::move(*MemMgr);
330b64fc0afSLang Hames     this->MemMgr = OwnedMemMgr.get();
331b64fc0afSLang Hames   } else
332b64fc0afSLang Hames     return MemMgr.takeError();
333b64fc0afSLang Hames 
3344fcc0ac1SLang Hames   // Set a default CreateMemoryAccess if none is specified.
3354fcc0ac1SLang Hames   if (!S.CreateMemoryAccess)
3364fcc0ac1SLang Hames     S.CreateMemoryAccess = createDefaultMemoryAccess;
3374fcc0ac1SLang Hames 
3384fcc0ac1SLang Hames   if (auto MemAccess = S.CreateMemoryAccess(*this)) {
339b64fc0afSLang Hames     OwnedMemAccess = std::move(*MemAccess);
340b64fc0afSLang Hames     this->MemAccess = OwnedMemAccess.get();
341b64fc0afSLang Hames   } else
342b64fc0afSLang Hames     return MemAccess.takeError();
343b64fc0afSLang Hames 
344b64fc0afSLang Hames   return Error::success();
345b64fc0afSLang Hames }
346b64fc0afSLang Hames 
handleResult(uint64_t SeqNo,ExecutorAddr TagAddr,SimpleRemoteEPCArgBytesVector ArgBytes)347ef391df2SLang Hames Error SimpleRemoteEPC::handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
348bb72f073SLang Hames                                     SimpleRemoteEPCArgBytesVector ArgBytes) {
3494d7cea3dSLang Hames   IncomingWFRHandler SendResult;
350bb72f073SLang Hames 
351bb72f073SLang Hames   if (TagAddr)
352bb72f073SLang Hames     return make_error<StringError>("Unexpected TagAddr in result message",
353bb72f073SLang Hames                                    inconvertibleErrorCode());
354bb72f073SLang Hames 
355bb72f073SLang Hames   {
356bb72f073SLang Hames     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
357bb72f073SLang Hames     auto I = PendingCallWrapperResults.find(SeqNo);
358bb72f073SLang Hames     if (I == PendingCallWrapperResults.end())
359bb72f073SLang Hames       return make_error<StringError>("No call for sequence number " +
360bb72f073SLang Hames                                          Twine(SeqNo),
361bb72f073SLang Hames                                      inconvertibleErrorCode());
362bb72f073SLang Hames     SendResult = std::move(I->second);
363bb72f073SLang Hames     PendingCallWrapperResults.erase(I);
364bb72f073SLang Hames     releaseSeqNo(SeqNo);
365bb72f073SLang Hames   }
366bb72f073SLang Hames 
367bb72f073SLang Hames   auto WFR =
368bb72f073SLang Hames       shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
369bb72f073SLang Hames   SendResult(std::move(WFR));
370bb72f073SLang Hames   return Error::success();
371bb72f073SLang Hames }
372bb72f073SLang Hames 
handleCallWrapper(uint64_t RemoteSeqNo,ExecutorAddr TagAddr,SimpleRemoteEPCArgBytesVector ArgBytes)373bb72f073SLang Hames void SimpleRemoteEPC::handleCallWrapper(
374ef391df2SLang Hames     uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
375bb72f073SLang Hames     SimpleRemoteEPCArgBytesVector ArgBytes) {
376bb72f073SLang Hames   assert(ES && "No ExecutionSession attached");
377*e9014d97SLang Hames   D->dispatch(makeGenericNamedTask(
378*e9014d97SLang Hames       [this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() {
379bb72f073SLang Hames         ES->runJITDispatchHandler(
380bb72f073SLang Hames             [this, RemoteSeqNo](shared::WrapperFunctionResult WFR) {
381*e9014d97SLang Hames               if (auto Err =
382*e9014d97SLang Hames                       sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo,
383ef391df2SLang Hames                                   ExecutorAddr(), {WFR.data(), WFR.size()}))
384bb72f073SLang Hames                 getExecutionSession().reportError(std::move(Err));
385bb72f073SLang Hames             },
386bb72f073SLang Hames             TagAddr.getValue(), ArgBytes);
387*e9014d97SLang Hames       },
388*e9014d97SLang Hames       "callWrapper task"));
389bb72f073SLang Hames }
390bb72f073SLang Hames 
handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes)391a6c95063SStefan Gränitz Error SimpleRemoteEPC::handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes) {
392a6c95063SStefan Gränitz   using namespace llvm::orc::shared;
393a6c95063SStefan Gränitz   auto WFR = WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
394a6c95063SStefan Gränitz   if (const char *ErrMsg = WFR.getOutOfBandError())
395a6c95063SStefan Gränitz     return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
396a6c95063SStefan Gränitz 
397a6c95063SStefan Gränitz   detail::SPSSerializableError Info;
398a6c95063SStefan Gränitz   SPSInputBuffer IB(WFR.data(), WFR.size());
399a6c95063SStefan Gränitz   if (!SPSArgList<SPSError>::deserialize(IB, Info))
400a6c95063SStefan Gränitz     return make_error<StringError>("Could not deserialize hangup info",
401a6c95063SStefan Gränitz                                    inconvertibleErrorCode());
402a6c95063SStefan Gränitz   return fromSPSSerializable(std::move(Info));
403a6c95063SStefan Gränitz }
404a6c95063SStefan Gränitz 
405bb72f073SLang Hames } // end namespace orc
406bb72f073SLang Hames } // end namespace llvm
407