LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine/Orc - RemoteObjectLayer.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 71 116 61.2 %
Date: 2018-10-20 13:21:21 Functions: 16 30 53.3 %
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             : class RemoteObjectLayer : public RemoteObjectLayerAPI {
     112             : public:
     113             : 
     114          16 :   RemoteObjectLayer(RPCEndpoint &Remote,
     115             :                     std::function<void(Error)> ReportError)
     116             :       : Remote(Remote), ReportError(std::move(ReportError)),
     117          16 :         SymbolIdMgr(NullSymbolId + 1) {
     118             :     using ThisT = RemoteObjectLayer<RPCEndpoint>;
     119             :     Remote.template addHandler<ReleaseRemoteSymbol>(
     120             :              *this, &ThisT::handleReleaseRemoteSymbol);
     121             :     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             :       : 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           0 :       const_cast<RemoteSymbolMaterializer&>(Other).Id = 0;
     147             :     }
     148             : 
     149             :     RemoteSymbolMaterializer&
     150             :     operator=(const RemoteSymbolMaterializer&) = delete;
     151             : 
     152             :     /// Release the remote symbol.
     153             :     ~RemoteSymbolMaterializer() {
     154           0 :       if (Id)
     155           0 :         C.releaseRemoteSymbol(Id);
     156             :     }
     157             : 
     158             :     /// Materialize the symbol on the remote and get its address.
     159           0 :     Expected<JITTargetAddress> materialize() {
     160           4 :       auto Addr = C.materializeRemoteSymbol(Id);
     161           2 :       Id = 0;
     162           0 :       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           0 :   RemoteSymbol nullRemoteSymbol() {
     172           0 :     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             :     return handleErrors(std::move(Err),
     182             :                         [this](std::unique_ptr<ErrorInfoBase> EIB) {
     183             :                           ReportError(make_error<StringError>(
     184             :                                         EIB->message(),
     185             :                                         EIB->convertToErrorCode()));
     186             :                           return Error(std::move(EIB));
     187          10 :                         });
     188             :   }
     189             : 
     190           0 :   Error badRemoteSymbolIdError(RemoteSymbolId Id) {
     191           0 :     return make_error<BadSymbolHandleError>(Id, "Remote JIT Symbol");
     192             :   }
     193             : 
     194           0 :   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             :       auto Id = SymbolIdMgr.getNext();
     203             :       auto Flags = Sym.getFlags();
     204             :       assert(!InUseSymbols.count(Id) && "Symbol id already in use");
     205           2 :       InUseSymbols.insert(std::make_pair(Id, std::move(Sym)));
     206             :       return RemoteSymbol(Id, Flags);
     207           0 :     } else if (auto Err = Sym.takeError())
     208           0 :       return teeLog(std::move(Err));
     209             :     // else...
     210             :     return nullRemoteSymbol();
     211             :   }
     212             : 
     213             :   /// Convert an Expected<RemoteSymbol> to a JITSymbol.
     214           5 :   JITSymbol remoteToJITSymbol(Expected<RemoteSymbol> RemoteSymOrErr) {
     215           5 :     if (RemoteSymOrErr) {
     216             :       auto &RemoteSym = *RemoteSymOrErr;
     217             :       if (RemoteSym == nullRemoteSymbol())
     218             :         return nullptr;
     219             :       // else...
     220             :       RemoteSymbolMaterializer RSM(*this, RemoteSym.first);
     221           2 :       auto Sym =
     222           0 :         JITSymbol([RSM]() mutable { return RSM.materialize(); },
     223             :                   RemoteSym.second);
     224           2 :       return Sym;
     225             :     } else
     226             :       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           0 :   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             :     auto SI = InUseSymbols.find(Id);
     249           0 :     if (SI != InUseSymbols.end()) {
     250             :       InUseSymbols.erase(SI);
     251             :       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             :     auto SI = InUseSymbols.find(Id);
     260           2 :     if (SI != InUseSymbols.end()) {
     261           2 :       auto AddrOrErr = SI->second.getAddress();
     262             :       InUseSymbols.erase(SI);
     263           2 :       SymbolIdMgr.release(Id);
     264           2 :       if (AddrOrErr)
     265             :         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           8 : 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 = std::unique_ptr<MemoryBuffer>;
     310             : 
     311             :   /// Create a RemoteObjectClientLayer that communicates with a
     312             :   /// RemoteObjectServerLayer instance via the given RPCEndpoint.
     313             :   ///
     314             :   /// The ReportError functor can be used locally log errors that are intended
     315             :   /// to be sent  sent
     316           8 :   RemoteObjectClientLayer(RPCEndpoint &Remote,
     317             :                           std::function<void(Error)> ReportError)
     318          24 :       : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {
     319             :     using ThisT = RemoteObjectClientLayer<RPCEndpoint>;
     320             :     Remote.template addHandler<Lookup>(*this, &ThisT::lookup);
     321             :     Remote.template addHandler<LookupInLogicalDylib>(
     322             :             *this, &ThisT::lookupInLogicalDylib);
     323           8 :   }
     324             : 
     325             :   /// Add an object to the JIT.
     326             :   ///
     327             :   /// @return A handle that can be used to refer to the loaded object (for
     328             :   ///         symbol searching, finalization, freeing memory, etc.).
     329             :   Expected<ObjHandleT>
     330           8 :   addObject(ObjectPtr ObjBuffer,
     331             :             std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
     332           8 :     if (auto HandleOrErr =
     333          16 :             this->Remote.template callB<AddObject>(ObjBuffer->getBuffer())) {
     334             :       auto &Handle = *HandleOrErr;
     335             :       // FIXME: Return an error for this:
     336             :       assert(!Resolvers.count(Handle) && "Handle already in use?");
     337           7 :       Resolvers[Handle] = std::move(Resolver);
     338             :       return Handle;
     339             :     } else
     340             :       return HandleOrErr.takeError();
     341             :   }
     342             : 
     343             :   /// Remove the given object from the JIT.
     344           0 :   Error removeObject(ObjHandleT H) {
     345           2 :     return this->Remote.template callB<RemoveObject>(H);
     346             :   }
     347             : 
     348             :   /// Search for the given named symbol.
     349           3 :   JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
     350             :     return remoteToJITSymbol(
     351           3 :              this->Remote.template callB<FindSymbol>(Name,
     352           3 :                                                      ExportedSymbolsOnly));
     353             :   }
     354             : 
     355             :   /// Search for the given named symbol within the given context.
     356           2 :   JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) {
     357             :     return remoteToJITSymbol(
     358           2 :              this->Remote.template callB<FindSymbolIn>(H, Name,
     359           2 :                                                        ExportedSymbolsOnly));
     360             :   }
     361             : 
     362             :   /// Immediately emit and finalize the object with the given handle.
     363           0 :   Error emitAndFinalize(ObjHandleT H) {
     364           2 :     return this->Remote.template callB<EmitAndFinalize>(H);
     365             :   }
     366             : 
     367             : private:
     368             : 
     369           0 :   Expected<RemoteSymbol> lookup(ObjHandleT H, const std::string &Name) {
     370             :     auto RI = Resolvers.find(H);
     371           0 :     if (RI != Resolvers.end()) {
     372           0 :       return this->jitSymbolToRemote(RI->second->findSymbol(Name));
     373             :     } else
     374           0 :       return teeLog(badObjectHandleError(H));
     375             :   }
     376             : 
     377           0 :   Expected<RemoteSymbol> lookupInLogicalDylib(ObjHandleT H,
     378             :                                               const std::string &Name) {
     379             :     auto RI = Resolvers.find(H);
     380           0 :     if (RI != Resolvers.end())
     381             :       return this->jitSymbolToRemote(
     382           0 :                RI->second->findSymbolInLogicalDylib(Name));
     383             :     else
     384           0 :       return teeLog(badObjectHandleError(H));
     385             :   }
     386             : 
     387             :   std::map<remote::ResourceIdMgr::ResourceId,
     388             :            std::shared_ptr<LegacyJITSymbolResolver>>
     389             :       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             : 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             :     : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),
     425          24 :       BaseLayer(BaseLayer), HandleIdMgr(1) {
     426             :     using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;
     427             : 
     428             :     Remote.template addHandler<AddObject>(*this, &ThisT::addObject);
     429             :     Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);
     430             :     Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);
     431             :     Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);
     432             :     Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);
     433           8 :   }
     434             : 
     435             : private:
     436             : 
     437           0 :   class StringMemoryBuffer : public MemoryBuffer {
     438             :   public:
     439           8 :     StringMemoryBuffer(std::string Buffer)
     440           8 :       : Buffer(std::move(Buffer)) {
     441          16 :       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           8 :     auto Id = HandleIdMgr.getNext();
     463             :     assert(!BaseLayerHandles.count(Id) && "Id already in use?");
     464             : 
     465           8 :     auto Resolver = createLambdaResolver(
     466           0 :         [this, Id](const std::string &Name) { return lookup(Id, Name); },
     467             :         [this, Id](const std::string &Name) {
     468           0 :           return lookupInLogicalDylib(Id, Name);
     469             :         });
     470             : 
     471          24 :     if (auto HandleOrErr =
     472           8 :             BaseLayer.addObject(std::move(Buffer), std::move(Resolver))) {
     473           7 :       BaseLayerHandles[Id] = std::move(*HandleOrErr);
     474             :       return Id;
     475             :     } else
     476           2 :       return teeLog(HandleOrErr.takeError());
     477             :   }
     478             : 
     479           2 :   Error removeObject(ObjHandleT H) {
     480             :     auto HI = BaseLayerHandles.find(H);
     481           2 :     if (HI != BaseLayerHandles.end()) {
     482           4 :       if (auto Err = BaseLayer.removeObject(HI->second))
     483           3 :         return teeLog(std::move(Err));
     484             :       return Error::success();
     485             :     } else
     486           0 :       return teeLog(badObjectHandleError(H));
     487             :   }
     488             : 
     489           3 :   Expected<RemoteSymbol> findSymbol(const std::string &Name,
     490             :                                     bool ExportedSymbolsOnly) {
     491           7 :     if (auto Sym = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
     492           1 :       return this->jitSymbolToRemote(std::move(Sym));
     493           2 :     else if (auto Err = Sym.takeError())
     494           2 :       return teeLog(std::move(Err));
     495             :     return this->nullRemoteSymbol();
     496             :   }
     497             : 
     498           2 :   Expected<RemoteSymbol> findSymbolIn(ObjHandleT H, const std::string &Name,
     499             :                                       bool ExportedSymbolsOnly) {
     500             :     auto HI = BaseLayerHandles.find(H);
     501           2 :     if (HI != BaseLayerHandles.end()) {
     502           4 :       if (auto Sym = BaseLayer.findSymbolIn(HI->second, Name, ExportedSymbolsOnly))
     503           1 :         return this->jitSymbolToRemote(std::move(Sym));
     504           1 :       else if (auto Err = Sym.takeError())
     505           2 :         return teeLog(std::move(Err));
     506             :       return this->nullRemoteSymbol();
     507             :     } else
     508           0 :       return teeLog(badObjectHandleError(H));
     509             :   }
     510             : 
     511           2 :   Error emitAndFinalize(ObjHandleT H) {
     512             :     auto HI = BaseLayerHandles.find(H);
     513           2 :     if (HI != BaseLayerHandles.end()) {
     514           4 :       if (auto Err = BaseLayer.emitAndFinalize(HI->second))
     515           3 :         return teeLog(std::move(Err));
     516             :       return Error::success();
     517             :     } else
     518           0 :       return teeLog(badObjectHandleError(H));
     519             :   }
     520             : 
     521             :   BaseLayerT &BaseLayer;
     522             :   remote::ResourceIdMgr HandleIdMgr;
     523             :   std::map<ObjHandleT, typename BaseLayerT::ObjHandleT> BaseLayerHandles;
     524             : };
     525             : 
     526             : } // end namespace orc
     527             : } // end namespace llvm
     528             : 
     529             : #endif // LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H

Generated by: LCOV version 1.13