LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/Orc - OrcMCJITReplacement.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 128 176 72.7 %
Date: 2018-06-17 00:07:59 Functions: 30 39 76.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- OrcMCJITReplacement.h - Orc based MCJIT replacement ------*- 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             : // Orc based MCJIT replacement.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
      15             : #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
      16             : 
      17             : #include "llvm/ADT/ArrayRef.h"
      18             : #include "llvm/ADT/STLExtras.h"
      19             : #include "llvm/ADT/StringRef.h"
      20             : #include "llvm/ExecutionEngine/ExecutionEngine.h"
      21             : #include "llvm/ExecutionEngine/GenericValue.h"
      22             : #include "llvm/ExecutionEngine/JITSymbol.h"
      23             : #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
      24             : #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
      25             : #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
      26             : #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
      27             : #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
      28             : #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
      29             : #include "llvm/ExecutionEngine/RuntimeDyld.h"
      30             : #include "llvm/IR/DataLayout.h"
      31             : #include "llvm/IR/Function.h"
      32             : #include "llvm/IR/Mangler.h"
      33             : #include "llvm/IR/Module.h"
      34             : #include "llvm/Object/Archive.h"
      35             : #include "llvm/Object/Binary.h"
      36             : #include "llvm/Object/ObjectFile.h"
      37             : #include "llvm/Support/Error.h"
      38             : #include "llvm/Support/ErrorHandling.h"
      39             : #include "llvm/Support/raw_ostream.h"
      40             : #include "llvm/Target/TargetMachine.h"
      41             : #include <algorithm>
      42             : #include <cassert>
      43             : #include <cstddef>
      44             : #include <cstdint>
      45             : #include <map>
      46             : #include <memory>
      47             : #include <set>
      48             : #include <string>
      49             : #include <vector>
      50             : 
      51             : namespace llvm {
      52             : 
      53             : class ObjectCache;
      54             : 
      55             : namespace orc {
      56             : 
      57          44 : class OrcMCJITReplacement : public ExecutionEngine {
      58             : 
      59             :   // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
      60             :   // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
      61             :   // expecting - see finalizeMemory.
      62          22 :   class MCJITReplacementMemMgr : public MCJITMemoryManager {
      63             :   public:
      64             :     MCJITReplacementMemMgr(OrcMCJITReplacement &M,
      65             :                            std::shared_ptr<MCJITMemoryManager> ClientMM)
      66         154 :       : M(M), ClientMM(std::move(ClientMM)) {}
      67             : 
      68          94 :     uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
      69             :                                  unsigned SectionID,
      70             :                                  StringRef SectionName) override {
      71             :       uint8_t *Addr =
      72          94 :           ClientMM->allocateCodeSection(Size, Alignment, SectionID,
      73          94 :                                         SectionName);
      74         188 :       M.SectionsAllocatedSinceLastLoad.insert(Addr);
      75          94 :       return Addr;
      76             :     }
      77             : 
      78         134 :     uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
      79             :                                  unsigned SectionID, StringRef SectionName,
      80             :                                  bool IsReadOnly) override {
      81         268 :       uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
      82         268 :                                                     SectionName, IsReadOnly);
      83         268 :       M.SectionsAllocatedSinceLastLoad.insert(Addr);
      84         134 :       return Addr;
      85             :     }
      86             : 
      87          14 :     void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
      88             :                                 uintptr_t RODataSize, uint32_t RODataAlign,
      89             :                                 uintptr_t RWDataSize,
      90             :                                 uint32_t RWDataAlign) override {
      91          28 :       return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign,
      92             :                                               RODataSize, RODataAlign,
      93          28 :                                               RWDataSize, RWDataAlign);
      94             :     }
      95             : 
      96          93 :     bool needsToReserveAllocationSpace() override {
      97          93 :       return ClientMM->needsToReserveAllocationSpace();
      98             :     }
      99             : 
     100          73 :     void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
     101             :                           size_t Size) override {
     102          73 :       return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
     103             :     }
     104             : 
     105          14 :     void deregisterEHFrames() override {
     106          14 :       return ClientMM->deregisterEHFrames();
     107             :     }
     108             : 
     109          93 :     void notifyObjectLoaded(RuntimeDyld &RTDyld,
     110             :                             const object::ObjectFile &O) override {
     111          93 :       return ClientMM->notifyObjectLoaded(RTDyld, O);
     112             :     }
     113             : 
     114          93 :     void notifyObjectLoaded(ExecutionEngine *EE,
     115             :                             const object::ObjectFile &O) override {
     116          93 :       return ClientMM->notifyObjectLoaded(EE, O);
     117             :     }
     118             : 
     119          76 :     bool finalizeMemory(std::string *ErrMsg = nullptr) override {
     120             :       // Each set of objects loaded will be finalized exactly once, but since
     121             :       // symbol lookup during relocation may recursively trigger the
     122             :       // loading/relocation of other modules, and since we're forwarding all
     123             :       // finalizeMemory calls to a single underlying memory manager, we need to
     124             :       // defer forwarding the call on until all necessary objects have been
     125             :       // loaded. Otherwise, during the relocation of a leaf object, we will end
     126             :       // up finalizing memory, causing a crash further up the stack when we
     127             :       // attempt to apply relocations to finalized memory.
     128             :       // To avoid finalizing too early, look at how many objects have been
     129             :       // loaded but not yet finalized. This is a bit of a hack that relies on
     130             :       // the fact that we're lazily emitting object files: The only way you can
     131             :       // get more than one set of objects loaded but not yet finalized is if
     132             :       // they were loaded during relocation of another set.
     133         152 :       if (M.UnfinalizedSections.size() == 1)
     134          76 :         return ClientMM->finalizeMemory(ErrMsg);
     135             :       return false;
     136             :     }
     137             : 
     138             :   private:
     139             :     OrcMCJITReplacement &M;
     140             :     std::shared_ptr<MCJITMemoryManager> ClientMM;
     141             :   };
     142             : 
     143          11 :   class LinkingORCResolver : public orc::SymbolResolver {
     144             :   public:
     145          77 :     LinkingORCResolver(OrcMCJITReplacement &M) : M(M) {}
     146             : 
     147          93 :     SymbolNameSet lookupFlags(SymbolFlagsMap &SymbolFlags,
     148             :                               const SymbolNameSet &Symbols) override {
     149             :       SymbolNameSet UnresolvedSymbols;
     150             : 
     151         112 :       for (auto &S : Symbols) {
     152          57 :         if (auto Sym = M.findMangledSymbol(*S)) {
     153           3 :           SymbolFlags[S] = Sym.getFlags();
     154          16 :         } else if (auto Err = Sym.takeError()) {
     155           0 :           M.reportError(std::move(Err));
     156           0 :           return SymbolNameSet();
     157             :         } else {
     158          80 :           if (auto Sym2 = M.ClientResolver->findSymbolInLogicalDylib(*S)) {
     159           0 :             SymbolFlags[S] = Sym2.getFlags();
     160          16 :           } else if (auto Err = Sym2.takeError()) {
     161           0 :             M.reportError(std::move(Err));
     162           0 :             return SymbolNameSet();
     163             :           } else
     164             :             UnresolvedSymbols.insert(S);
     165             :         }
     166             :       }
     167             : 
     168             :       return UnresolvedSymbols;
     169             :     }
     170             : 
     171          35 :     SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
     172             :                          SymbolNameSet Symbols) override {
     173             :       SymbolNameSet UnresolvedSymbols;
     174             :       bool NewSymbolsResolved = false;
     175             : 
     176          95 :       for (auto &S : Symbols) {
     177         180 :         if (auto Sym = M.findMangledSymbol(*S)) {
     178         120 :           if (auto Addr = Sym.getAddress()) {
     179         120 :             Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
     180          60 :             Query->notifySymbolReady();
     181             :             NewSymbolsResolved = true;
     182             :           } else {
     183           0 :             M.ES.failQuery(*Query, Addr.takeError());
     184           0 :             return SymbolNameSet();
     185             :           }
     186           0 :         } else if (auto Err = Sym.takeError()) {
     187           0 :           M.ES.failQuery(*Query, std::move(Err));
     188           0 :           return SymbolNameSet();
     189             :         } else {
     190           0 :           if (auto Sym2 = M.ClientResolver->findSymbol(*S)) {
     191           0 :             if (auto Addr = Sym2.getAddress()) {
     192           0 :               Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym2.getFlags()));
     193           0 :               Query->notifySymbolReady();
     194             :               NewSymbolsResolved = true;
     195             :             } else {
     196           0 :               M.ES.failQuery(*Query, Addr.takeError());
     197           0 :               return SymbolNameSet();
     198             :             }
     199           0 :           } else if (auto Err = Sym2.takeError()) {
     200           0 :             M.ES.failQuery(*Query, std::move(Err));
     201           0 :             return SymbolNameSet();
     202             :           } else
     203             :             UnresolvedSymbols.insert(S);
     204             :         }
     205             :       }
     206             : 
     207          70 :       if (NewSymbolsResolved && Query->isFullyResolved())
     208          35 :         Query->handleFullyResolved();
     209             : 
     210          70 :       if (NewSymbolsResolved && Query->isFullyReady())
     211          35 :         Query->handleFullyReady();
     212             : 
     213             :       return UnresolvedSymbols;
     214             :     }
     215             : 
     216             :   private:
     217             :     OrcMCJITReplacement &M;
     218             :   };
     219             : 
     220             : private:
     221             :   static ExecutionEngine *
     222          77 :   createOrcMCJITReplacement(std::string *ErrorMsg,
     223             :                             std::shared_ptr<MCJITMemoryManager> MemMgr,
     224             :                             std::shared_ptr<LegacyJITSymbolResolver> Resolver,
     225             :                             std::unique_ptr<TargetMachine> TM) {
     226             :     return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
     227         308 :                                    std::move(TM));
     228             :   }
     229             : 
     230           0 :   void reportError(Error Err) {
     231           0 :     logAllUnhandledErrors(std::move(Err), errs(), "MCJIT error: ");
     232           0 :   }
     233             : 
     234             : public:
     235          77 :   OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr,
     236             :                       std::shared_ptr<LegacyJITSymbolResolver> ClientResolver,
     237             :                       std::unique_ptr<TargetMachine> TM)
     238         154 :       : ExecutionEngine(TM->createDataLayout()),
     239             :         TM(std::move(TM)),
     240             :         MemMgr(
     241             :             std::make_shared<MCJITReplacementMemMgr>(*this, std::move(MemMgr))),
     242             :         Resolver(std::make_shared<LinkingORCResolver>(*this)),
     243             :         ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
     244             :         NotifyFinalized(*this),
     245             :         ObjectLayer(
     246             :             ES,
     247         186 :             [this](VModuleKey K) {
     248             :               return ObjectLayerT::Resources{this->MemMgr, this->Resolver};
     249             :             },
     250             :             NotifyObjectLoaded, NotifyFinalized),
     251             :         CompileLayer(ObjectLayer, SimpleCompiler(*this->TM),
     252          89 :                      [this](VModuleKey K, std::unique_ptr<Module> M) {
     253          89 :                        Modules.push_back(std::move(M));
     254             :                      }),
     255        1001 :         LazyEmitLayer(CompileLayer) {}
     256             : 
     257             :   static void Register() {
     258      101169 :     OrcMCJITReplacementCtor = createOrcMCJITReplacement;
     259             :   }
     260             : 
     261          90 :   void addModule(std::unique_ptr<Module> M) override {
     262             :     // If this module doesn't have a DataLayout attached then attach the
     263             :     // default.
     264         180 :     if (M->getDataLayout().isDefault()) {
     265          90 :       M->setDataLayout(getDataLayout());
     266             :     } else {
     267             :       assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
     268             :     }
     269             : 
     270             :     // Rename, bump linkage and record static constructors and destructors.
     271             :     // We have to do this before we hand over ownership of the module to the
     272             :     // JIT.
     273          90 :     std::vector<std::string> CtorNames, DtorNames;
     274             :     {
     275             :       unsigned CtorId = 0, DtorId = 0;
     276          91 :       for (auto Ctor : orc::getConstructors(*M)) {
     277           2 :         std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str();
     278           2 :         Ctor.Func->setName(NewCtorName);
     279             :         Ctor.Func->setLinkage(GlobalValue::ExternalLinkage);
     280             :         Ctor.Func->setVisibility(GlobalValue::HiddenVisibility);
     281           2 :         CtorNames.push_back(mangle(NewCtorName));
     282             :       }
     283          91 :       for (auto Dtor : orc::getDestructors(*M)) {
     284           2 :         std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str();
     285           2 :         dbgs() << "Found dtor: " << NewDtorName << "\n";
     286           2 :         Dtor.Func->setName(NewDtorName);
     287             :         Dtor.Func->setLinkage(GlobalValue::ExternalLinkage);
     288             :         Dtor.Func->setVisibility(GlobalValue::HiddenVisibility);
     289           2 :         DtorNames.push_back(mangle(NewDtorName));
     290             :       }
     291             :     }
     292             : 
     293          90 :     auto K = ES.allocateVModule();
     294             : 
     295          90 :     UnexecutedConstructors[K] = std::move(CtorNames);
     296          90 :     UnexecutedDestructors[K] = std::move(DtorNames);
     297             : 
     298         270 :     cantFail(LazyEmitLayer.addModule(K, std::move(M)));
     299          90 :   }
     300             : 
     301           0 :   void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
     302           0 :     cantFail(ObjectLayer.addObject(
     303           0 :         ES.allocateVModule(), MemoryBuffer::getMemBufferCopy(O->getData())));
     304           0 :   }
     305             : 
     306           2 :   void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
     307           2 :     std::unique_ptr<object::ObjectFile> Obj;
     308           2 :     std::unique_ptr<MemoryBuffer> ObjBuffer;
     309           2 :     std::tie(Obj, ObjBuffer) = O.takeBinary();
     310           8 :     cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(ObjBuffer)));
     311           2 :   }
     312             : 
     313           1 :   void addArchive(object::OwningBinary<object::Archive> A) override {
     314           1 :     Archives.push_back(std::move(A));
     315           1 :   }
     316             : 
     317           0 :   bool removeModule(Module *M) override {
     318             :     auto I = Modules.begin();
     319           0 :     for (auto E = Modules.end(); I != E; ++I)
     320           0 :       if (I->get() == M)
     321             :         break;
     322           0 :     if (I == Modules.end())
     323             :       return false;
     324           0 :     Modules.erase(I);
     325           0 :     return true;
     326             :   }
     327             : 
     328         205 :   uint64_t getSymbolAddress(StringRef Name) {
     329         410 :     return cantFail(findSymbol(Name).getAddress());
     330             :   }
     331             : 
     332         205 :   JITSymbol findSymbol(StringRef Name) {
     333         615 :     return findMangledSymbol(mangle(Name));
     334             :   }
     335             : 
     336          76 :   void finalizeObject() override {
     337             :     // This is deprecated - Aim to remove in ExecutionEngine.
     338             :     // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
     339          76 :   }
     340             : 
     341           0 :   void mapSectionAddress(const void *LocalAddress,
     342             :                          uint64_t TargetAddress) override {
     343           0 :     for (auto &P : UnfinalizedSections)
     344             :       if (P.second.count(LocalAddress))
     345           0 :         ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
     346           0 :   }
     347             : 
     348           0 :   uint64_t getGlobalValueAddress(const std::string &Name) override {
     349           0 :     return getSymbolAddress(Name);
     350             :   }
     351             : 
     352          11 :   uint64_t getFunctionAddress(const std::string &Name) override {
     353          11 :     return getSymbolAddress(Name);
     354             :   }
     355             : 
     356         194 :   void *getPointerToFunction(Function *F) override {
     357         194 :     uint64_t FAddr = getSymbolAddress(F->getName());
     358         194 :     return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
     359             :   }
     360             : 
     361           0 :   void *getPointerToNamedFunction(StringRef Name,
     362             :                                   bool AbortOnFailure = true) override {
     363           0 :     uint64_t Addr = getSymbolAddress(Name);
     364           0 :     if (!Addr && AbortOnFailure)
     365           0 :       llvm_unreachable("Missing symbol!");
     366           0 :     return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
     367             :   }
     368             : 
     369             :   GenericValue runFunction(Function *F,
     370             :                            ArrayRef<GenericValue> ArgValues) override;
     371             : 
     372           1 :   void setObjectCache(ObjectCache *NewCache) override {
     373             :     CompileLayer.getCompiler().setObjectCache(NewCache);
     374           1 :   }
     375             : 
     376           0 :   void setProcessAllSections(bool ProcessAllSections) override {
     377             :     ObjectLayer.setProcessAllSections(ProcessAllSections);
     378           0 :   }
     379             : 
     380             :   void runStaticConstructorsDestructors(bool isDtors) override;
     381             : 
     382             : private:
     383         284 :   JITSymbol findMangledSymbol(StringRef Name) {
     384         974 :     if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
     385         162 :       return Sym;
     386         384 :     if (auto Sym = ClientResolver->findSymbol(Name))
     387         104 :       return Sym;
     388          34 :     if (auto Sym = scanArchives(Name))
     389           2 :       return Sym;
     390             : 
     391             :     return nullptr;
     392             :   }
     393             : 
     394          18 :   JITSymbol scanArchives(StringRef Name) {
     395          18 :     for (object::OwningBinary<object::Archive> &OB : Archives) {
     396             :       object::Archive *A = OB.getBinary();
     397             :       // Look for our symbols in each Archive
     398           2 :       auto OptionalChildOrErr = A->findSym(Name);
     399           2 :       if (!OptionalChildOrErr)
     400           0 :         report_fatal_error(OptionalChildOrErr.takeError());
     401             :       auto &OptionalChild = *OptionalChildOrErr;
     402           2 :       if (OptionalChild) {
     403             :         // FIXME: Support nested archives?
     404             :         Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
     405           2 :             OptionalChild->getAsBinary();
     406           2 :         if (!ChildBinOrErr) {
     407             :           // TODO: Actually report errors helpfully.
     408           0 :           consumeError(ChildBinOrErr.takeError());
     409           0 :           continue;
     410             :         }
     411             :         std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
     412           4 :         if (ChildBin->isObject()) {
     413           6 :           cantFail(ObjectLayer.addObject(
     414             :               ES.allocateVModule(),
     415           4 :               MemoryBuffer::getMemBufferCopy(ChildBin->getData())));
     416           2 :           if (auto Sym = ObjectLayer.findSymbol(Name, true))
     417           2 :             return Sym;
     418             :         }
     419             :       }
     420             :     }
     421             :     return nullptr;
     422             :   }
     423             : 
     424             :   class NotifyObjectLoadedT {
     425             :   public:
     426             :     using LoadedObjInfoListT =
     427             :         std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>;
     428             : 
     429          77 :     NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
     430             : 
     431          93 :     void operator()(VModuleKey K, const object::ObjectFile &Obj,
     432             :                     const RuntimeDyld::LoadedObjectInfo &Info) const {
     433          93 :       M.UnfinalizedSections[K] = std::move(M.SectionsAllocatedSinceLastLoad);
     434         186 :       M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
     435         186 :       M.MemMgr->notifyObjectLoaded(&M, Obj);
     436          93 :     }
     437             :   private:
     438             :     OrcMCJITReplacement &M;
     439             :   };
     440             : 
     441             :   class NotifyFinalizedT {
     442             :   public:
     443          77 :     NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
     444             : 
     445             :     void operator()(VModuleKey K, const object::ObjectFile &Obj,
     446             :                     const RuntimeDyld::LoadedObjectInfo &Info) {
     447          93 :       M.UnfinalizedSections.erase(K);
     448             :     }
     449             : 
     450             :   private:
     451             :     OrcMCJITReplacement &M;
     452             :   };
     453             : 
     454         207 :   std::string mangle(StringRef Name) {
     455             :     std::string MangledName;
     456             :     {
     457         207 :       raw_string_ostream MangledNameStream(MangledName);
     458         207 :       Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout());
     459             :     }
     460         207 :     return MangledName;
     461             :   }
     462             : 
     463             :   using ObjectLayerT = RTDyldObjectLinkingLayer;
     464             :   using CompileLayerT = IRCompileLayer<ObjectLayerT, orc::SimpleCompiler>;
     465             :   using LazyEmitLayerT = LazyEmittingLayer<CompileLayerT>;
     466             : 
     467             :   ExecutionSession ES;
     468             : 
     469             :   std::unique_ptr<TargetMachine> TM;
     470             :   std::shared_ptr<MCJITReplacementMemMgr> MemMgr;
     471             :   std::shared_ptr<LinkingORCResolver> Resolver;
     472             :   std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
     473             :   Mangler Mang;
     474             : 
     475             :   // IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr
     476             :   // delete blocks in LocalModules refer to the ShouldDelete map, so
     477             :   // LocalModules needs to be destructed before ShouldDelete.
     478             :   std::map<Module*, bool> ShouldDelete;
     479             : 
     480             :   NotifyObjectLoadedT NotifyObjectLoaded;
     481             :   NotifyFinalizedT NotifyFinalized;
     482             : 
     483             :   ObjectLayerT ObjectLayer;
     484             :   CompileLayerT CompileLayer;
     485             :   LazyEmitLayerT LazyEmitLayer;
     486             : 
     487             :   std::map<VModuleKey, std::vector<std::string>> UnexecutedConstructors;
     488             :   std::map<VModuleKey, std::vector<std::string>> UnexecutedDestructors;
     489             : 
     490             :   // We need to store ObjLayerT::ObjSetHandles for each of the object sets
     491             :   // that have been emitted but not yet finalized so that we can forward the
     492             :   // mapSectionAddress calls appropriately.
     493             :   using SectionAddrSet = std::set<const void *>;
     494             :   SectionAddrSet SectionsAllocatedSinceLastLoad;
     495             :   std::map<VModuleKey, SectionAddrSet> UnfinalizedSections;
     496             : 
     497             :   std::vector<object::OwningBinary<object::Archive>> Archives;
     498             : };
     499             : 
     500             : } // end namespace orc
     501             : 
     502             : } // end namespace llvm
     503             : 
     504             : #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H

Generated by: LCOV version 1.13