LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine/Orc - RemoteObjectLayer.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 119 160 74.4 %
Date: 2017-09-14 15:23:50 Functions: 21 28 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===------ RemoteObjectLayer.h - Forwards objs to a remote -----*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // Forwards objects to a remote object layer via RPC.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
      15             : #define LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
      16             : 
      17             : #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
      18             : #include "llvm/Object/ObjectFile.h"
      19             : #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
      20             : #include <map>
      21             : 
      22             : namespace llvm {
      23             : namespace orc {
      24             : 
      25             : /// RPC API needed by RemoteObjectClientLayer and RemoteObjectServerLayer.
      26             : class RemoteObjectLayerAPI {
      27             : public:
      28             : 
      29             :   using ObjHandleT = remote::ResourceIdMgr::ResourceId;
      30             : 
      31             : protected:
      32             : 
      33             :   using RemoteSymbolId = remote::ResourceIdMgr::ResourceId;
      34             :   using RemoteSymbol = std::pair<RemoteSymbolId, JITSymbolFlags>;
      35             : 
      36             : public:
      37             : 
      38             :   using BadSymbolHandleError = remote::ResourceNotFound<RemoteSymbolId>;
      39             :   using BadObjectHandleError = remote::ResourceNotFound<ObjHandleT>;
      40             : 
      41             : protected:
      42             : 
      43             :   static const ObjHandleT InvalidObjectHandleId = 0;
      44             :   static const RemoteSymbolId NullSymbolId = 0;
      45             : 
      46             :   class AddObject
      47             :     : public rpc::Function<AddObject, Expected<ObjHandleT>(std::string)> {
      48             :   public:
      49             :     static const char *getName() { return "AddObject"; }
      50             :   };
      51             : 
      52             :   class RemoveObject
      53             :     : public rpc::Function<RemoveObject, Error(ObjHandleT)> {
      54             :   public:
      55             :     static const char *getName() { return "RemoveObject"; }
      56             :   };
      57             : 
      58             :   class FindSymbol
      59             :     : public rpc::Function<FindSymbol, Expected<RemoteSymbol>(std::string,
      60             :                                                               bool)> {
      61             :   public:
      62             :     static const char *getName() { return "FindSymbol"; }
      63             :   };
      64             : 
      65             :   class FindSymbolIn
      66             :     : public rpc::Function<FindSymbolIn,
      67             :                            Expected<RemoteSymbol>(ObjHandleT, std::string,
      68             :                                                   bool)> {
      69             :   public:
      70             :     static const char *getName() { return "FindSymbolIn"; }
      71             :   };
      72             : 
      73             :   class EmitAndFinalize
      74             :     : public rpc::Function<EmitAndFinalize,
      75             :                            Error(ObjHandleT)> {
      76             :   public:
      77             :     static const char *getName() { return "EmitAndFinalize"; }
      78             :   };
      79             : 
      80             :   class Lookup
      81             :     : public rpc::Function<Lookup,
      82             :                            Expected<RemoteSymbol>(ObjHandleT, std::string)> {
      83             :   public:
      84             :     static const char *getName() { return "Lookup"; }
      85             :   };
      86             : 
      87             :   class LookupInLogicalDylib
      88             :     : public rpc::Function<LookupInLogicalDylib,
      89             :                            Expected<RemoteSymbol>(ObjHandleT, std::string)> {
      90             :   public:
      91             :     static const char *getName() { return "LookupInLogicalDylib"; }
      92             :   };
      93             : 
      94             :   class ReleaseRemoteSymbol
      95             :     : public rpc::Function<ReleaseRemoteSymbol, Error(RemoteSymbolId)> {
      96             :   public:
      97             :     static const char *getName() { return "ReleaseRemoteSymbol"; }
      98             :   };
      99             : 
     100             :   class MaterializeRemoteSymbol
     101             :     : public rpc::Function<MaterializeRemoteSymbol,
     102             :                            Expected<JITTargetAddress>(RemoteSymbolId)> {
     103             :   public:
     104             :     static const char *getName() { return "MaterializeRemoteSymbol"; }
     105             :   };
     106             : };
     107             : 
     108             : /// Base class containing common utilities for RemoteObjectClientLayer and
     109             : /// RemoteObjectServerLayer.
     110             : template <typename RPCEndpoint>
     111          64 : class RemoteObjectLayer : public RemoteObjectLayerAPI {
     112             : public:
     113             : 
     114          16 :   RemoteObjectLayer(RPCEndpoint &Remote,
     115             :                     std::function<void(Error)> ReportError)
     116          16 :       : Remote(Remote), ReportError(std::move(ReportError)),
     117          64 :         SymbolIdMgr(NullSymbolId + 1) {
     118             :     using ThisT = RemoteObjectLayer<RPCEndpoint>;
     119          32 :     Remote.template addHandler<ReleaseRemoteSymbol>(
     120             :              *this, &ThisT::handleReleaseRemoteSymbol);
     121          32 :     Remote.template addHandler<MaterializeRemoteSymbol>(
     122             :              *this, &ThisT::handleMaterializeRemoteSymbol);
     123          16 :   }
     124             : 
     125             : protected:
     126             : 
     127             :   /// This class is used as the symbol materializer for JITSymbols returned by
     128             :   /// RemoteObjectLayerClient/RemoteObjectLayerServer -- the materializer knows
     129             :   /// how to call back to the other RPC endpoint to get the address when
     130             :   /// requested.
     131             :   class RemoteSymbolMaterializer {
     132             :   public:
     133             : 
     134             :     /// Construct a RemoteSymbolMaterializer for the given RemoteObjectLayer
     135             :     /// with the given Id.
     136             :     RemoteSymbolMaterializer(RemoteObjectLayer &C,
     137             :                              RemoteSymbolId Id)
     138           2 :       : C(C), Id(Id) {}
     139             : 
     140           2 :     RemoteSymbolMaterializer(const RemoteSymbolMaterializer &Other)
     141           2 :       : C(Other.C), Id(Other.Id) {
     142             :       // FIXME: This is a horrible, auto_ptr-style, copy-as-move operation.
     143             :       //        It should be removed as soon as LLVM has C++14's generalized
     144             :       //        lambda capture (at which point the materializer can be moved
     145             :       //        into the lambda in remoteToJITSymbol below).
     146           2 :       const_cast<RemoteSymbolMaterializer&>(Other).Id = 0;
     147             :     }
     148             : 
     149             :     RemoteSymbolMaterializer&
     150             :     operator=(const RemoteSymbolMaterializer&) = delete;
     151             : 
     152             :     /// Release the remote symbol.
     153             :     ~RemoteSymbolMaterializer() {
     154           2 :       if (Id)
     155           0 :         C.releaseRemoteSymbol(Id);
     156             :     }
     157             : 
     158             :     /// Materialize the symbol on the remote and get its address.
     159             :     Expected<JITTargetAddress> materialize() {
     160           4 :       auto Addr = C.materializeRemoteSymbol(Id);
     161           2 :       Id = 0;
     162             :       return Addr;
     163             :     }
     164             : 
     165             :   private:
     166             :     RemoteObjectLayer &C;
     167             :     RemoteSymbolId Id;
     168             :   };
     169             : 
     170             :   /// Convenience function for getting a null remote symbol value.
     171             :   RemoteSymbol nullRemoteSymbol() {
     172           8 :     return RemoteSymbol(0, JITSymbolFlags());
     173             :   }
     174             : 
     175             :   /// Creates a StringError that contains a copy of Err's log message, then
     176             :   /// sends that StringError to ReportError.
     177             :   ///
     178             :   /// This allows us to locally log error messages for errors that will actually
     179             :   /// be delivered to the remote.
     180           5 :   Error teeLog(Error Err) {
     181           5 :     return handleErrors(std::move(Err),
     182           5 :                         [this](std::unique_ptr<ErrorInfoBase> EIB) {
     183          30 :                           ReportError(make_error<StringError>(
     184           5 :                                         EIB->message(),
     185          10 :                                         EIB->convertToErrorCode()));
     186          20 :                           return Error(std::move(EIB));
     187          15 :                         });
     188             :   }
     189             : 
     190             :   Error badRemoteSymbolIdError(RemoteSymbolId Id) {
     191           0 :     return make_error<BadSymbolHandleError>(Id, "Remote JIT Symbol");
     192             :   }
     193             : 
     194             :   Error badObjectHandleError(ObjHandleT H) {
     195             :     return make_error<RemoteObjectLayerAPI::BadObjectHandleError>(
     196           0 :              H, "Bad object handle");
     197             :   }
     198             : 
     199             :   /// Create a RemoteSymbol wrapping the given JITSymbol.
     200           2 :   Expected<RemoteSymbol> jitSymbolToRemote(JITSymbol Sym) {
     201             :     if (Sym) {
     202           4 :       auto Id = SymbolIdMgr.getNext();
     203           2 :       auto Flags = Sym.getFlags();
     204             :       assert(!InUseSymbols.count(Id) && "Symbol id already in use");
     205           8 :       InUseSymbols.insert(std::make_pair(Id, std::move(Sym)));
     206           4 :       return RemoteSymbol(Id, Flags);
     207           0 :     } else if (auto Err = Sym.takeError())
     208           0 :       return teeLog(std::move(Err));
     209             :     // else...
     210           0 :     return nullRemoteSymbol();
     211             :   }
     212             : 
     213             :   /// Convert an Expected<RemoteSymbol> to a JITSymbol.
     214           5 :   JITSymbol remoteToJITSymbol(Expected<RemoteSymbol> RemoteSymOrErr) {
     215           5 :     if (RemoteSymOrErr) {
     216           3 :       auto &RemoteSym = *RemoteSymOrErr;
     217           8 :       if (RemoteSym == nullRemoteSymbol())
     218             :         return nullptr;
     219             :       // else...
     220           4 :       RemoteSymbolMaterializer RSM(*this, RemoteSym.first);
     221          10 :       auto Sym =
     222          14 :         JITSymbol([RSM]() mutable { return RSM.materialize(); },
     223             :                   RemoteSym.second);
     224           2 :       return Sym;
     225             :     } else
     226           6 :       return RemoteSymOrErr.takeError();
     227             :   }
     228             : 
     229             :   RPCEndpoint &Remote;
     230             :   std::function<void(Error)> ReportError;
     231             : 
     232             : private:
     233             : 
     234             :   /// Notify the remote to release the given JITSymbol.
     235           0 :   void releaseRemoteSymbol(RemoteSymbolId Id) {
     236           0 :     if (auto Err = Remote.template callB<ReleaseRemoteSymbol>(Id))
     237           0 :       ReportError(std::move(Err));
     238           0 :   }
     239             : 
     240             :   /// Notify the remote to materialize the JITSymbol with the given Id and
     241             :   /// return its address.
     242             :   Expected<JITTargetAddress> materializeRemoteSymbol(RemoteSymbolId Id) {
     243           2 :     return Remote.template callB<MaterializeRemoteSymbol>(Id);
     244             :   }
     245             : 
     246             :   /// Release the JITSymbol with the given Id.
     247           0 :   Error handleReleaseRemoteSymbol(RemoteSymbolId Id) {
     248           0 :     auto SI = InUseSymbols.find(Id);
     249           0 :     if (SI != InUseSymbols.end()) {
     250           0 :       InUseSymbols.erase(SI);
     251           0 :       return Error::success();
     252             :     } else
     253           0 :       return teeLog(badRemoteSymbolIdError(Id));
     254             :   }
     255             : 
     256             :   /// Run the materializer for the JITSymbol with the given Id and return its
     257             :   /// address.
     258           2 :   Expected<JITTargetAddress> handleMaterializeRemoteSymbol(RemoteSymbolId Id) {
     259           4 :     auto SI = InUseSymbols.find(Id);
     260           4 :     if (SI != InUseSymbols.end()) {
     261           4 :       auto AddrOrErr = SI->second.getAddress();
     262           4 :       InUseSymbols.erase(SI);
     263           4 :       SymbolIdMgr.release(Id);
     264           2 :       if (AddrOrErr)
     265           2 :         return *AddrOrErr;
     266             :       else
     267           0 :         return teeLog(AddrOrErr.takeError());
     268             :     } else {
     269           0 :       return teeLog(badRemoteSymbolIdError(Id));
     270             :     }
     271             :   }
     272             : 
     273             :   remote::ResourceIdMgr SymbolIdMgr;
     274             :   std::map<RemoteSymbolId, JITSymbol> InUseSymbols;
     275             : };
     276             : 
     277             : /// RemoteObjectClientLayer forwards the ORC Object Layer API over an RPC
     278             : /// connection.
     279             : ///
     280             : /// This class can be used as the base layer of a JIT stack on the client and
     281             : /// will forward operations to a corresponding RemoteObjectServerLayer on the
     282             : /// server (which can be composed on top of a "real" object layer like
     283             : /// RTDyldObjectLinkingLayer to actually carry out the operations).
     284             : ///
     285             : /// Sending relocatable objects to the server (rather than fully relocated
     286             : /// bits) allows JIT'd code to be cached on the server side and re-used in
     287             : /// subsequent JIT sessions.
     288             : template <typename RPCEndpoint>
     289          16 : class RemoteObjectClientLayer : public RemoteObjectLayer<RPCEndpoint> {
     290             : private:
     291             : 
     292             :   using AddObject = RemoteObjectLayerAPI::AddObject;
     293             :   using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
     294             :   using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
     295             :   using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
     296             :   using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
     297             :   using Lookup = RemoteObjectLayerAPI::Lookup;
     298             :   using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
     299             : 
     300             :   using RemoteObjectLayer<RPCEndpoint>::teeLog;
     301             :   using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
     302             :   using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
     303             : 
     304             : public:
     305             : 
     306             :   using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
     307             :   using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
     308             : 
     309             :   using ObjectPtr =
     310             :     std::shared_ptr<object::OwningBinary<object::ObjectFile>>;
     311             : 
     312             :   /// Create a RemoteObjectClientLayer that communicates with a
     313             :   /// RemoteObjectServerLayer instance via the given RPCEndpoint.
     314             :   ///
     315             :   /// The ReportError functor can be used locally log errors that are intended
     316             :   /// to be sent  sent
     317           8 :   RemoteObjectClientLayer(RPCEndpoint &Remote,
     318             :                           std::function<void(Error)> ReportError)
     319          32 :       : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {
     320             :     using ThisT = RemoteObjectClientLayer<RPCEndpoint>;
     321          16 :     Remote.template addHandler<Lookup>(*this, &ThisT::lookup);
     322          16 :     Remote.template addHandler<LookupInLogicalDylib>(
     323             :             *this, &ThisT::lookupInLogicalDylib);
     324           8 :   }
     325             : 
     326             :   /// @brief Add an object to the JIT.
     327             :   ///
     328             :   /// @return A handle that can be used to refer to the loaded object (for
     329             :   ///         symbol searching, finalization, freeing memory, etc.).
     330             :   Expected<ObjHandleT>
     331           8 :   addObject(ObjectPtr Object, std::shared_ptr<JITSymbolResolver> Resolver) {
     332          16 :     StringRef ObjBuffer = Object->getBinary()->getData();
     333          24 :     if (auto HandleOrErr =
     334           8 :           this->Remote.template callB<AddObject>(ObjBuffer)) {
     335           7 :       auto &Handle = *HandleOrErr;
     336             :       // FIXME: Return an error for this:
     337             :       assert(!Resolvers.count(Handle) && "Handle already in use?");
     338          14 :       Resolvers[Handle] = std::move(Resolver);
     339             :       return Handle;
     340             :     } else
     341           3 :       return HandleOrErr.takeError();
     342             :   }
     343             : 
     344             :   /// @brief Remove the given object from the JIT.
     345             :   Error removeObject(ObjHandleT H) {
     346           2 :     return this->Remote.template callB<RemoveObject>(H);
     347             :   }
     348             : 
     349             :   /// @brief Search for the given named symbol.
     350           3 :   JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
     351             :     return remoteToJITSymbol(
     352           3 :              this->Remote.template callB<FindSymbol>(Name,
     353           9 :                                                      ExportedSymbolsOnly));
     354             :   }
     355             : 
     356             :   /// @brief Search for the given named symbol within the given context.
     357           2 :   JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) {
     358             :     return remoteToJITSymbol(
     359           2 :              this->Remote.template callB<FindSymbolIn>(H, Name,
     360           6 :                                                        ExportedSymbolsOnly));
     361             :   }
     362             : 
     363             :   /// @brief Immediately emit and finalize the object with the given handle.
     364             :   Error emitAndFinalize(ObjHandleT H) {
     365           2 :     return this->Remote.template callB<EmitAndFinalize>(H);
     366             :   }
     367             : 
     368             : private:
     369             : 
     370           0 :   Expected<RemoteSymbol> lookup(ObjHandleT H, const std::string &Name) {
     371           0 :     auto RI = Resolvers.find(H);
     372           0 :     if (RI != Resolvers.end()) {
     373           0 :       return this->jitSymbolToRemote(RI->second->findSymbol(Name));
     374             :     } else
     375           0 :       return teeLog(badObjectHandleError(H));
     376             :   }
     377             : 
     378           0 :   Expected<RemoteSymbol> lookupInLogicalDylib(ObjHandleT H,
     379             :                                               const std::string &Name) {
     380           0 :     auto RI = Resolvers.find(H);
     381           0 :     if (RI != Resolvers.end())
     382             :       return this->jitSymbolToRemote(
     383           0 :                RI->second->findSymbolInLogicalDylib(Name));
     384             :     else
     385           0 :       return teeLog(badObjectHandleError(H));
     386             :   }
     387             : 
     388             :   std::map<remote::ResourceIdMgr::ResourceId,
     389             :            std::shared_ptr<JITSymbolResolver>> Resolvers;
     390             : };
     391             : 
     392             : /// RemoteObjectServerLayer acts as a server and handling RPC calls for the
     393             : /// object layer API from the given RPC connection.
     394             : ///
     395             : /// This class can be composed on top of a 'real' object layer (e.g.
     396             : /// RTDyldObjectLinkingLayer) to do the actual work of relocating objects
     397             : /// and making them executable.
     398             : template <typename BaseLayerT, typename RPCEndpoint>
     399          24 : class RemoteObjectServerLayer : public RemoteObjectLayer<RPCEndpoint> {
     400             : private:
     401             : 
     402             :   using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
     403             :   using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
     404             : 
     405             :   using AddObject = RemoteObjectLayerAPI::AddObject;
     406             :   using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
     407             :   using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
     408             :   using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
     409             :   using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
     410             :   using Lookup = RemoteObjectLayerAPI::Lookup;
     411             :   using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
     412             : 
     413             :   using RemoteObjectLayer<RPCEndpoint>::teeLog;
     414             :   using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
     415             :   using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
     416             : 
     417             : public:
     418             : 
     419             :   /// Create a RemoteObjectServerLayer with the given base layer (which must be
     420             :   /// an object layer), RPC endpoint, and error reporter function.
     421           8 :   RemoteObjectServerLayer(BaseLayerT &BaseLayer,
     422             :                           RPCEndpoint &Remote,
     423             :                           std::function<void(Error)> ReportError)
     424           8 :     : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),
     425          40 :       BaseLayer(BaseLayer), HandleIdMgr(1) {
     426             :     using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;
     427             : 
     428          16 :     Remote.template addHandler<AddObject>(*this, &ThisT::addObject);
     429          16 :     Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);
     430          16 :     Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);
     431          16 :     Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);
     432          16 :     Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);
     433           8 :   }
     434             : 
     435             : private:
     436             : 
     437          24 :   class StringMemoryBuffer : public MemoryBuffer {
     438             :   public:
     439           8 :     StringMemoryBuffer(std::string Buffer)
     440          16 :       : Buffer(std::move(Buffer)) {
     441          24 :       init(this->Buffer.data(), this->Buffer.data() + this->Buffer.size(),
     442             :            false);
     443           8 :     }
     444             : 
     445           0 :     BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }
     446             :   private:
     447             :     std::string Buffer;
     448             :   };
     449             : 
     450           0 :   JITSymbol lookup(ObjHandleT Id, const std::string &Name) {
     451             :     return remoteToJITSymbol(
     452           0 :              this->Remote.template callB<Lookup>(Id, Name));
     453             :   }
     454             : 
     455           0 :   JITSymbol lookupInLogicalDylib(ObjHandleT Id, const std::string &Name) {
     456             :     return remoteToJITSymbol(
     457           0 :              this->Remote.template callB<LookupInLogicalDylib>(Id, Name));
     458             :   }
     459             : 
     460           8 :   Expected<ObjHandleT> addObject(std::string ObjBuffer) {
     461          16 :     auto Buffer = llvm::make_unique<StringMemoryBuffer>(std::move(ObjBuffer));
     462          32 :     if (auto ObjectOrErr =
     463           8 :           object::ObjectFile::createObjectFile(Buffer->getMemBufferRef())) {
     464          16 :       auto Object =
     465             :         std::make_shared<object::OwningBinary<object::ObjectFile>>(
     466          16 :           std::move(*ObjectOrErr), std::move(Buffer));
     467             : 
     468          16 :       auto Id = HandleIdMgr.getNext();
     469             :       assert(!BaseLayerHandles.count(Id) && "Id already in use?");
     470             : 
     471          16 :       auto Resolver =
     472             :         createLambdaResolver(
     473           0 :           [this, Id](const std::string &Name) { return lookup(Id, Name); },
     474           0 :           [this, Id](const std::string &Name) {
     475             :             return lookupInLogicalDylib(Id, Name);
     476           0 :           });
     477             : 
     478          48 :       if (auto HandleOrErr =
     479          16 :           BaseLayer.addObject(std::move(Object), std::move(Resolver))) {
     480           7 :         BaseLayerHandles[Id] = std::move(*HandleOrErr);
     481             :         return Id;
     482             :       } else
     483           5 :         return teeLog(HandleOrErr.takeError());
     484             :     } else
     485           0 :       return teeLog(ObjectOrErr.takeError());
     486             :   }
     487             : 
     488           2 :   Error removeObject(ObjHandleT H) {
     489           4 :     auto HI = BaseLayerHandles.find(H);
     490           4 :     if (HI != BaseLayerHandles.end()) {
     491           7 :       if (auto Err = BaseLayer.removeObject(HI->second))
     492           3 :         return teeLog(std::move(Err));
     493           3 :       return Error::success();
     494             :     } else
     495           0 :       return teeLog(badObjectHandleError(H));
     496             :   }
     497             : 
     498           3 :   Expected<RemoteSymbol> findSymbol(const std::string &Name,
     499             :                                     bool ExportedSymbolsOnly) {
     500           7 :     if (auto Sym = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
     501           1 :       return this->jitSymbolToRemote(std::move(Sym));
     502           5 :     else if (auto Err = Sym.takeError())
     503           5 :       return teeLog(std::move(Err));
     504           3 :     return this->nullRemoteSymbol();
     505             :   }
     506             : 
     507           2 :   Expected<RemoteSymbol> findSymbolIn(ObjHandleT H, const std::string &Name,
     508             :                                       bool ExportedSymbolsOnly) {
     509           4 :     auto HI = BaseLayerHandles.find(H);
     510           4 :     if (HI != BaseLayerHandles.end()) {
     511           6 :       if (auto Sym = BaseLayer.findSymbolIn(HI->second, Name, ExportedSymbolsOnly))
     512           1 :         return this->jitSymbolToRemote(std::move(Sym));
     513           2 :       else if (auto Err = Sym.takeError())
     514           5 :         return teeLog(std::move(Err));
     515           0 :       return this->nullRemoteSymbol();
     516             :     } else
     517           0 :       return teeLog(badObjectHandleError(H));
     518             :   }
     519             : 
     520           2 :   Error emitAndFinalize(ObjHandleT H) {
     521           4 :     auto HI = BaseLayerHandles.find(H);
     522           4 :     if (HI != BaseLayerHandles.end()) {
     523           7 :       if (auto Err = BaseLayer.emitAndFinalize(HI->second))
     524           3 :         return teeLog(std::move(Err));
     525           3 :       return Error::success();
     526             :     } else
     527           0 :       return teeLog(badObjectHandleError(H));
     528             :   }
     529             : 
     530             :   BaseLayerT &BaseLayer;
     531             :   remote::ResourceIdMgr HandleIdMgr;
     532             :   std::map<ObjHandleT, typename BaseLayerT::ObjHandleT> BaseLayerHandles;
     533             : };
     534             : 
     535             : } // end namespace orc
     536             : } // end namespace llvm
     537             : 
     538             : #endif // LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H

Generated by: LCOV version 1.13