LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/Orc - OrcMCJITReplacement.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 121 172 70.3 %
Date: 2018-10-20 13:21:21 Functions: 26 34 76.5 %
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             : 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             :   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         188 :           ClientMM->allocateCodeSection(Size, Alignment, SectionID,
      73          94 :                                         SectionName);
      74          94 :       M.SectionsAllocatedSinceLastLoad.insert(Addr);
      75          94 :       return Addr;
      76             :     }
      77             : 
      78         135 :     uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
      79             :                                  unsigned SectionID, StringRef SectionName,
      80             :                                  bool IsReadOnly) override {
      81         270 :       uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
      82         135 :                                                     SectionName, IsReadOnly);
      83         135 :       M.SectionsAllocatedSinceLastLoad.insert(Addr);
      84         135 :       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          14 :                                               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             :   class LinkingORCResolver : public orc::SymbolResolver {
     144             :   public:
     145          77 :     LinkingORCResolver(OrcMCJITReplacement &M) : M(M) {}
     146             : 
     147          93 :     SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) override {
     148             :       SymbolNameSet Result;
     149             : 
     150         112 :       for (auto &S : Symbols) {
     151          57 :         if (auto Sym = M.findMangledSymbol(*S)) {
     152             :           if (!Sym.getFlags().isStrong())
     153             :             Result.insert(S);
     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             :             if (!Sym2.getFlags().isStrong())
     160             :               Result.insert(S);
     161          16 :           } else if (auto Err = Sym2.takeError()) {
     162           0 :             M.reportError(std::move(Err));
     163           0 :             return SymbolNameSet();
     164             :           } else
     165             :             Result.insert(S);
     166             :         }
     167             :       }
     168             : 
     169             :       return Result;
     170             :     }
     171             : 
     172          35 :     SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
     173             :                          SymbolNameSet Symbols) override {
     174             :       SymbolNameSet UnresolvedSymbols;
     175             :       bool NewSymbolsResolved = false;
     176             : 
     177          95 :       for (auto &S : Symbols) {
     178         180 :         if (auto Sym = M.findMangledSymbol(*S)) {
     179          60 :           if (auto Addr = Sym.getAddress()) {
     180         120 :             Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
     181          60 :             Query->notifySymbolReady();
     182             :             NewSymbolsResolved = true;
     183             :           } else {
     184           0 :             M.ES.legacyFailQuery(*Query, Addr.takeError());
     185           0 :             return SymbolNameSet();
     186             :           }
     187           0 :         } else if (auto Err = Sym.takeError()) {
     188           0 :           M.ES.legacyFailQuery(*Query, std::move(Err));
     189           0 :           return SymbolNameSet();
     190             :         } else {
     191           0 :           if (auto Sym2 = M.ClientResolver->findSymbol(*S)) {
     192           0 :             if (auto Addr = Sym2.getAddress()) {
     193           0 :               Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym2.getFlags()));
     194           0 :               Query->notifySymbolReady();
     195             :               NewSymbolsResolved = true;
     196             :             } else {
     197           0 :               M.ES.legacyFailQuery(*Query, Addr.takeError());
     198           0 :               return SymbolNameSet();
     199             :             }
     200           0 :           } else if (auto Err = Sym2.takeError()) {
     201           0 :             M.ES.legacyFailQuery(*Query, std::move(Err));
     202           0 :             return SymbolNameSet();
     203             :           } else
     204             :             UnresolvedSymbols.insert(S);
     205             :         }
     206             :       }
     207             : 
     208          35 :       if (NewSymbolsResolved && Query->isFullyResolved())
     209          35 :         Query->handleFullyResolved();
     210             : 
     211          35 :       if (NewSymbolsResolved && Query->isFullyReady())
     212          35 :         Query->handleFullyReady();
     213             : 
     214             :       return UnresolvedSymbols;
     215             :     }
     216             : 
     217             :   private:
     218             :     OrcMCJITReplacement &M;
     219             :   };
     220             : 
     221             : private:
     222             :   static ExecutionEngine *
     223          77 :   createOrcMCJITReplacement(std::string *ErrorMsg,
     224             :                             std::shared_ptr<MCJITMemoryManager> MemMgr,
     225             :                             std::shared_ptr<LegacyJITSymbolResolver> Resolver,
     226             :                             std::unique_ptr<TargetMachine> TM) {
     227             :     return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
     228         154 :                                    std::move(TM));
     229             :   }
     230             : 
     231           0 :   void reportError(Error Err) {
     232           0 :     logAllUnhandledErrors(std::move(Err), errs(), "MCJIT error: ");
     233           0 :   }
     234             : 
     235             : public:
     236          77 :   OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr,
     237             :                       std::shared_ptr<LegacyJITSymbolResolver> ClientResolver,
     238             :                       std::unique_ptr<TargetMachine> TM)
     239          77 :       : ExecutionEngine(TM->createDataLayout()),
     240             :         TM(std::move(TM)),
     241             :         MemMgr(
     242             :             std::make_shared<MCJITReplacementMemMgr>(*this, std::move(MemMgr))),
     243             :         Resolver(std::make_shared<LinkingORCResolver>(*this)),
     244             :         ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
     245             :         NotifyFinalized(*this),
     246             :         ObjectLayer(
     247             :             ES,
     248          93 :             [this](VModuleKey K) {
     249             :               return ObjectLayerT::Resources{this->MemMgr, this->Resolver};
     250             :             },
     251             :             NotifyObjectLoaded, NotifyFinalized),
     252             :         CompileLayer(ObjectLayer, SimpleCompiler(*this->TM),
     253             :                      [this](VModuleKey K, std::unique_ptr<Module> M) {
     254          89 :                        Modules.push_back(std::move(M));
     255             :                      }),
     256         539 :         LazyEmitLayer(CompileLayer) {}
     257             : 
     258             :   static void Register() {
     259           0 :     OrcMCJITReplacementCtor = createOrcMCJITReplacement;
     260             :   }
     261             : 
     262          90 :   void addModule(std::unique_ptr<Module> M) override {
     263             :     // If this module doesn't have a DataLayout attached then attach the
     264             :     // default.
     265          90 :     if (M->getDataLayout().isDefault()) {
     266          90 :       M->setDataLayout(getDataLayout());
     267             :     } else {
     268             :       assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
     269             :     }
     270             : 
     271             :     // Rename, bump linkage and record static constructors and destructors.
     272             :     // We have to do this before we hand over ownership of the module to the
     273             :     // JIT.
     274          90 :     std::vector<std::string> CtorNames, DtorNames;
     275             :     {
     276             :       unsigned CtorId = 0, DtorId = 0;
     277          91 :       for (auto Ctor : orc::getConstructors(*M)) {
     278           1 :         std::string NewCtorName = ("__ORCstatic_ctor." + Twine(CtorId++)).str();
     279           2 :         Ctor.Func->setName(NewCtorName);
     280             :         Ctor.Func->setLinkage(GlobalValue::ExternalLinkage);
     281             :         Ctor.Func->setVisibility(GlobalValue::HiddenVisibility);
     282           2 :         CtorNames.push_back(mangle(NewCtorName));
     283             :       }
     284          91 :       for (auto Dtor : orc::getDestructors(*M)) {
     285           1 :         std::string NewDtorName = ("__ORCstatic_dtor." + Twine(DtorId++)).str();
     286           2 :         dbgs() << "Found dtor: " << NewDtorName << "\n";
     287           2 :         Dtor.Func->setName(NewDtorName);
     288             :         Dtor.Func->setLinkage(GlobalValue::ExternalLinkage);
     289             :         Dtor.Func->setVisibility(GlobalValue::HiddenVisibility);
     290           2 :         DtorNames.push_back(mangle(NewDtorName));
     291             :       }
     292             :     }
     293             : 
     294          90 :     auto K = ES.allocateVModule();
     295             : 
     296          90 :     UnexecutedConstructors[K] = std::move(CtorNames);
     297          90 :     UnexecutedDestructors[K] = std::move(DtorNames);
     298             : 
     299         270 :     cantFail(LazyEmitLayer.addModule(K, std::move(M)));
     300          90 :   }
     301             : 
     302           0 :   void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
     303           0 :     cantFail(ObjectLayer.addObject(
     304           0 :         ES.allocateVModule(), MemoryBuffer::getMemBufferCopy(O->getData())));
     305           0 :   }
     306             : 
     307           2 :   void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
     308           2 :     std::unique_ptr<object::ObjectFile> Obj;
     309           2 :     std::unique_ptr<MemoryBuffer> ObjBuffer;
     310           2 :     std::tie(Obj, ObjBuffer) = O.takeBinary();
     311           6 :     cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(ObjBuffer)));
     312           2 :   }
     313             : 
     314           1 :   void addArchive(object::OwningBinary<object::Archive> A) override {
     315           1 :     Archives.push_back(std::move(A));
     316           1 :   }
     317             : 
     318           0 :   bool removeModule(Module *M) override {
     319             :     auto I = Modules.begin();
     320           0 :     for (auto E = Modules.end(); I != E; ++I)
     321           0 :       if (I->get() == M)
     322             :         break;
     323           0 :     if (I == Modules.end())
     324             :       return false;
     325           0 :     Modules.erase(I);
     326           0 :     return true;
     327             :   }
     328             : 
     329         205 :   uint64_t getSymbolAddress(StringRef Name) {
     330         410 :     return cantFail(findSymbol(Name).getAddress());
     331             :   }
     332             : 
     333         205 :   JITSymbol findSymbol(StringRef Name) {
     334         205 :     return findMangledSymbol(mangle(Name));
     335             :   }
     336             : 
     337          76 :   void finalizeObject() override {
     338             :     // This is deprecated - Aim to remove in ExecutionEngine.
     339             :     // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
     340          76 :   }
     341             : 
     342           0 :   void mapSectionAddress(const void *LocalAddress,
     343             :                          uint64_t TargetAddress) override {
     344           0 :     for (auto &P : UnfinalizedSections)
     345             :       if (P.second.count(LocalAddress))
     346           0 :         ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
     347           0 :   }
     348             : 
     349           0 :   uint64_t getGlobalValueAddress(const std::string &Name) override {
     350           0 :     return getSymbolAddress(Name);
     351             :   }
     352             : 
     353          11 :   uint64_t getFunctionAddress(const std::string &Name) override {
     354          11 :     return getSymbolAddress(Name);
     355             :   }
     356             : 
     357         194 :   void *getPointerToFunction(Function *F) override {
     358         194 :     uint64_t FAddr = getSymbolAddress(F->getName());
     359         194 :     return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
     360             :   }
     361             : 
     362           0 :   void *getPointerToNamedFunction(StringRef Name,
     363             :                                   bool AbortOnFailure = true) override {
     364           0 :     uint64_t Addr = getSymbolAddress(Name);
     365           0 :     if (!Addr && AbortOnFailure)
     366           0 :       llvm_unreachable("Missing symbol!");
     367           0 :     return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
     368             :   }
     369             : 
     370             :   GenericValue runFunction(Function *F,
     371             :                            ArrayRef<GenericValue> ArgValues) override;
     372             : 
     373           1 :   void setObjectCache(ObjectCache *NewCache) override {
     374             :     CompileLayer.getCompiler().setObjectCache(NewCache);
     375           1 :   }
     376             : 
     377           0 :   void setProcessAllSections(bool ProcessAllSections) override {
     378             :     ObjectLayer.setProcessAllSections(ProcessAllSections);
     379           0 :   }
     380             : 
     381             :   void runStaticConstructorsDestructors(bool isDtors) override;
     382             : 
     383             : private:
     384         284 :   JITSymbol findMangledSymbol(StringRef Name) {
     385         974 :     if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
     386         162 :       return Sym;
     387         384 :     if (auto Sym = ClientResolver->findSymbol(Name))
     388         104 :       return Sym;
     389          34 :     if (auto Sym = scanArchives(Name))
     390           2 :       return Sym;
     391             : 
     392             :     return nullptr;
     393             :   }
     394             : 
     395          18 :   JITSymbol scanArchives(StringRef Name) {
     396          18 :     for (object::OwningBinary<object::Archive> &OB : Archives) {
     397             :       object::Archive *A = OB.getBinary();
     398             :       // Look for our symbols in each Archive
     399           2 :       auto OptionalChildOrErr = A->findSym(Name);
     400           2 :       if (!OptionalChildOrErr)
     401           0 :         report_fatal_error(OptionalChildOrErr.takeError());
     402             :       auto &OptionalChild = *OptionalChildOrErr;
     403           2 :       if (OptionalChild) {
     404             :         // FIXME: Support nested archives?
     405             :         Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
     406           2 :             OptionalChild->getAsBinary();
     407           2 :         if (!ChildBinOrErr) {
     408             :           // TODO: Actually report errors helpfully.
     409           0 :           consumeError(ChildBinOrErr.takeError());
     410           0 :           continue;
     411             :         }
     412             :         std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
     413           4 :         if (ChildBin->isObject()) {
     414           6 :           cantFail(ObjectLayer.addObject(
     415             :               ES.allocateVModule(),
     416           2 :               MemoryBuffer::getMemBufferCopy(ChildBin->getData())));
     417           2 :           if (auto Sym = ObjectLayer.findSymbol(Name, true))
     418           2 :             return Sym;
     419             :         }
     420             :       }
     421             :     }
     422             :     return nullptr;
     423             :   }
     424             : 
     425             :   class NotifyObjectLoadedT {
     426             :   public:
     427             :     using LoadedObjInfoListT =
     428             :         std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>;
     429             : 
     430          77 :     NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
     431             : 
     432          93 :     void operator()(VModuleKey K, const object::ObjectFile &Obj,
     433             :                     const RuntimeDyld::LoadedObjectInfo &Info) const {
     434          93 :       M.UnfinalizedSections[K] = std::move(M.SectionsAllocatedSinceLastLoad);
     435          93 :       M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
     436         186 :       M.MemMgr->notifyObjectLoaded(&M, Obj);
     437          93 :     }
     438             :   private:
     439             :     OrcMCJITReplacement &M;
     440             :   };
     441             : 
     442             :   class NotifyFinalizedT {
     443             :   public:
     444          77 :     NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
     445             : 
     446           0 :     void operator()(VModuleKey K, const object::ObjectFile &Obj,
     447             :                     const RuntimeDyld::LoadedObjectInfo &Info) {
     448           0 :       M.UnfinalizedSections.erase(K);
     449           0 :     }
     450             : 
     451             :   private:
     452             :     OrcMCJITReplacement &M;
     453             :   };
     454             : 
     455         207 :   std::string mangle(StringRef Name) {
     456             :     std::string MangledName;
     457             :     {
     458         207 :       raw_string_ostream MangledNameStream(MangledName);
     459         207 :       Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout());
     460             :     }
     461         207 :     return MangledName;
     462             :   }
     463             : 
     464             :   using ObjectLayerT = LegacyRTDyldObjectLinkingLayer;
     465             :   using CompileLayerT = LegacyIRCompileLayer<ObjectLayerT, orc::SimpleCompiler>;
     466             :   using LazyEmitLayerT = LazyEmittingLayer<CompileLayerT>;
     467             : 
     468             :   ExecutionSession ES;
     469             : 
     470             :   std::unique_ptr<TargetMachine> TM;
     471             :   std::shared_ptr<MCJITReplacementMemMgr> MemMgr;
     472             :   std::shared_ptr<LinkingORCResolver> Resolver;
     473             :   std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
     474             :   Mangler Mang;
     475             : 
     476             :   // IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr
     477             :   // delete blocks in LocalModules refer to the ShouldDelete map, so
     478             :   // LocalModules needs to be destructed before ShouldDelete.
     479             :   std::map<Module*, bool> ShouldDelete;
     480             : 
     481             :   NotifyObjectLoadedT NotifyObjectLoaded;
     482             :   NotifyFinalizedT NotifyFinalized;
     483             : 
     484             :   ObjectLayerT ObjectLayer;
     485             :   CompileLayerT CompileLayer;
     486             :   LazyEmitLayerT LazyEmitLayer;
     487             : 
     488             :   std::map<VModuleKey, std::vector<std::string>> UnexecutedConstructors;
     489             :   std::map<VModuleKey, std::vector<std::string>> UnexecutedDestructors;
     490             : 
     491             :   // We need to store ObjLayerT::ObjSetHandles for each of the object sets
     492             :   // that have been emitted but not yet finalized so that we can forward the
     493             :   // mapSectionAddress calls appropriately.
     494             :   using SectionAddrSet = std::set<const void *>;
     495             :   SectionAddrSet SectionsAllocatedSinceLastLoad;
     496             :   std::map<VModuleKey, SectionAddrSet> UnfinalizedSections;
     497             : 
     498             :   std::vector<object::OwningBinary<object::Archive>> Archives;
     499             : };
     500             : 
     501             : } // end namespace orc
     502             : 
     503             : } // end namespace llvm
     504             : 
     505             : #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H

Generated by: LCOV version 1.13