1*349cc55cSDimitry Andric //===------- SimpleRemoteEPC.cpp -- Simple remote executor control --------===// 2*349cc55cSDimitry Andric // 3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*349cc55cSDimitry Andric // 7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8*349cc55cSDimitry Andric 9*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h" 10*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h" 11*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h" 12*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" 13*349cc55cSDimitry Andric #include "llvm/Support/FormatVariadic.h" 14*349cc55cSDimitry Andric 15*349cc55cSDimitry Andric #define DEBUG_TYPE "orc" 16*349cc55cSDimitry Andric 17*349cc55cSDimitry Andric namespace llvm { 18*349cc55cSDimitry Andric namespace orc { 19*349cc55cSDimitry Andric 20*349cc55cSDimitry Andric SimpleRemoteEPC::~SimpleRemoteEPC() { 21*349cc55cSDimitry Andric #ifndef NDEBUG 22*349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 23*349cc55cSDimitry Andric assert(Disconnected && "Destroyed without disconnection"); 24*349cc55cSDimitry Andric #endif // NDEBUG 25*349cc55cSDimitry Andric } 26*349cc55cSDimitry Andric 27*349cc55cSDimitry Andric Expected<tpctypes::DylibHandle> 28*349cc55cSDimitry Andric SimpleRemoteEPC::loadDylib(const char *DylibPath) { 29*349cc55cSDimitry Andric return DylibMgr->open(DylibPath, 0); 30*349cc55cSDimitry Andric } 31*349cc55cSDimitry Andric 32*349cc55cSDimitry Andric Expected<std::vector<tpctypes::LookupResult>> 33*349cc55cSDimitry Andric SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) { 34*349cc55cSDimitry Andric std::vector<tpctypes::LookupResult> Result; 35*349cc55cSDimitry Andric 36*349cc55cSDimitry Andric for (auto &Element : Request) { 37*349cc55cSDimitry Andric if (auto R = DylibMgr->lookup(Element.Handle, Element.Symbols)) { 38*349cc55cSDimitry Andric Result.push_back({}); 39*349cc55cSDimitry Andric Result.back().reserve(R->size()); 40*349cc55cSDimitry Andric for (auto Addr : *R) 41*349cc55cSDimitry Andric Result.back().push_back(Addr.getValue()); 42*349cc55cSDimitry Andric } else 43*349cc55cSDimitry Andric return R.takeError(); 44*349cc55cSDimitry Andric } 45*349cc55cSDimitry Andric return std::move(Result); 46*349cc55cSDimitry Andric } 47*349cc55cSDimitry Andric 48*349cc55cSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsMain(ExecutorAddr MainFnAddr, 49*349cc55cSDimitry Andric ArrayRef<std::string> Args) { 50*349cc55cSDimitry Andric int64_t Result = 0; 51*349cc55cSDimitry Andric if (auto Err = callSPSWrapper<rt::SPSRunAsMainSignature>( 52*349cc55cSDimitry Andric RunAsMainAddr, Result, ExecutorAddr(MainFnAddr), Args)) 53*349cc55cSDimitry Andric return std::move(Err); 54*349cc55cSDimitry Andric return Result; 55*349cc55cSDimitry Andric } 56*349cc55cSDimitry Andric 57*349cc55cSDimitry Andric void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr, 58*349cc55cSDimitry Andric IncomingWFRHandler OnComplete, 59*349cc55cSDimitry Andric ArrayRef<char> ArgBuffer) { 60*349cc55cSDimitry Andric uint64_t SeqNo; 61*349cc55cSDimitry Andric { 62*349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 63*349cc55cSDimitry Andric SeqNo = getNextSeqNo(); 64*349cc55cSDimitry Andric assert(!PendingCallWrapperResults.count(SeqNo) && "SeqNo already in use"); 65*349cc55cSDimitry Andric PendingCallWrapperResults[SeqNo] = std::move(OnComplete); 66*349cc55cSDimitry Andric } 67*349cc55cSDimitry Andric 68*349cc55cSDimitry Andric if (auto Err = sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo, 69*349cc55cSDimitry Andric WrapperFnAddr, ArgBuffer)) { 70*349cc55cSDimitry Andric IncomingWFRHandler H; 71*349cc55cSDimitry Andric 72*349cc55cSDimitry Andric // We just registered OnComplete, but there may be a race between this 73*349cc55cSDimitry Andric // thread returning from sendMessage and handleDisconnect being called from 74*349cc55cSDimitry Andric // the transport's listener thread. If handleDisconnect gets there first 75*349cc55cSDimitry Andric // then it will have failed 'H' for us. If we get there first (or if 76*349cc55cSDimitry Andric // handleDisconnect already ran) then we need to take care of it. 77*349cc55cSDimitry Andric { 78*349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 79*349cc55cSDimitry Andric auto I = PendingCallWrapperResults.find(SeqNo); 80*349cc55cSDimitry Andric if (I != PendingCallWrapperResults.end()) { 81*349cc55cSDimitry Andric H = std::move(I->second); 82*349cc55cSDimitry Andric PendingCallWrapperResults.erase(I); 83*349cc55cSDimitry Andric } 84*349cc55cSDimitry Andric } 85*349cc55cSDimitry Andric 86*349cc55cSDimitry Andric if (H) 87*349cc55cSDimitry Andric H(shared::WrapperFunctionResult::createOutOfBandError("disconnecting")); 88*349cc55cSDimitry Andric 89*349cc55cSDimitry Andric getExecutionSession().reportError(std::move(Err)); 90*349cc55cSDimitry Andric } 91*349cc55cSDimitry Andric } 92*349cc55cSDimitry Andric 93*349cc55cSDimitry Andric Error SimpleRemoteEPC::disconnect() { 94*349cc55cSDimitry Andric T->disconnect(); 95*349cc55cSDimitry Andric D->shutdown(); 96*349cc55cSDimitry Andric std::unique_lock<std::mutex> Lock(SimpleRemoteEPCMutex); 97*349cc55cSDimitry Andric DisconnectCV.wait(Lock, [this] { return Disconnected; }); 98*349cc55cSDimitry Andric return std::move(DisconnectErr); 99*349cc55cSDimitry Andric } 100*349cc55cSDimitry Andric 101*349cc55cSDimitry Andric Expected<SimpleRemoteEPCTransportClient::HandleMessageAction> 102*349cc55cSDimitry Andric SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 103*349cc55cSDimitry Andric ExecutorAddr TagAddr, 104*349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 105*349cc55cSDimitry Andric 106*349cc55cSDimitry Andric LLVM_DEBUG({ 107*349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC::handleMessage: opc = "; 108*349cc55cSDimitry Andric switch (OpC) { 109*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Setup: 110*349cc55cSDimitry Andric dbgs() << "Setup"; 111*349cc55cSDimitry Andric assert(SeqNo == 0 && "Non-zero SeqNo for Setup?"); 112*349cc55cSDimitry Andric assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Setup?"); 113*349cc55cSDimitry Andric break; 114*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Hangup: 115*349cc55cSDimitry Andric dbgs() << "Hangup"; 116*349cc55cSDimitry Andric assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?"); 117*349cc55cSDimitry Andric assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Hangup?"); 118*349cc55cSDimitry Andric break; 119*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Result: 120*349cc55cSDimitry Andric dbgs() << "Result"; 121*349cc55cSDimitry Andric assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Result?"); 122*349cc55cSDimitry Andric break; 123*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::CallWrapper: 124*349cc55cSDimitry Andric dbgs() << "CallWrapper"; 125*349cc55cSDimitry Andric break; 126*349cc55cSDimitry Andric } 127*349cc55cSDimitry Andric dbgs() << ", seqno = " << SeqNo 128*349cc55cSDimitry Andric << ", tag-addr = " << formatv("{0:x}", TagAddr.getValue()) 129*349cc55cSDimitry Andric << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size()) 130*349cc55cSDimitry Andric << " bytes\n"; 131*349cc55cSDimitry Andric }); 132*349cc55cSDimitry Andric 133*349cc55cSDimitry Andric using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>; 134*349cc55cSDimitry Andric if (static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC)) 135*349cc55cSDimitry Andric return make_error<StringError>("Unexpected opcode", 136*349cc55cSDimitry Andric inconvertibleErrorCode()); 137*349cc55cSDimitry Andric 138*349cc55cSDimitry Andric switch (OpC) { 139*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Setup: 140*349cc55cSDimitry Andric if (auto Err = handleSetup(SeqNo, TagAddr, std::move(ArgBytes))) 141*349cc55cSDimitry Andric return std::move(Err); 142*349cc55cSDimitry Andric break; 143*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Hangup: 144*349cc55cSDimitry Andric T->disconnect(); 145*349cc55cSDimitry Andric if (auto Err = handleHangup(std::move(ArgBytes))) 146*349cc55cSDimitry Andric return std::move(Err); 147*349cc55cSDimitry Andric return EndSession; 148*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Result: 149*349cc55cSDimitry Andric if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes))) 150*349cc55cSDimitry Andric return std::move(Err); 151*349cc55cSDimitry Andric break; 152*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::CallWrapper: 153*349cc55cSDimitry Andric handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes)); 154*349cc55cSDimitry Andric break; 155*349cc55cSDimitry Andric } 156*349cc55cSDimitry Andric return ContinueSession; 157*349cc55cSDimitry Andric } 158*349cc55cSDimitry Andric 159*349cc55cSDimitry Andric void SimpleRemoteEPC::handleDisconnect(Error Err) { 160*349cc55cSDimitry Andric LLVM_DEBUG({ 161*349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC::handleDisconnect: " 162*349cc55cSDimitry Andric << (Err ? "failure" : "success") << "\n"; 163*349cc55cSDimitry Andric }); 164*349cc55cSDimitry Andric 165*349cc55cSDimitry Andric PendingCallWrapperResultsMap TmpPending; 166*349cc55cSDimitry Andric 167*349cc55cSDimitry Andric { 168*349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 169*349cc55cSDimitry Andric std::swap(TmpPending, PendingCallWrapperResults); 170*349cc55cSDimitry Andric } 171*349cc55cSDimitry Andric 172*349cc55cSDimitry Andric for (auto &KV : TmpPending) 173*349cc55cSDimitry Andric KV.second( 174*349cc55cSDimitry Andric shared::WrapperFunctionResult::createOutOfBandError("disconnecting")); 175*349cc55cSDimitry Andric 176*349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 177*349cc55cSDimitry Andric DisconnectErr = joinErrors(std::move(DisconnectErr), std::move(Err)); 178*349cc55cSDimitry Andric Disconnected = true; 179*349cc55cSDimitry Andric DisconnectCV.notify_all(); 180*349cc55cSDimitry Andric } 181*349cc55cSDimitry Andric 182*349cc55cSDimitry Andric Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>> 183*349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryManager(SimpleRemoteEPC &SREPC) { 184*349cc55cSDimitry Andric EPCGenericJITLinkMemoryManager::SymbolAddrs SAs; 185*349cc55cSDimitry Andric if (auto Err = SREPC.getBootstrapSymbols( 186*349cc55cSDimitry Andric {{SAs.Allocator, rt::SimpleExecutorMemoryManagerInstanceName}, 187*349cc55cSDimitry Andric {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName}, 188*349cc55cSDimitry Andric {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName}, 189*349cc55cSDimitry Andric {SAs.Deallocate, 190*349cc55cSDimitry Andric rt::SimpleExecutorMemoryManagerDeallocateWrapperName}})) 191*349cc55cSDimitry Andric return std::move(Err); 192*349cc55cSDimitry Andric 193*349cc55cSDimitry Andric return std::make_unique<EPCGenericJITLinkMemoryManager>(SREPC, SAs); 194*349cc55cSDimitry Andric } 195*349cc55cSDimitry Andric 196*349cc55cSDimitry Andric Expected<std::unique_ptr<ExecutorProcessControl::MemoryAccess>> 197*349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryAccess(SimpleRemoteEPC &SREPC) { 198*349cc55cSDimitry Andric return nullptr; 199*349cc55cSDimitry Andric } 200*349cc55cSDimitry Andric 201*349cc55cSDimitry Andric Error SimpleRemoteEPC::sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 202*349cc55cSDimitry Andric ExecutorAddr TagAddr, 203*349cc55cSDimitry Andric ArrayRef<char> ArgBytes) { 204*349cc55cSDimitry Andric assert(OpC != SimpleRemoteEPCOpcode::Setup && 205*349cc55cSDimitry Andric "SimpleRemoteEPC sending Setup message? That's the wrong direction."); 206*349cc55cSDimitry Andric 207*349cc55cSDimitry Andric LLVM_DEBUG({ 208*349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC::sendMessage: opc = "; 209*349cc55cSDimitry Andric switch (OpC) { 210*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Hangup: 211*349cc55cSDimitry Andric dbgs() << "Hangup"; 212*349cc55cSDimitry Andric assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?"); 213*349cc55cSDimitry Andric assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Hangup?"); 214*349cc55cSDimitry Andric break; 215*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Result: 216*349cc55cSDimitry Andric dbgs() << "Result"; 217*349cc55cSDimitry Andric assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Result?"); 218*349cc55cSDimitry Andric break; 219*349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::CallWrapper: 220*349cc55cSDimitry Andric dbgs() << "CallWrapper"; 221*349cc55cSDimitry Andric break; 222*349cc55cSDimitry Andric default: 223*349cc55cSDimitry Andric llvm_unreachable("Invalid opcode"); 224*349cc55cSDimitry Andric } 225*349cc55cSDimitry Andric dbgs() << ", seqno = " << SeqNo 226*349cc55cSDimitry Andric << ", tag-addr = " << formatv("{0:x}", TagAddr.getValue()) 227*349cc55cSDimitry Andric << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size()) 228*349cc55cSDimitry Andric << " bytes\n"; 229*349cc55cSDimitry Andric }); 230*349cc55cSDimitry Andric auto Err = T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes); 231*349cc55cSDimitry Andric LLVM_DEBUG({ 232*349cc55cSDimitry Andric if (Err) 233*349cc55cSDimitry Andric dbgs() << " \\--> SimpleRemoteEPC::sendMessage failed\n"; 234*349cc55cSDimitry Andric }); 235*349cc55cSDimitry Andric return Err; 236*349cc55cSDimitry Andric } 237*349cc55cSDimitry Andric 238*349cc55cSDimitry Andric Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr, 239*349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 240*349cc55cSDimitry Andric if (SeqNo != 0) 241*349cc55cSDimitry Andric return make_error<StringError>("Setup packet SeqNo not zero", 242*349cc55cSDimitry Andric inconvertibleErrorCode()); 243*349cc55cSDimitry Andric 244*349cc55cSDimitry Andric if (TagAddr) 245*349cc55cSDimitry Andric return make_error<StringError>("Setup packet TagAddr not zero", 246*349cc55cSDimitry Andric inconvertibleErrorCode()); 247*349cc55cSDimitry Andric 248*349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 249*349cc55cSDimitry Andric auto I = PendingCallWrapperResults.find(0); 250*349cc55cSDimitry Andric assert(PendingCallWrapperResults.size() == 1 && 251*349cc55cSDimitry Andric I != PendingCallWrapperResults.end() && 252*349cc55cSDimitry Andric "Setup message handler not connectly set up"); 253*349cc55cSDimitry Andric auto SetupMsgHandler = std::move(I->second); 254*349cc55cSDimitry Andric PendingCallWrapperResults.erase(I); 255*349cc55cSDimitry Andric 256*349cc55cSDimitry Andric auto WFR = 257*349cc55cSDimitry Andric shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 258*349cc55cSDimitry Andric SetupMsgHandler(std::move(WFR)); 259*349cc55cSDimitry Andric return Error::success(); 260*349cc55cSDimitry Andric } 261*349cc55cSDimitry Andric 262*349cc55cSDimitry Andric Error SimpleRemoteEPC::setup(Setup S) { 263*349cc55cSDimitry Andric using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames; 264*349cc55cSDimitry Andric 265*349cc55cSDimitry Andric std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP; 266*349cc55cSDimitry Andric auto EIF = EIP.get_future(); 267*349cc55cSDimitry Andric 268*349cc55cSDimitry Andric // Prepare a handler for the setup packet. 269*349cc55cSDimitry Andric PendingCallWrapperResults[0] = 270*349cc55cSDimitry Andric RunInPlace()( 271*349cc55cSDimitry Andric [&](shared::WrapperFunctionResult SetupMsgBytes) { 272*349cc55cSDimitry Andric if (const char *ErrMsg = SetupMsgBytes.getOutOfBandError()) { 273*349cc55cSDimitry Andric EIP.set_value( 274*349cc55cSDimitry Andric make_error<StringError>(ErrMsg, inconvertibleErrorCode())); 275*349cc55cSDimitry Andric return; 276*349cc55cSDimitry Andric } 277*349cc55cSDimitry Andric using SPSSerialize = 278*349cc55cSDimitry Andric shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>; 279*349cc55cSDimitry Andric shared::SPSInputBuffer IB(SetupMsgBytes.data(), SetupMsgBytes.size()); 280*349cc55cSDimitry Andric SimpleRemoteEPCExecutorInfo EI; 281*349cc55cSDimitry Andric if (SPSSerialize::deserialize(IB, EI)) 282*349cc55cSDimitry Andric EIP.set_value(EI); 283*349cc55cSDimitry Andric else 284*349cc55cSDimitry Andric EIP.set_value(make_error<StringError>( 285*349cc55cSDimitry Andric "Could not deserialize setup message", inconvertibleErrorCode())); 286*349cc55cSDimitry Andric }); 287*349cc55cSDimitry Andric 288*349cc55cSDimitry Andric // Start the transport. 289*349cc55cSDimitry Andric if (auto Err = T->start()) 290*349cc55cSDimitry Andric return Err; 291*349cc55cSDimitry Andric 292*349cc55cSDimitry Andric // Wait for setup packet to arrive. 293*349cc55cSDimitry Andric auto EI = EIF.get(); 294*349cc55cSDimitry Andric if (!EI) { 295*349cc55cSDimitry Andric T->disconnect(); 296*349cc55cSDimitry Andric return EI.takeError(); 297*349cc55cSDimitry Andric } 298*349cc55cSDimitry Andric 299*349cc55cSDimitry Andric LLVM_DEBUG({ 300*349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC received setup message:\n" 301*349cc55cSDimitry Andric << " Triple: " << EI->TargetTriple << "\n" 302*349cc55cSDimitry Andric << " Page size: " << EI->PageSize << "\n" 303*349cc55cSDimitry Andric << " Bootstrap symbols:\n"; 304*349cc55cSDimitry Andric for (const auto &KV : EI->BootstrapSymbols) 305*349cc55cSDimitry Andric dbgs() << " " << KV.first() << ": " 306*349cc55cSDimitry Andric << formatv("{0:x16}", KV.second.getValue()) << "\n"; 307*349cc55cSDimitry Andric }); 308*349cc55cSDimitry Andric TargetTriple = Triple(EI->TargetTriple); 309*349cc55cSDimitry Andric PageSize = EI->PageSize; 310*349cc55cSDimitry Andric BootstrapSymbols = std::move(EI->BootstrapSymbols); 311*349cc55cSDimitry Andric 312*349cc55cSDimitry Andric if (auto Err = getBootstrapSymbols( 313*349cc55cSDimitry Andric {{JDI.JITDispatchContext, ExecutorSessionObjectName}, 314*349cc55cSDimitry Andric {JDI.JITDispatchFunction, DispatchFnName}, 315*349cc55cSDimitry Andric {RunAsMainAddr, rt::RunAsMainWrapperName}})) 316*349cc55cSDimitry Andric return Err; 317*349cc55cSDimitry Andric 318*349cc55cSDimitry Andric if (auto DM = 319*349cc55cSDimitry Andric EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this)) 320*349cc55cSDimitry Andric DylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM)); 321*349cc55cSDimitry Andric else 322*349cc55cSDimitry Andric return DM.takeError(); 323*349cc55cSDimitry Andric 324*349cc55cSDimitry Andric // Set a default CreateMemoryManager if none is specified. 325*349cc55cSDimitry Andric if (!S.CreateMemoryManager) 326*349cc55cSDimitry Andric S.CreateMemoryManager = createDefaultMemoryManager; 327*349cc55cSDimitry Andric 328*349cc55cSDimitry Andric if (auto MemMgr = S.CreateMemoryManager(*this)) { 329*349cc55cSDimitry Andric OwnedMemMgr = std::move(*MemMgr); 330*349cc55cSDimitry Andric this->MemMgr = OwnedMemMgr.get(); 331*349cc55cSDimitry Andric } else 332*349cc55cSDimitry Andric return MemMgr.takeError(); 333*349cc55cSDimitry Andric 334*349cc55cSDimitry Andric // Set a default CreateMemoryAccess if none is specified. 335*349cc55cSDimitry Andric if (!S.CreateMemoryAccess) 336*349cc55cSDimitry Andric S.CreateMemoryAccess = createDefaultMemoryAccess; 337*349cc55cSDimitry Andric 338*349cc55cSDimitry Andric if (auto MemAccess = S.CreateMemoryAccess(*this)) { 339*349cc55cSDimitry Andric OwnedMemAccess = std::move(*MemAccess); 340*349cc55cSDimitry Andric this->MemAccess = OwnedMemAccess.get(); 341*349cc55cSDimitry Andric } else 342*349cc55cSDimitry Andric return MemAccess.takeError(); 343*349cc55cSDimitry Andric 344*349cc55cSDimitry Andric return Error::success(); 345*349cc55cSDimitry Andric } 346*349cc55cSDimitry Andric 347*349cc55cSDimitry Andric Error SimpleRemoteEPC::handleResult(uint64_t SeqNo, ExecutorAddr TagAddr, 348*349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 349*349cc55cSDimitry Andric IncomingWFRHandler SendResult; 350*349cc55cSDimitry Andric 351*349cc55cSDimitry Andric if (TagAddr) 352*349cc55cSDimitry Andric return make_error<StringError>("Unexpected TagAddr in result message", 353*349cc55cSDimitry Andric inconvertibleErrorCode()); 354*349cc55cSDimitry Andric 355*349cc55cSDimitry Andric { 356*349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 357*349cc55cSDimitry Andric auto I = PendingCallWrapperResults.find(SeqNo); 358*349cc55cSDimitry Andric if (I == PendingCallWrapperResults.end()) 359*349cc55cSDimitry Andric return make_error<StringError>("No call for sequence number " + 360*349cc55cSDimitry Andric Twine(SeqNo), 361*349cc55cSDimitry Andric inconvertibleErrorCode()); 362*349cc55cSDimitry Andric SendResult = std::move(I->second); 363*349cc55cSDimitry Andric PendingCallWrapperResults.erase(I); 364*349cc55cSDimitry Andric releaseSeqNo(SeqNo); 365*349cc55cSDimitry Andric } 366*349cc55cSDimitry Andric 367*349cc55cSDimitry Andric auto WFR = 368*349cc55cSDimitry Andric shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 369*349cc55cSDimitry Andric SendResult(std::move(WFR)); 370*349cc55cSDimitry Andric return Error::success(); 371*349cc55cSDimitry Andric } 372*349cc55cSDimitry Andric 373*349cc55cSDimitry Andric void SimpleRemoteEPC::handleCallWrapper( 374*349cc55cSDimitry Andric uint64_t RemoteSeqNo, ExecutorAddr TagAddr, 375*349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 376*349cc55cSDimitry Andric assert(ES && "No ExecutionSession attached"); 377*349cc55cSDimitry Andric D->dispatch(makeGenericNamedTask( 378*349cc55cSDimitry Andric [this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() { 379*349cc55cSDimitry Andric ES->runJITDispatchHandler( 380*349cc55cSDimitry Andric [this, RemoteSeqNo](shared::WrapperFunctionResult WFR) { 381*349cc55cSDimitry Andric if (auto Err = 382*349cc55cSDimitry Andric sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo, 383*349cc55cSDimitry Andric ExecutorAddr(), {WFR.data(), WFR.size()})) 384*349cc55cSDimitry Andric getExecutionSession().reportError(std::move(Err)); 385*349cc55cSDimitry Andric }, 386*349cc55cSDimitry Andric TagAddr.getValue(), ArgBytes); 387*349cc55cSDimitry Andric }, 388*349cc55cSDimitry Andric "callWrapper task")); 389*349cc55cSDimitry Andric } 390*349cc55cSDimitry Andric 391*349cc55cSDimitry Andric Error SimpleRemoteEPC::handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes) { 392*349cc55cSDimitry Andric using namespace llvm::orc::shared; 393*349cc55cSDimitry Andric auto WFR = WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 394*349cc55cSDimitry Andric if (const char *ErrMsg = WFR.getOutOfBandError()) 395*349cc55cSDimitry Andric return make_error<StringError>(ErrMsg, inconvertibleErrorCode()); 396*349cc55cSDimitry Andric 397*349cc55cSDimitry Andric detail::SPSSerializableError Info; 398*349cc55cSDimitry Andric SPSInputBuffer IB(WFR.data(), WFR.size()); 399*349cc55cSDimitry Andric if (!SPSArgList<SPSError>::deserialize(IB, Info)) 400*349cc55cSDimitry Andric return make_error<StringError>("Could not deserialize hangup info", 401*349cc55cSDimitry Andric inconvertibleErrorCode()); 402*349cc55cSDimitry Andric return fromSPSSerializable(std::move(Info)); 403*349cc55cSDimitry Andric } 404*349cc55cSDimitry Andric 405*349cc55cSDimitry Andric } // end namespace orc 406*349cc55cSDimitry Andric } // end namespace llvm 407