diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h index b9db3890cc7..4d846986e8d 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h @@ -43,41 +43,54 @@ public: } std::error_code handleKnownProcedure(JITProcId Id) { + typedef OrcRemoteTargetServer ThisT; + DEBUG(dbgs() << "Handling known proc: " << getJITProcIdName(Id) << "\n"); switch (Id) { case CallIntVoidId: - return handleCallIntVoid(); + return handle(Channel, *this, &ThisT::handleCallIntVoid); case CallMainId: - return handleCallMain(); + return handle(Channel, *this, &ThisT::handleCallMain); case CallVoidVoidId: - return handleCallVoidVoid(); + return handle(Channel, *this, &ThisT::handleCallVoidVoid); case CreateRemoteAllocatorId: - return handleCreateRemoteAllocator(); + return handle(Channel, *this, + &ThisT::handleCreateRemoteAllocator); case CreateIndirectStubsOwnerId: - return handleCreateIndirectStubsOwner(); + return handle( + Channel, *this, &ThisT::handleCreateIndirectStubsOwner); case DestroyRemoteAllocatorId: - return handleDestroyRemoteAllocator(); + return handle( + Channel, *this, &ThisT::handleDestroyRemoteAllocator); + case DestroyIndirectStubsOwnerId: + return handle( + Channel, *this, &ThisT::handleDestroyIndirectStubsOwner); case EmitIndirectStubsId: - return handleEmitIndirectStubs(); + return handle(Channel, *this, + &ThisT::handleEmitIndirectStubs); case EmitResolverBlockId: - return handleEmitResolverBlock(); + return handle(Channel, *this, + &ThisT::handleEmitResolverBlock); case EmitTrampolineBlockId: - return handleEmitTrampolineBlock(); + return handle(Channel, *this, + &ThisT::handleEmitTrampolineBlock); case GetSymbolAddressId: - return handleGetSymbolAddress(); + return handle(Channel, *this, + &ThisT::handleGetSymbolAddress); case GetRemoteInfoId: - return handleGetRemoteInfo(); + return handle(Channel, *this, &ThisT::handleGetRemoteInfo); case ReadMemId: - return handleReadMem(); + return handle(Channel, *this, &ThisT::handleReadMem); case ReserveMemId: - return handleReserveMem(); + return handle(Channel, *this, &ThisT::handleReserveMem); case SetProtectionsId: - return handleSetProtections(); + return handle(Channel, *this, + &ThisT::handleSetProtections); case WriteMemId: - return handleWriteMem(); + return handle(Channel, *this, &ThisT::handleWriteMem); case WritePtrId: - return handleWritePtr(); + return handle(Channel, *this, &ThisT::handleWritePtr); default: return orcError(OrcErrorCode::UnexpectedRPCCall); } @@ -160,16 +173,10 @@ private: return CompiledFnAddr; } - std::error_code handleCallIntVoid() { + std::error_code handleCallIntVoid(TargetAddress Addr) { typedef int (*IntVoidFnTy)(); - - IntVoidFnTy Fn = nullptr; - if (std::error_code EC = - handle(Channel, [&](TargetAddress Addr) { - Fn = reinterpret_cast(static_cast(Addr)); - return std::error_code(); - })) - return EC; + IntVoidFnTy Fn = + reinterpret_cast(static_cast(Addr)); DEBUG(dbgs() << " Calling " << reinterpret_cast(reinterpret_cast(Fn)) @@ -180,19 +187,11 @@ private: return call(Channel, Result); } - std::error_code handleCallMain() { + std::error_code handleCallMain(TargetAddress Addr, + std::vector Args) { typedef int (*MainFnTy)(int, const char *[]); - MainFnTy Fn = nullptr; - std::vector Args; - if (std::error_code EC = handle( - Channel, [&](TargetAddress Addr, std::vector &A) { - Fn = reinterpret_cast(static_cast(Addr)); - Args = std::move(A); - return std::error_code(); - })) - return EC; - + MainFnTy Fn = reinterpret_cast(static_cast(Addr)); int ArgC = Args.size() + 1; int Idx = 1; std::unique_ptr ArgV(new const char *[ArgC + 1]); @@ -207,16 +206,10 @@ private: return call(Channel, Result); } - std::error_code handleCallVoidVoid() { + std::error_code handleCallVoidVoid(TargetAddress Addr) { typedef void (*VoidVoidFnTy)(); - - VoidVoidFnTy Fn = nullptr; - if (std::error_code EC = - handle(Channel, [&](TargetAddress Addr) { - Fn = reinterpret_cast(static_cast(Addr)); - return std::error_code(); - })) - return EC; + VoidVoidFnTy Fn = + reinterpret_cast(static_cast(Addr)); DEBUG(dbgs() << " Calling " << reinterpret_cast(Fn) << "\n"); Fn(); @@ -225,66 +218,48 @@ private: return call(Channel); } - std::error_code handleCreateRemoteAllocator() { - return handle( - Channel, [&](ResourceIdMgr::ResourceId Id) { - auto I = Allocators.find(Id); - if (I != Allocators.end()) - return orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse); - DEBUG(dbgs() << " Created allocator " << Id << "\n"); - Allocators[Id] = Allocator(); - return std::error_code(); - }); + std::error_code handleCreateRemoteAllocator(ResourceIdMgr::ResourceId Id) { + auto I = Allocators.find(Id); + if (I != Allocators.end()) + return orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse); + DEBUG(dbgs() << " Created allocator " << Id << "\n"); + Allocators[Id] = Allocator(); + return std::error_code(); } - std::error_code handleCreateIndirectStubsOwner() { - return handle( - Channel, [&](ResourceIdMgr::ResourceId Id) { - auto I = IndirectStubsOwners.find(Id); - if (I != IndirectStubsOwners.end()) - return orcError( - OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse); - DEBUG(dbgs() << " Create indirect stubs owner " << Id << "\n"); - IndirectStubsOwners[Id] = ISBlockOwnerList(); - return std::error_code(); - }); + std::error_code handleCreateIndirectStubsOwner(ResourceIdMgr::ResourceId Id) { + auto I = IndirectStubsOwners.find(Id); + if (I != IndirectStubsOwners.end()) + return orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse); + DEBUG(dbgs() << " Create indirect stubs owner " << Id << "\n"); + IndirectStubsOwners[Id] = ISBlockOwnerList(); + return std::error_code(); } - std::error_code handleDestroyRemoteAllocator() { - return handle( - Channel, [&](ResourceIdMgr::ResourceId Id) { - auto I = Allocators.find(Id); - if (I == Allocators.end()) - return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); - Allocators.erase(I); - DEBUG(dbgs() << " Destroyed allocator " << Id << "\n"); - return std::error_code(); - }); + std::error_code handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId Id) { + auto I = Allocators.find(Id); + if (I == Allocators.end()) + return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); + Allocators.erase(I); + DEBUG(dbgs() << " Destroyed allocator " << Id << "\n"); + return std::error_code(); } - std::error_code handleDestroyIndirectStubsOwner() { - return handle( - Channel, [&](ResourceIdMgr::ResourceId Id) { - auto I = IndirectStubsOwners.find(Id); - if (I == IndirectStubsOwners.end()) - return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist); - IndirectStubsOwners.erase(I); - return std::error_code(); - }); + std::error_code + handleDestroyIndirectStubsOwner(ResourceIdMgr::ResourceId Id) { + auto I = IndirectStubsOwners.find(Id); + if (I == IndirectStubsOwners.end()) + return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist); + IndirectStubsOwners.erase(I); + return std::error_code(); } - std::error_code handleEmitIndirectStubs() { - ResourceIdMgr::ResourceId ISOwnerId = ~0U; - uint32_t NumStubsRequired = 0; - - if (auto EC = handle( - Channel, readArgs(ISOwnerId, NumStubsRequired))) - return EC; - - DEBUG(dbgs() << " ISMgr " << ISOwnerId << " request " << NumStubsRequired + std::error_code handleEmitIndirectStubs(ResourceIdMgr::ResourceId Id, + uint32_t NumStubsRequired) { + DEBUG(dbgs() << " ISMgr " << Id << " request " << NumStubsRequired << " stubs.\n"); - auto StubOwnerItr = IndirectStubsOwners.find(ISOwnerId); + auto StubOwnerItr = IndirectStubsOwners.find(Id); if (StubOwnerItr == IndirectStubsOwners.end()) return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist); @@ -307,9 +282,6 @@ private: } std::error_code handleEmitResolverBlock() { - if (auto EC = handle(Channel, doNothing)) - return EC; - std::error_code EC; ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( TargetT::ResolverCodeSize, nullptr, @@ -326,11 +298,7 @@ private: } std::error_code handleEmitTrampolineBlock() { - if (auto EC = handle(Channel, doNothing)) - return EC; - std::error_code EC; - auto TrampolineBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( sys::Process::getPageSize(), nullptr, @@ -358,21 +326,14 @@ private: NumTrampolines); } - std::error_code handleGetSymbolAddress() { - std::string SymbolName; - if (auto EC = handle(Channel, readArgs(SymbolName))) - return EC; - - TargetAddress SymbolAddr = SymbolLookup(SymbolName); - DEBUG(dbgs() << " Symbol '" << SymbolName - << "' = " << format("0x%016x", SymbolAddr) << "\n"); - return call(Channel, SymbolAddr); + std::error_code handleGetSymbolAddress(const std::string &Name) { + TargetAddress Addr = SymbolLookup(Name); + DEBUG(dbgs() << " Symbol '" << Name << "' = " << format("0x%016x", Addr) + << "\n"); + return call(Channel, Addr); } std::error_code handleGetRemoteInfo() { - if (auto EC = handle(Channel, doNothing)) - return EC; - std::string ProcessTriple = sys::getProcessTriple(); uint32_t PointerSize = TargetT::PointerSize; uint32_t PageSize = sys::Process::getPageSize(); @@ -389,16 +350,8 @@ private: IndirectStubSize); } - std::error_code handleReadMem() { - char *Src = nullptr; - uint64_t Size = 0; - if (std::error_code EC = - handle(Channel, [&](TargetAddress RSrc, uint64_t RSize) { - Src = reinterpret_cast(static_cast(RSrc)); - Size = RSize; - return std::error_code(); - })) - return EC; + std::error_code handleReadMem(TargetAddress RSrc, uint64_t Size) { + char *Src = reinterpret_cast(static_cast(RSrc)); DEBUG(dbgs() << " Reading " << Size << " bytes from " << static_cast(Src) << "\n"); @@ -412,62 +365,49 @@ private: return Channel.send(); } - std::error_code handleReserveMem() { + std::error_code handleReserveMem(ResourceIdMgr::ResourceId Id, uint64_t Size, + uint32_t Align) { + auto I = Allocators.find(Id); + if (I == Allocators.end()) + return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); + auto &Allocator = I->second; void *LocalAllocAddr = nullptr; - - if (std::error_code EC = - handle(Channel, [&](ResourceIdMgr::ResourceId Id, - uint64_t Size, uint32_t Align) { - auto I = Allocators.find(Id); - if (I == Allocators.end()) - return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); - auto &Allocator = I->second; - auto EC2 = Allocator.allocate(LocalAllocAddr, Size, Align); - DEBUG(dbgs() << " Allocator " << Id << " reserved " - << LocalAllocAddr << " (" << Size - << " bytes, alignment " << Align << ")\n"); - return EC2; - })) + if (auto EC = Allocator.allocate(LocalAllocAddr, Size, Align)) return EC; + DEBUG(dbgs() << " Allocator " << Id << " reserved " << LocalAllocAddr + << " (" << Size << " bytes, alignment " << Align << ")\n"); + TargetAddress AllocAddr = static_cast(reinterpret_cast(LocalAllocAddr)); return call(Channel, AllocAddr); } - std::error_code handleSetProtections() { - return handle(Channel, [&](ResourceIdMgr::ResourceId Id, - TargetAddress Addr, uint32_t Flags) { - auto I = Allocators.find(Id); - if (I == Allocators.end()) - return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); - auto &Allocator = I->second; - void *LocalAddr = reinterpret_cast(static_cast(Addr)); - DEBUG(dbgs() << " Allocator " << Id << " set permissions on " - << LocalAddr << " to " - << (Flags & sys::Memory::MF_READ ? 'R' : '-') - << (Flags & sys::Memory::MF_WRITE ? 'W' : '-') - << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n"); - return Allocator.setProtections(LocalAddr, Flags); - }); + std::error_code handleSetProtections(ResourceIdMgr::ResourceId Id, + TargetAddress Addr, uint32_t Flags) { + auto I = Allocators.find(Id); + if (I == Allocators.end()) + return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); + auto &Allocator = I->second; + void *LocalAddr = reinterpret_cast(static_cast(Addr)); + DEBUG(dbgs() << " Allocator " << Id << " set permissions on " << LocalAddr + << " to " << (Flags & sys::Memory::MF_READ ? 'R' : '-') + << (Flags & sys::Memory::MF_WRITE ? 'W' : '-') + << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n"); + return Allocator.setProtections(LocalAddr, Flags); } - std::error_code handleWriteMem() { - return handle(Channel, [&](TargetAddress RDst, uint64_t Size) { - char *Dst = reinterpret_cast(static_cast(RDst)); - return Channel.readBytes(Dst, Size); - }); + std::error_code handleWriteMem(TargetAddress RDst, uint64_t Size) { + char *Dst = reinterpret_cast(static_cast(RDst)); + return Channel.readBytes(Dst, Size); } - std::error_code handleWritePtr() { - return handle( - Channel, [&](TargetAddress Addr, TargetAddress PtrVal) { - uintptr_t *Ptr = - reinterpret_cast(static_cast(Addr)); - *Ptr = static_cast(PtrVal); - return std::error_code(); - }); + std::error_code handleWritePtr(TargetAddress Addr, TargetAddress PtrVal) { + uintptr_t *Ptr = + reinterpret_cast(static_cast(Addr)); + *Ptr = static_cast(PtrVal); + return std::error_code(); } ChannelT &Channel; diff --git a/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/include/llvm/ExecutionEngine/Orc/RPCUtils.h index a2f0edb7334..0bd5cbc0cdd 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCUtils.h +++ b/include/llvm/ExecutionEngine/Orc/RPCUtils.h @@ -69,6 +69,20 @@ protected: } }; + template class MemberFnWrapper { + public: + typedef std::error_code (ClassT::*MethodT)(ArgTs...); + MemberFnWrapper(ClassT &Instance, MethodT Method) + : Instance(Instance), Method(Method) {} + std::error_code operator()(ArgTs &... Args) { + return (Instance.*Method)(Args...); + } + + private: + ClassT &Instance; + MethodT Method; + }; + template class ReadArgs { public: std::error_code operator()() { return std::error_code(); } @@ -193,6 +207,15 @@ public: return HandlerHelper::handle(C, Handler); } + /// Helper version of 'handle' for calling member functions. + template + static std::error_code + handle(ChannelT &C, ClassT &Instance, + std::error_code (ClassT::*HandlerMethod)(ArgTs...)) { + return handle( + C, MemberFnWrapper(Instance, HandlerMethod)); + } + /// Deserialize a ProcedureIdT from C and verify it matches the id for Proc. /// If the id does match, deserialize the arguments and call the handler /// (similarly to handle). @@ -208,6 +231,15 @@ public: return handle(C, Handler); } + /// Helper version of expect for calling member functions. + template + static std::error_code + expect(ChannelT &C, ClassT &Instance, + std::error_code (ClassT::*HandlerMethod)(ArgTs...)) { + return expect( + C, MemberFnWrapper(Instance, HandlerMethod)); + } + /// Helper for handling setter procedures - this method returns a functor that /// sets the variables referred to by Args... to values deserialized from the /// channel.