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