diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc')
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Core.cpp | 653 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp | 68 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp | 112 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 36 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Legacy.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/OrcError.cpp | 115 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/RPCUtils.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp | 19 |
15 files changed, 580 insertions, 582 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp index 75ddbc30445d..f26835ff8a08 100644 --- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp @@ -162,7 +162,8 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R, return; } - R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), true)); + R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), + JITDylibLookupFlags::MatchAllSymbols)); R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), std::move(Callables), AliaseeImpls)); } @@ -171,18 +172,22 @@ CompileOnDemandLayer::PerDylibResources & CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) { auto I = DylibResources.find(&TargetD); if (I == DylibResources.end()) { - auto &ImplD = getExecutionSession().createJITDylib( - TargetD.getName() + ".impl", false); - TargetD.withSearchOrderDo([&](const JITDylibSearchList &TargetSearchOrder) { - auto NewSearchOrder = TargetSearchOrder; - assert(!NewSearchOrder.empty() && - NewSearchOrder.front().first == &TargetD && - NewSearchOrder.front().second == true && - "TargetD must be at the front of its own search order and match " - "non-exported symbol"); - NewSearchOrder.insert(std::next(NewSearchOrder.begin()), {&ImplD, true}); - ImplD.setSearchOrder(std::move(NewSearchOrder), false); - }); + auto &ImplD = + getExecutionSession().createJITDylib(TargetD.getName() + ".impl"); + TargetD.withSearchOrderDo( + [&](const JITDylibSearchOrder &TargetSearchOrder) { + auto NewSearchOrder = TargetSearchOrder; + assert( + !NewSearchOrder.empty() && + NewSearchOrder.front().first == &TargetD && + NewSearchOrder.front().second == + JITDylibLookupFlags::MatchAllSymbols && + "TargetD must be at the front of its own search order and match " + "non-exported symbol"); + NewSearchOrder.insert(std::next(NewSearchOrder.begin()), + {&ImplD, JITDylibLookupFlags::MatchAllSymbols}); + ImplD.setSearchOrder(std::move(NewSearchOrder), false); + }); PerDylibResources PDR(ImplD, BuildIndirectStubsManager()); I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first; } diff --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp index f8251627a4ef..f5671d90420a 100644 --- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp @@ -43,8 +43,7 @@ SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) { } auto ObjBuffer = std::make_unique<SmallVectorMemoryBuffer>( - std::move(ObjBufferSV), - "<in memory object compiled from " + M.getModuleIdentifier() + ">"); + std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer"); auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index 5c7d888c2d6e..63ef889dae46 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/Orc/Core.h" + +#include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" #include "llvm/ExecutionEngine/Orc/OrcError.h" #include "llvm/IR/Mangler.h" @@ -77,16 +79,19 @@ bool flagsMatchCLOpts(const JITSymbolFlags &Flags) { #endif // NDEBUG } -// Prints a set of items, filtered by an user-supplied predicate. -template <typename Set, typename Pred = PrintAll<typename Set::value_type>> -class SetPrinter { +// Prints a sequence of items, filtered by an user-supplied predicate. +template <typename Sequence, + typename Pred = PrintAll<typename Sequence::value_type>> +class SequencePrinter { public: - SetPrinter(const Set &S, Pred ShouldPrint = Pred()) - : S(S), ShouldPrint(std::move(ShouldPrint)) {} + SequencePrinter(const Sequence &S, char OpenSeq, char CloseSeq, + Pred ShouldPrint = Pred()) + : S(S), OpenSeq(OpenSeq), CloseSeq(CloseSeq), + ShouldPrint(std::move(ShouldPrint)) {} void printTo(llvm::raw_ostream &OS) const { bool PrintComma = false; - OS << "{"; + OS << OpenSeq; for (auto &E : S) { if (ShouldPrint(E)) { if (PrintComma) @@ -95,23 +100,26 @@ public: PrintComma = true; } } - OS << " }"; + OS << ' ' << CloseSeq; } private: - const Set &S; + const Sequence &S; + char OpenSeq; + char CloseSeq; mutable Pred ShouldPrint; }; -template <typename Set, typename Pred> -SetPrinter<Set, Pred> printSet(const Set &S, Pred P = Pred()) { - return SetPrinter<Set, Pred>(S, std::move(P)); +template <typename Sequence, typename Pred> +SequencePrinter<Sequence, Pred> printSequence(const Sequence &S, char OpenSeq, + char CloseSeq, Pred P = Pred()) { + return SequencePrinter<Sequence, Pred>(S, OpenSeq, CloseSeq, std::move(P)); } -// Render a SetPrinter by delegating to its printTo method. -template <typename Set, typename Pred> +// Render a SequencePrinter by delegating to its printTo method. +template <typename Sequence, typename Pred> llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, - const SetPrinter<Set, Pred> &Printer) { + const SequencePrinter<Sequence, Pred> &Printer) { Printer.printTo(OS); return OS; } @@ -147,7 +155,11 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym) { } raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) { - return OS << printSet(Symbols, PrintAll<SymbolStringPtr>()); + return OS << printSequence(Symbols, '{', '}', PrintAll<SymbolStringPtr>()); +} + +raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols) { + return OS << printSequence(Symbols, '[', ']', PrintAll<SymbolStringPtr>()); } raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) { @@ -182,11 +194,13 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) { } raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) { - return OS << printSet(SymbolFlags, PrintSymbolFlagsMapElemsMatchingCLOpts()); + return OS << printSequence(SymbolFlags, '{', '}', + PrintSymbolFlagsMapElemsMatchingCLOpts()); } raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) { - return OS << printSet(Symbols, PrintSymbolMapElemsMatchingCLOpts()); + return OS << printSequence(Symbols, '{', '}', + PrintSymbolMapElemsMatchingCLOpts()); } raw_ostream &operator<<(raw_ostream &OS, @@ -195,7 +209,8 @@ raw_ostream &operator<<(raw_ostream &OS, } raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) { - return OS << printSet(Deps, PrintAll<SymbolDependenceMap::value_type>()); + return OS << printSequence(Deps, '{', '}', + PrintAll<SymbolDependenceMap::value_type>()); } raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) { @@ -205,16 +220,59 @@ raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) { return OS << ")"; } -raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs) { +raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K) { + switch (K) { + case LookupKind::Static: + return OS << "Static"; + case LookupKind::DLSym: + return OS << "DLSym"; + } + llvm_unreachable("Invalid lookup kind"); +} + +raw_ostream &operator<<(raw_ostream &OS, + const JITDylibLookupFlags &JDLookupFlags) { + switch (JDLookupFlags) { + case JITDylibLookupFlags::MatchExportedSymbolsOnly: + return OS << "MatchExportedSymbolsOnly"; + case JITDylibLookupFlags::MatchAllSymbols: + return OS << "MatchAllSymbols"; + } + llvm_unreachable("Invalid JITDylib lookup flags"); +} + +raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags) { + switch (LookupFlags) { + case SymbolLookupFlags::RequiredSymbol: + return OS << "RequiredSymbol"; + case SymbolLookupFlags::WeaklyReferencedSymbol: + return OS << "WeaklyReferencedSymbol"; + } + llvm_unreachable("Invalid symbol lookup flags"); +} + +raw_ostream &operator<<(raw_ostream &OS, + const SymbolLookupSet::value_type &KV) { + return OS << "(" << KV.first << ", " << KV.second << ")"; +} + +raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet) { + return OS << printSequence(LookupSet, '{', '}', + PrintAll<SymbolLookupSet::value_type>()); +} + +raw_ostream &operator<<(raw_ostream &OS, + const JITDylibSearchOrder &SearchOrder) { OS << "["; - if (!JDs.empty()) { - assert(JDs.front().first && "JITDylibList entries must not be null"); - OS << " (\"" << JDs.front().first->getName() << "\", " - << (JDs.front().second ? "true" : "false") << ")"; - for (auto &KV : make_range(std::next(JDs.begin()), JDs.end())) { + if (!SearchOrder.empty()) { + assert(SearchOrder.front().first && + "JITDylibList entries must not be null"); + OS << " (\"" << SearchOrder.front().first->getName() << "\", " + << SearchOrder.begin()->second << ")"; + for (auto &KV : + make_range(std::next(SearchOrder.begin(), 1), SearchOrder.end())) { assert(KV.first && "JITDylibList entries must not be null"); - OS << ", (\"" << KV.first->getName() << "\", " - << (KV.second ? "true" : "false") << ")"; + OS << ", (\"" << KV.first->getName() << "\", " << KV.second << ")"; } } OS << " ]"; @@ -262,7 +320,13 @@ void FailedToMaterialize::log(raw_ostream &OS) const { OS << "Failed to materialize symbols: " << *Symbols; } -SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) +SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) { + for (auto &Sym : Symbols) + this->Symbols.push_back(Sym); + assert(!this->Symbols.empty() && "Can not fail to resolve an empty set"); +} + +SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols) : Symbols(std::move(Symbols)) { assert(!this->Symbols.empty() && "Can not fail to resolve an empty set"); } @@ -289,7 +353,7 @@ void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const { } AsynchronousSymbolQuery::AsynchronousSymbolQuery( - const SymbolNameSet &Symbols, SymbolState RequiredState, + const SymbolLookupSet &Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete) : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) { assert(RequiredState >= SymbolState::Resolved && @@ -298,8 +362,8 @@ AsynchronousSymbolQuery::AsynchronousSymbolQuery( OutstandingSymbolsCount = Symbols.size(); - for (auto &S : Symbols) - ResolvedSymbols[S] = nullptr; + for (auto &KV : Symbols) + ResolvedSymbols[KV.first] = nullptr; } void AsynchronousSymbolQuery::notifySymbolMetRequiredState( @@ -511,10 +575,10 @@ AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) { } ReExportsMaterializationUnit::ReExportsMaterializationUnit( - JITDylib *SourceJD, bool MatchNonExported, SymbolAliasMap Aliases, - VModuleKey K) + JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags, + SymbolAliasMap Aliases, VModuleKey K) : MaterializationUnit(extractFlags(Aliases), std::move(K)), - SourceJD(SourceJD), MatchNonExported(MatchNonExported), + SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags), Aliases(std::move(Aliases)) {} StringRef ReExportsMaterializationUnit::getName() const { @@ -551,7 +615,7 @@ void ReExportsMaterializationUnit::materialize( if (!Aliases.empty()) { if (SourceJD) - R.replace(reexports(*SourceJD, std::move(Aliases), MatchNonExported)); + R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags)); else R.replace(symbolAliases(std::move(Aliases))); } @@ -572,11 +636,11 @@ void ReExportsMaterializationUnit::materialize( // be waitin on a symbol that it itself had to resolve. Usually this will just // involve one round and a single query. - std::vector<std::pair<SymbolNameSet, std::shared_ptr<OnResolveInfo>>> + std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>> QueryInfos; while (!RequestedAliases.empty()) { SymbolNameSet ResponsibilitySymbols; - SymbolNameSet QuerySymbols; + SymbolLookupSet QuerySymbols; SymbolAliasMap QueryAliases; // Collect as many aliases as we can without including a chain. @@ -587,7 +651,7 @@ void ReExportsMaterializationUnit::materialize( continue; ResponsibilitySymbols.insert(KV.first); - QuerySymbols.insert(KV.second.Aliasee); + QuerySymbols.add(KV.second.Aliasee); QueryAliases[KV.first] = std::move(KV.second); } @@ -657,8 +721,9 @@ void ReExportsMaterializationUnit::materialize( } }; - ES.lookup(JITDylibSearchList({{&SrcJD, MatchNonExported}}), QuerySymbols, - SymbolState::Resolved, std::move(OnComplete), + ES.lookup(LookupKind::Static, + JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}), + QuerySymbols, SymbolState::Resolved, std::move(OnComplete), std::move(RegisterDependencies)); } } @@ -681,16 +746,16 @@ ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) { Expected<SymbolAliasMap> buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) { - auto Flags = SourceJD.lookupFlags(Symbols); + SymbolLookupSet LookupSet(Symbols); + auto Flags = SourceJD.lookupFlags( + LookupKind::Static, JITDylibLookupFlags::MatchAllSymbols, LookupSet); if (!Flags) return Flags.takeError(); - if (Flags->size() != Symbols.size()) { - SymbolNameSet Unresolved = Symbols; - for (auto &KV : *Flags) - Unresolved.erase(KV.first); - return make_error<SymbolsNotFound>(std::move(Unresolved)); + if (!LookupSet.empty()) { + LookupSet.sortByName(); + return make_error<SymbolsNotFound>(LookupSet.getSymbolNames()); } SymbolAliasMap Result; @@ -703,32 +768,32 @@ buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) { } ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD, - bool MatchNonExported, + JITDylibLookupFlags SourceJDLookupFlags, SymbolPredicate Allow) - : SourceJD(SourceJD), MatchNonExported(MatchNonExported), + : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags), Allow(std::move(Allow)) {} -Expected<SymbolNameSet> -ReexportsGenerator::tryToGenerate(JITDylib &JD, const SymbolNameSet &Names) { - orc::SymbolNameSet Added; - orc::SymbolAliasMap AliasMap; - - auto Flags = SourceJD.lookupFlags(Names); +Error ReexportsGenerator::tryToGenerate(LookupKind K, JITDylib &JD, + JITDylibLookupFlags JDLookupFlags, + const SymbolLookupSet &LookupSet) { + assert(&JD != &SourceJD && "Cannot re-export from the same dylib"); + // Use lookupFlags to find the subset of symbols that match our lookup. + auto Flags = SourceJD.lookupFlags(K, JDLookupFlags, LookupSet); if (!Flags) return Flags.takeError(); - for (auto &KV : *Flags) { - if (Allow && !Allow(KV.first)) - continue; - AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second); - Added.insert(KV.first); - } + // Create an alias map. + orc::SymbolAliasMap AliasMap; + for (auto &KV : *Flags) + if (!Allow || Allow(KV.first)) + AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second); - if (!Added.empty()) - cantFail(JD.define(reexports(SourceJD, AliasMap, MatchNonExported))); + if (AliasMap.empty()) + return Error::success(); - return Added; + // Define the re-exports. + return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags)); } JITDylib::DefinitionGenerator::~DefinitionGenerator() {} @@ -1228,11 +1293,14 @@ void JITDylib::notifyFailed(FailedSymbolsWorklist Worklist) { MI.UnemittedDependencies.clear(); // Collect queries to be failed for this MII. + AsynchronousSymbolQueryList ToDetach; for (auto &Q : MII->second.pendingQueries()) { // Add the query to the list to be failed and detach it. FailedQueries.insert(Q); - Q->detach(); + ToDetach.push_back(Q); } + for (auto &Q : ToDetach) + Q->detach(); assert(MI.Dependants.empty() && "Can not delete MaterializingInfo with dependants still attached"); @@ -1249,41 +1317,41 @@ void JITDylib::notifyFailed(FailedSymbolsWorklist Worklist) { Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbolsMap)); } -void JITDylib::setSearchOrder(JITDylibSearchList NewSearchOrder, - bool SearchThisJITDylibFirst, - bool MatchNonExportedInThisDylib) { - if (SearchThisJITDylibFirst) { - if (NewSearchOrder.empty() || NewSearchOrder.front().first != this) - NewSearchOrder.insert(NewSearchOrder.begin(), - {this, MatchNonExportedInThisDylib}); - } - - ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); }); -} - -void JITDylib::addToSearchOrder(JITDylib &JD, bool MatchNonExported) { +void JITDylib::setSearchOrder(JITDylibSearchOrder NewSearchOrder, + bool SearchThisJITDylibFirst) { ES.runSessionLocked([&]() { - SearchOrder.push_back({&JD, MatchNonExported}); + if (SearchThisJITDylibFirst) { + SearchOrder.clear(); + if (NewSearchOrder.empty() || NewSearchOrder.front().first != this) + SearchOrder.push_back( + std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols)); + SearchOrder.insert(SearchOrder.end(), NewSearchOrder.begin(), + NewSearchOrder.end()); + } else + SearchOrder = std::move(NewSearchOrder); }); } +void JITDylib::addToSearchOrder(JITDylib &JD, + JITDylibLookupFlags JDLookupFlags) { + ES.runSessionLocked([&]() { SearchOrder.push_back({&JD, JDLookupFlags}); }); +} + void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD, - bool MatchNonExported) { + JITDylibLookupFlags JDLookupFlags) { ES.runSessionLocked([&]() { - auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(), - [&](const JITDylibSearchList::value_type &KV) { - return KV.first == &OldJD; - }); - - if (I != SearchOrder.end()) - *I = {&NewJD, MatchNonExported}; + for (auto &KV : SearchOrder) + if (KV.first == &OldJD) { + KV = {&NewJD, JDLookupFlags}; + break; + } }); } void JITDylib::removeFromSearchOrder(JITDylib &JD) { ES.runSessionLocked([&]() { auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(), - [&](const JITDylibSearchList::value_type &KV) { + [&](const JITDylibSearchOrder::value_type &KV) { return KV.first == &JD; }); if (I != SearchOrder.end()) @@ -1346,63 +1414,54 @@ Error JITDylib::remove(const SymbolNameSet &Names) { }); } -Expected<SymbolFlagsMap> JITDylib::lookupFlags(const SymbolNameSet &Names) { +Expected<SymbolFlagsMap> +JITDylib::lookupFlags(LookupKind K, JITDylibLookupFlags JDLookupFlags, + SymbolLookupSet LookupSet) { return ES.runSessionLocked([&, this]() -> Expected<SymbolFlagsMap> { SymbolFlagsMap Result; - auto Unresolved = lookupFlagsImpl(Result, Names); - if (!Unresolved) - return Unresolved.takeError(); + lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet); - /// Run any definition generators. + // Run any definition generators. for (auto &DG : DefGenerators) { - // Bail out early if we've resolved everything. - if (Unresolved->empty()) + // Bail out early if we found everything. + if (LookupSet.empty()) break; // Run this generator. - auto NewDefs = DG->tryToGenerate(*this, *Unresolved); - if (!NewDefs) - return NewDefs.takeError(); - - if (!NewDefs->empty()) { - auto Unresolved2 = lookupFlagsImpl(Result, *NewDefs); - if (!Unresolved2) - return Unresolved2.takeError(); - (void)Unresolved2; - assert(Unresolved2->empty() && - "All fallback defs should have been found by lookupFlagsImpl"); - } + if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, LookupSet)) + return std::move(Err); - for (auto &Name : *NewDefs) - Unresolved->erase(Name); + // Re-try the search. + lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet); } + return Result; }); } -Expected<SymbolNameSet> JITDylib::lookupFlagsImpl(SymbolFlagsMap &Flags, - const SymbolNameSet &Names) { - SymbolNameSet Unresolved; +void JITDylib::lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K, + JITDylibLookupFlags JDLookupFlags, + SymbolLookupSet &LookupSet) { - for (auto &Name : Names) { - auto I = Symbols.find(Name); - if (I != Symbols.end()) { - assert(!Flags.count(Name) && "Symbol already present in Flags map"); - Flags[Name] = I->second.getFlags(); - } else - Unresolved.insert(Name); - } - - return Unresolved; + LookupSet.forEachWithRemoval( + [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool { + auto I = Symbols.find(Name); + if (I == Symbols.end()) + return false; + assert(!Result.count(Name) && "Symbol already present in Flags map"); + Result[Name] = I->second.getFlags(); + return true; + }); } -Error JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q, - SymbolNameSet &Unresolved, bool MatchNonExported, - MaterializationUnitList &MUs) { +Error JITDylib::lodgeQuery(MaterializationUnitList &MUs, + std::shared_ptr<AsynchronousSymbolQuery> &Q, + LookupKind K, JITDylibLookupFlags JDLookupFlags, + SymbolLookupSet &Unresolved) { assert(Q && "Query can not be null"); - if (auto Err = lodgeQueryImpl(Q, Unresolved, MatchNonExported, MUs)) + if (auto Err = lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved)) return Err; // Run any definition generators. @@ -1413,104 +1472,86 @@ Error JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q, break; // Run the generator. - auto NewDefs = DG->tryToGenerate(*this, Unresolved); - - // If the generator returns an error then bail out. - if (!NewDefs) - return NewDefs.takeError(); - - // If the generator was able to generate new definitions for any of the - // unresolved symbols then lodge the query against them. - if (!NewDefs->empty()) { - for (auto &D : *NewDefs) - Unresolved.erase(D); - - // Lodge query. This can not fail as any new definitions were added - // by the generator under the session locked. Since they can't have - // started materializing yet the can not have failed. - cantFail(lodgeQueryImpl(Q, *NewDefs, MatchNonExported, MUs)); + if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, Unresolved)) + return Err; - assert(NewDefs->empty() && - "All fallback defs should have been found by lookupImpl"); - } + // Lodge query. This can not fail as any new definitions were added + // by the generator under the session locked. Since they can't have + // started materializing yet they can not have failed. + cantFail(lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved)); } return Error::success(); } -Error JITDylib::lodgeQueryImpl( - std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved, - bool MatchNonExported, - std::vector<std::unique_ptr<MaterializationUnit>> &MUs) { - - std::vector<SymbolStringPtr> ToRemove; - for (auto Name : Unresolved) { - - // Search for the name in Symbols. Skip it if not found. - auto SymI = Symbols.find(Name); - if (SymI == Symbols.end()) - continue; - - // If this is a non exported symbol and we're skipping those then skip it. - if (!SymI->second.getFlags().isExported() && !MatchNonExported) - continue; - - // If we matched against Name in JD, mark it to be removed from the - // Unresolved set. - ToRemove.push_back(Name); - - // If we matched against this symbol but it is in the error state then - // bail out and treat it as a failure to materialize. - if (SymI->second.getFlags().hasError()) { - auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>(); - (*FailedSymbolsMap)[this] = {Name}; - return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap)); - } - - // If this symbol already meets the required state for then notify the - // query and continue. - if (SymI->second.getState() >= Q->getRequiredState()) { - Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol()); - continue; - } - - // Otherwise this symbol does not yet meet the required state. Check whether - // it has a materializer attached, and if so prepare to run it. - if (SymI->second.hasMaterializerAttached()) { - assert(SymI->second.getAddress() == 0 && - "Symbol not resolved but already has address?"); - auto UMII = UnmaterializedInfos.find(Name); - assert(UMII != UnmaterializedInfos.end() && - "Lazy symbol should have UnmaterializedInfo"); - auto MU = std::move(UMII->second->MU); - assert(MU != nullptr && "Materializer should not be null"); - - // Move all symbols associated with this MaterializationUnit into - // materializing state. - for (auto &KV : MU->getSymbols()) { - auto SymK = Symbols.find(KV.first); - SymK->second.setMaterializerAttached(false); - SymK->second.setState(SymbolState::Materializing); - UnmaterializedInfos.erase(KV.first); - } +Error JITDylib::lodgeQueryImpl(MaterializationUnitList &MUs, + std::shared_ptr<AsynchronousSymbolQuery> &Q, + LookupKind K, JITDylibLookupFlags JDLookupFlags, + SymbolLookupSet &Unresolved) { + + return Unresolved.forEachWithRemoval( + [&](const SymbolStringPtr &Name, + SymbolLookupFlags SymLookupFlags) -> Expected<bool> { + // Search for name in symbols. If not found then continue without + // removal. + auto SymI = Symbols.find(Name); + if (SymI == Symbols.end()) + return false; + + // If this is a non exported symbol and we're matching exported symbols + // only then skip this symbol without removal. + if (!SymI->second.getFlags().isExported() && + JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly) + return false; + + // If we matched against this symbol but it is in the error state then + // bail out and treat it as a failure to materialize. + if (SymI->second.getFlags().hasError()) { + auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>(); + (*FailedSymbolsMap)[this] = {Name}; + return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap)); + } - // Add MU to the list of MaterializationUnits to be materialized. - MUs.push_back(std::move(MU)); - } + // If this symbol already meets the required state for then notify the + // query, then remove the symbol and continue. + if (SymI->second.getState() >= Q->getRequiredState()) { + Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol()); + return true; + } - // Add the query to the PendingQueries list. - assert(SymI->second.isInMaterializationPhase() && - "By this line the symbol should be materializing"); - auto &MI = MaterializingInfos[Name]; - MI.addQuery(Q); - Q->addQueryDependence(*this, Name); - } + // Otherwise this symbol does not yet meet the required state. Check + // whether it has a materializer attached, and if so prepare to run it. + if (SymI->second.hasMaterializerAttached()) { + assert(SymI->second.getAddress() == 0 && + "Symbol not resolved but already has address?"); + auto UMII = UnmaterializedInfos.find(Name); + assert(UMII != UnmaterializedInfos.end() && + "Lazy symbol should have UnmaterializedInfo"); + auto MU = std::move(UMII->second->MU); + assert(MU != nullptr && "Materializer should not be null"); + + // Move all symbols associated with this MaterializationUnit into + // materializing state. + for (auto &KV : MU->getSymbols()) { + auto SymK = Symbols.find(KV.first); + SymK->second.setMaterializerAttached(false); + SymK->second.setState(SymbolState::Materializing); + UnmaterializedInfos.erase(KV.first); + } - // Remove any symbols that we found. - for (auto &Name : ToRemove) - Unresolved.erase(Name); + // Add MU to the list of MaterializationUnits to be materialized. + MUs.push_back(std::move(MU)); + } - return Error::success(); + // Add the query to the PendingQueries list and continue, deleting the + // element. + assert(SymI->second.isInMaterializationPhase() && + "By this line the symbol should be materializing"); + auto &MI = MaterializingInfos[Name]; + MI.addQuery(Q); + Q->addQueryDependence(*this, Name); + return true; + }); } Expected<SymbolNameSet> @@ -1523,7 +1564,7 @@ JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, bool QueryComplete = false; std::vector<std::unique_ptr<MaterializationUnit>> MUs; - SymbolNameSet Unresolved = std::move(Names); + SymbolLookupSet Unresolved(Names); auto Err = ES.runSessionLocked([&, this]() -> Error { QueryComplete = lookupImpl(Q, MUs, Unresolved); @@ -1535,16 +1576,13 @@ JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, break; assert(!QueryComplete && "query complete but unresolved symbols remain?"); - auto NewDefs = DG->tryToGenerate(*this, Unresolved); - if (!NewDefs) - return NewDefs.takeError(); - if (!NewDefs->empty()) { - for (auto &D : *NewDefs) - Unresolved.erase(D); - QueryComplete = lookupImpl(Q, MUs, *NewDefs); - assert(NewDefs->empty() && - "All fallback defs should have been found by lookupImpl"); - } + if (auto Err = DG->tryToGenerate(LookupKind::Static, *this, + JITDylibLookupFlags::MatchAllSymbols, + Unresolved)) + return Err; + + if (!Unresolved.empty()) + QueryComplete = lookupImpl(Q, MUs, Unresolved); } return Error::success(); }); @@ -1572,68 +1610,68 @@ JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, // for (auto &MU : MUs) // ES.dispatchMaterialization(*this, std::move(MU)); - return Unresolved; + SymbolNameSet RemainingSymbols; + for (auto &KV : Unresolved) + RemainingSymbols.insert(KV.first); + + return RemainingSymbols; } bool JITDylib::lookupImpl( std::shared_ptr<AsynchronousSymbolQuery> &Q, std::vector<std::unique_ptr<MaterializationUnit>> &MUs, - SymbolNameSet &Unresolved) { + SymbolLookupSet &Unresolved) { bool QueryComplete = false; std::vector<SymbolStringPtr> ToRemove; - for (auto Name : Unresolved) { - - // Search for the name in Symbols. Skip it if not found. - auto SymI = Symbols.find(Name); - if (SymI == Symbols.end()) - continue; - - // If we found Name, mark it to be removed from the Unresolved set. - ToRemove.push_back(Name); - - if (SymI->second.getState() >= Q->getRequiredState()) { - Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol()); - if (Q->isComplete()) - QueryComplete = true; - continue; - } - - // If the symbol is lazy, get the MaterialiaztionUnit for it. - if (SymI->second.hasMaterializerAttached()) { - assert(SymI->second.getAddress() == 0 && - "Lazy symbol should not have a resolved address"); - auto UMII = UnmaterializedInfos.find(Name); - assert(UMII != UnmaterializedInfos.end() && - "Lazy symbol should have UnmaterializedInfo"); - auto MU = std::move(UMII->second->MU); - assert(MU != nullptr && "Materializer should not be null"); - - // Kick all symbols associated with this MaterializationUnit into - // materializing state. - for (auto &KV : MU->getSymbols()) { - auto SymK = Symbols.find(KV.first); - assert(SymK != Symbols.end() && "Missing symbol table entry"); - SymK->second.setState(SymbolState::Materializing); - SymK->second.setMaterializerAttached(false); - UnmaterializedInfos.erase(KV.first); - } + Unresolved.forEachWithRemoval( + [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool { + // Search for the name in Symbols. Skip without removing if not found. + auto SymI = Symbols.find(Name); + if (SymI == Symbols.end()) + return false; + + // If the symbol is already in the required state then notify the query + // and remove. + if (SymI->second.getState() >= Q->getRequiredState()) { + Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol()); + if (Q->isComplete()) + QueryComplete = true; + return true; + } - // Add MU to the list of MaterializationUnits to be materialized. - MUs.push_back(std::move(MU)); - } + // If the symbol is lazy, get the MaterialiaztionUnit for it. + if (SymI->second.hasMaterializerAttached()) { + assert(SymI->second.getAddress() == 0 && + "Lazy symbol should not have a resolved address"); + auto UMII = UnmaterializedInfos.find(Name); + assert(UMII != UnmaterializedInfos.end() && + "Lazy symbol should have UnmaterializedInfo"); + auto MU = std::move(UMII->second->MU); + assert(MU != nullptr && "Materializer should not be null"); + + // Kick all symbols associated with this MaterializationUnit into + // materializing state. + for (auto &KV : MU->getSymbols()) { + auto SymK = Symbols.find(KV.first); + assert(SymK != Symbols.end() && "Missing symbol table entry"); + SymK->second.setState(SymbolState::Materializing); + SymK->second.setMaterializerAttached(false); + UnmaterializedInfos.erase(KV.first); + } - // Add the query to the PendingQueries list. - assert(SymI->second.isInMaterializationPhase() && - "By this line the symbol should be materializing"); - auto &MI = MaterializingInfos[Name]; - MI.addQuery(Q); - Q->addQueryDependence(*this, Name); - } + // Add MU to the list of MaterializationUnits to be materialized. + MUs.push_back(std::move(MU)); + } - // Remove any marked symbols from the Unresolved set. - for (auto &Name : ToRemove) - Unresolved.erase(Name); + // Add the query to the PendingQueries list. + assert(SymI->second.isInMaterializationPhase() && + "By this line the symbol should be materializing"); + auto &MI = MaterializingInfos[Name]; + MI.addQuery(Q); + Q->addQueryDependence(*this, Name); + return true; + }); return QueryComplete; } @@ -1642,11 +1680,7 @@ void JITDylib::dump(raw_ostream &OS) { ES.runSessionLocked([&, this]() { OS << "JITDylib \"" << JITDylibName << "\" (ES: " << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n" - << "Search order: ["; - for (auto &KV : SearchOrder) - OS << " (\"" << KV.first->getName() << "\", " - << (KV.second ? "all" : "exported only") << ")"; - OS << " ]\n" + << "Search order: " << SearchOrder << "\n" << "Symbol table:\n"; for (auto &KV : Symbols) { @@ -1727,7 +1761,7 @@ JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) { JITDylib::JITDylib(ExecutionSession &ES, std::string Name) : ES(ES), JITDylibName(std::move(Name)) { - SearchOrder.push_back({this, true}); + SearchOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols}); } Error JITDylib::defineImpl(MaterializationUnit &MU) { @@ -1820,12 +1854,6 @@ void JITDylib::transferEmittedNodeDependencies( ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP) : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) { - // Construct the main dylib. - JDs.push_back(std::unique_ptr<JITDylib>(new JITDylib(*this, "<main>"))); -} - -JITDylib &ExecutionSession::getMainJITDylib() { - return runSessionLocked([this]() -> JITDylib & { return *JDs.front(); }); } JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) { @@ -1837,14 +1865,11 @@ JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) { }); } -JITDylib &ExecutionSession::createJITDylib(std::string Name, - bool AddToMainDylibSearchOrder) { +JITDylib &ExecutionSession::createJITDylib(std::string Name) { assert(!getJITDylibByName(Name) && "JITDylib with that name already exists"); return runSessionLocked([&, this]() -> JITDylib & { JDs.push_back( std::unique_ptr<JITDylib>(new JITDylib(*this, std::move(Name)))); - if (AddToMainDylibSearchOrder) - JDs.front()->addToSearchOrder(*JDs.back()); return *JDs.back(); }); } @@ -1895,7 +1920,7 @@ Expected<SymbolMap> ExecutionSession::legacyLookup( #endif auto Query = std::make_shared<AsynchronousSymbolQuery>( - Names, RequiredState, std::move(NotifyComplete)); + SymbolLookupSet(Names), RequiredState, std::move(NotifyComplete)); // FIXME: This should be run session locked along with the registration code // and error reporting below. SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names)); @@ -1932,8 +1957,9 @@ Expected<SymbolMap> ExecutionSession::legacyLookup( } void ExecutionSession::lookup( - const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols, - SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, + LookupKind K, const JITDylibSearchOrder &SearchOrder, + SymbolLookupSet Symbols, SymbolState RequiredState, + SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies) { LLVM_DEBUG({ @@ -1962,14 +1988,24 @@ void ExecutionSession::lookup( "JITDylibList should not contain duplicate entries"); auto &JD = *KV.first; - auto MatchNonExported = KV.second; - if (auto Err = JD.lodgeQuery(Q, Unresolved, MatchNonExported, - CollectedMUsMap[&JD])) + auto JDLookupFlags = KV.second; + if (auto Err = JD.lodgeQuery(CollectedMUsMap[&JD], Q, K, JDLookupFlags, + Unresolved)) return Err; } + // Strip any weakly referenced symbols that were not found. + Unresolved.forEachWithRemoval( + [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) { + if (Flags == SymbolLookupFlags::WeaklyReferencedSymbol) { + Q->dropSymbol(Name); + return true; + } + return false; + }); + if (!Unresolved.empty()) - return make_error<SymbolsNotFound>(std::move(Unresolved)); + return make_error<SymbolsNotFound>(Unresolved.getSymbolNames()); return Error::success(); }; @@ -2023,8 +2059,8 @@ void ExecutionSession::lookup( } Expected<SymbolMap> -ExecutionSession::lookup(const JITDylibSearchList &SearchOrder, - const SymbolNameSet &Symbols, +ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder, + const SymbolLookupSet &Symbols, LookupKind K, SymbolState RequiredState, RegisterDependenciesFunction RegisterDependencies) { #if LLVM_ENABLE_THREADS @@ -2056,7 +2092,7 @@ ExecutionSession::lookup(const JITDylibSearchList &SearchOrder, #endif // Perform the asynchronous lookup. - lookup(SearchOrder, Symbols, RequiredState, NotifyComplete, + lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete, RegisterDependencies); #if LLVM_ENABLE_THREADS @@ -2077,12 +2113,12 @@ ExecutionSession::lookup(const JITDylibSearchList &SearchOrder, } Expected<JITEvaluatedSymbol> -ExecutionSession::lookup(const JITDylibSearchList &SearchOrder, +ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder, SymbolStringPtr Name) { - SymbolNameSet Names({Name}); + SymbolLookupSet Names({Name}); - if (auto ResultMap = lookup(SearchOrder, std::move(Names), SymbolState::Ready, - NoDependenciesToRegister)) { + if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static, + SymbolState::Ready, NoDependenciesToRegister)) { assert(ResultMap->size() == 1 && "Unexpected number of results"); assert(ResultMap->count(Name) && "Missing result for symbol"); return std::move(ResultMap->begin()->second); @@ -2093,14 +2129,7 @@ ExecutionSession::lookup(const JITDylibSearchList &SearchOrder, Expected<JITEvaluatedSymbol> ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name) { - SymbolNameSet Names({Name}); - - JITDylibSearchList FullSearchOrder; - FullSearchOrder.reserve(SearchOrder.size()); - for (auto *JD : SearchOrder) - FullSearchOrder.push_back({JD, false}); - - return lookup(FullSearchOrder, Name); + return lookup(makeJITDylibSearchOrder(SearchOrder), Name); } Expected<JITEvaluatedSymbol> diff --git a/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp b/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp new file mode 100644 index 000000000000..c9e87ff737fc --- /dev/null +++ b/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp @@ -0,0 +1,68 @@ +//===---------- DebugUtils.cpp - Utilities for debugging ORC JITs ---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/DebugUtils.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "orc" + +namespace llvm { +namespace orc { + +DumpObjects::DumpObjects(std::string DumpDir, std::string IdentifierOverride) + : DumpDir(std::move(DumpDir)), + IdentifierOverride(std::move(IdentifierOverride)) { + + /// Discard any trailing separators. + while (!this->DumpDir.empty() && + sys::path::is_separator(this->DumpDir.back())) + this->DumpDir.pop_back(); +} + +Expected<std::unique_ptr<MemoryBuffer>> +DumpObjects::operator()(std::unique_ptr<MemoryBuffer> Obj) { + size_t Idx = 1; + + std::string DumpPathStem; + raw_string_ostream(DumpPathStem) + << DumpDir << (DumpDir.empty() ? "" : "/") << getBufferIdentifier(*Obj); + + std::string DumpPath = DumpPathStem + ".o"; + while (sys::fs::exists(DumpPath)) { + DumpPath.clear(); + raw_string_ostream(DumpPath) << DumpPathStem << "." << (++Idx) << ".o"; + } + + LLVM_DEBUG({ + dbgs() << "Dumping object buffer [ " << (const void *)Obj->getBufferStart() + << " -- " << (const void *)(Obj->getBufferEnd() - 1) << " ] to " + << DumpPath << "\n"; + }); + + std::error_code EC; + raw_fd_ostream DumpStream(DumpPath, EC); + if (EC) + return errorCodeToError(EC); + DumpStream.write(Obj->getBufferStart(), Obj->getBufferSize()); + + return std::move(Obj); +} + +StringRef DumpObjects::getBufferIdentifier(MemoryBuffer &B) { + if (!IdentifierOverride.empty()) + return IdentifierOverride; + StringRef Identifier = B.getBufferIdentifier(); + Identifier.consume_back(".o"); + return Identifier; +} + +} // End namespace orc. +} // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp index 4a886ac0597c..3d97fe9eeab1 100644 --- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -19,6 +19,32 @@ namespace llvm { namespace orc { +int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args, + Optional<StringRef> ProgramName) { + std::vector<std::unique_ptr<char[]>> ArgVStorage; + std::vector<char *> ArgV; + + ArgVStorage.reserve(Args.size() + (ProgramName ? 1 : 0)); + ArgV.reserve(Args.size() + 1 + (ProgramName ? 1 : 0)); + + if (ProgramName) { + ArgVStorage.push_back(std::make_unique<char[]>(ProgramName->size() + 1)); + llvm::copy(*ProgramName, &ArgVStorage.back()[0]); + ArgVStorage.back()[ProgramName->size()] = '\0'; + ArgV.push_back(ArgVStorage.back().get()); + } + + for (auto &Arg : Args) { + ArgVStorage.push_back(std::make_unique<char[]>(Arg.size() + 1)); + llvm::copy(Arg, &ArgVStorage.back()[0]); + ArgVStorage.back()[Arg.size()] = '\0'; + ArgV.push_back(ArgVStorage.back().get()); + } + ArgV.push_back(nullptr); + + return Main(Args.size() + !!ProgramName, ArgV.data()); +} + CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End) : InitList( GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), @@ -95,7 +121,7 @@ void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) { JD.getExecutionSession(), (*CtorDtors.begin()).Func->getParent()->getDataLayout()); - for (const auto &CtorDtor : CtorDtors) { + for (auto CtorDtor : CtorDtors) { assert(CtorDtor.Func && CtorDtor.Func->hasName() && "Ctor/Dtor function must be named to be runnable under the JIT"); @@ -118,19 +144,17 @@ void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) { Error CtorDtorRunner::run() { using CtorDtorTy = void (*)(); - SymbolNameSet Names; - - for (auto &KV : CtorDtorsByPriority) { - for (auto &Name : KV.second) { - auto Added = Names.insert(Name).second; - (void)Added; - assert(Added && "Ctor/Dtor names clashed"); - } - } + SymbolLookupSet LookupSet; + for (auto &KV : CtorDtorsByPriority) + for (auto &Name : KV.second) + LookupSet.add(Name); + assert(!LookupSet.containsDuplicates() && + "Ctor/Dtor list contains duplicates"); auto &ES = JD.getExecutionSession(); - if (auto CtorDtorMap = - ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names))) { + if (auto CtorDtorMap = ES.lookup( + makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), + std::move(LookupSet))) { for (auto &KV : CtorDtorsByPriority) { for (auto &Name : KV.second) { assert(CtorDtorMap->count(Name) && "No entry for Name"); @@ -190,15 +214,16 @@ DynamicLibrarySearchGenerator::Load(const char *FileName, char GlobalPrefix, std::move(Lib), GlobalPrefix, std::move(Allow)); } -Expected<SymbolNameSet> -DynamicLibrarySearchGenerator::tryToGenerate(JITDylib &JD, - const SymbolNameSet &Names) { - orc::SymbolNameSet Added; +Error DynamicLibrarySearchGenerator::tryToGenerate( + LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, + const SymbolLookupSet &Symbols) { orc::SymbolMap NewSymbols; bool HasGlobalPrefix = (GlobalPrefix != '\0'); - for (auto &Name : Names) { + for (auto &KV : Symbols) { + auto &Name = KV.first; + if ((*Name).empty()) continue; @@ -211,20 +236,16 @@ DynamicLibrarySearchGenerator::tryToGenerate(JITDylib &JD, std::string Tmp((*Name).data() + HasGlobalPrefix, (*Name).size() - HasGlobalPrefix); if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) { - Added.insert(Name); NewSymbols[Name] = JITEvaluatedSymbol( static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)), JITSymbolFlags::Exported); } } - // Add any new symbols to JD. Since the generator is only called for symbols - // that are not already defined, this will never trigger a duplicate - // definition error, so we can wrap this call in a 'cantFail'. - if (!NewSymbols.empty()) - cantFail(JD.define(absoluteSymbols(std::move(NewSymbols)))); + if (NewSymbols.empty()) + return Error::success(); - return Added; + return JD.define(absoluteSymbols(std::move(NewSymbols))); } Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> @@ -251,15 +272,24 @@ StaticLibraryDefinitionGenerator::Create( return std::move(ADG); } -Expected<SymbolNameSet> -StaticLibraryDefinitionGenerator::tryToGenerate(JITDylib &JD, - const SymbolNameSet &Names) { +Error StaticLibraryDefinitionGenerator::tryToGenerate( + LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, + const SymbolLookupSet &Symbols) { + + // Don't materialize symbols from static archives unless this is a static + // lookup. + if (K != LookupKind::Static) + return Error::success(); + + // Bail out early if we've already freed the archive. + if (!Archive) + return Error::success(); DenseSet<std::pair<StringRef, StringRef>> ChildBufferInfos; - SymbolNameSet NewDefs; - for (const auto &Name : Names) { - auto Child = Archive.findSym(*Name); + for (const auto &KV : Symbols) { + const auto &Name = KV.first; + auto Child = Archive->findSym(*Name); if (!Child) return Child.takeError(); if (*Child == None) @@ -269,7 +299,6 @@ StaticLibraryDefinitionGenerator::tryToGenerate(JITDylib &JD, return ChildBuffer.takeError(); ChildBufferInfos.insert( {ChildBuffer->getBuffer(), ChildBuffer->getBufferIdentifier()}); - NewDefs.insert(Name); } for (auto ChildBufferInfo : ChildBufferInfos) { @@ -278,31 +307,16 @@ StaticLibraryDefinitionGenerator::tryToGenerate(JITDylib &JD, if (auto Err = L.add(JD, MemoryBuffer::getMemBuffer(ChildBufferRef), VModuleKey())) - return std::move(Err); - - --UnrealizedObjects; + return Err; } - return NewDefs; + return Error::success(); } StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator( ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, Error &Err) : L(L), ArchiveBuffer(std::move(ArchiveBuffer)), - Archive(*this->ArchiveBuffer, Err) { - - if (Err) - return; - - Error Err2 = Error::success(); - for (auto _ : Archive.children(Err2)) { - (void)_; - ++UnrealizedObjects; - } - - // No need to check this: We will leave it to the caller. - Err = std::move(Err2); -} + Archive(std::make_unique<object::Archive>(*this->ArchiveBuffer, Err)) {} } // End namespace orc. } // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index 0295db7633dd..1ac9a58aeaef 100644 --- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -101,7 +101,10 @@ JITTargetAddress JITCompileCallbackManager::executeCompileCallback( Name = I->second; } - if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name)) + if (auto Sym = + ES.lookup(makeJITDylibSearchOrder( + &CallbacksJD, JITDylibLookupFlags::MatchAllSymbols), + Name)) return Sym->getAddress(); else { llvm::dbgs() << "Didn't find callback.\n"; @@ -199,7 +202,7 @@ createLocalIndirectStubsManagerBuilder(const Triple &T) { return std::make_unique< orc::LocalIndirectStubsManager<orc::OrcMips64>>(); }; - + case Triple::x86_64: if (T.getOS() == Triple::OSType::Win32) { return [](){ diff --git a/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp b/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp index 1d3e6db913e2..114e81e41771 100644 --- a/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp +++ b/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp @@ -28,14 +28,12 @@ Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() { // Retrieve host CPU name and sub-target features and add them to builder. // Relocation model, code model and codegen opt level are kept to default // values. - llvm::SubtargetFeatures SubtargetFeatures; llvm::StringMap<bool> FeatureMap; llvm::sys::getHostCPUFeatures(FeatureMap); for (auto &Feature : FeatureMap) - SubtargetFeatures.AddFeature(Feature.first(), Feature.second); + TMBuilder.getFeatures().AddFeature(Feature.first(), Feature.second); TMBuilder.setCPU(llvm::sys::getHostCPUName()); - TMBuilder.addFeatures(SubtargetFeatures.getFeatures()); return TMBuilder; } diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index a80f78afe80f..54473ab46423 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/Orc/LLJIT.h" +#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" +#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/Orc/OrcError.h" #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" @@ -24,6 +26,26 @@ Error LLJITBuilderState::prepareForConstruction() { return JTMBOrErr.takeError(); } + // If the client didn't configure any linker options then auto-configure the + // JIT linker. + if (!CreateObjectLinkingLayer && JTMB->getCodeModel() == None && + JTMB->getRelocationModel() == None) { + + auto &TT = JTMB->getTargetTriple(); + if (TT.isOSBinFormatMachO() && + (TT.getArch() == Triple::aarch64 || TT.getArch() == Triple::x86_64)) { + + JTMB->setRelocationModel(Reloc::PIC_); + JTMB->setCodeModel(CodeModel::Small); + CreateObjectLinkingLayer = + [](ExecutionSession &ES, + const Triple &) -> std::unique_ptr<ObjectLayer> { + return std::make_unique<ObjectLinkingLayer>( + ES, std::make_unique<jitlink::InProcessMemoryManager>()); + }; + } + } + return Error::success(); } @@ -51,12 +73,14 @@ Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) { assert(Obj && "Can not add null object"); - return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule()); + return ObjTransformLayer.add(JD, std::move(Obj), ES->allocateVModule()); } Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD, StringRef Name) { - return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name)); + return ES->lookup( + makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), + ES->intern(Name)); } std::unique_ptr<ObjectLayer> @@ -103,13 +127,13 @@ LLJIT::createCompileFunction(LLJITBuilderState &S, LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) : ES(S.ES ? std::move(S.ES) : std::make_unique<ExecutionSession>()), - Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main), + Main(this->ES->createJITDylib("<main>")), DL(""), + ObjLinkingLayer(createObjectLinkingLayer(S, *ES)), + ObjTransformLayer(*this->ES, *ObjLinkingLayer), CtorRunner(Main), DtorRunner(Main) { ErrorAsOutParameter _(&Err); - ObjLinkingLayer = createObjectLinkingLayer(S, *ES); - if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget()) DL = std::move(*DLOrErr); else { @@ -124,7 +148,7 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) return; } CompileLayer = std::make_unique<IRCompileLayer>( - *ES, *ObjLinkingLayer, std::move(*CompileFunction)); + *ES, ObjTransformLayer, std::move(*CompileFunction)); } if (S.NumCompileThreads > 0) { diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp index 93aabd817d60..aab490feb8ea 100644 --- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp @@ -50,8 +50,10 @@ LazyCallThroughManager::callThroughToSymbol(JITTargetAddress TrampolineAddr) { SourceJD = I->second.first; SymbolName = I->second.second; } - auto LookupResult = - ES.lookup(JITDylibSearchList({{SourceJD, true}}), SymbolName); + + auto LookupResult = ES.lookup( + makeJITDylibSearchOrder(SourceJD, JITDylibLookupFlags::MatchAllSymbols), + SymbolName); if (!LookupResult) { ES.reportError(LookupResult.takeError()); diff --git a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp index 9f9a6730b2c3..67b804c37287 100644 --- a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp @@ -37,7 +37,8 @@ void JITSymbolResolverAdapter::lookup(const LookupSet &Symbols, }; auto Q = std::make_shared<AsynchronousSymbolQuery>( - InternedSymbols, SymbolState::Resolved, std::move(OnResolvedWithUnwrap)); + SymbolLookupSet(InternedSymbols), SymbolState::Resolved, + std::move(OnResolvedWithUnwrap)); auto Unresolved = R.lookup(Q, InternedSymbols); if (Unresolved.empty()) { diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index 874decb2ade0..2572b7f4878d 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -36,7 +36,7 @@ public: Layer.ReturnObjectBuffer(std::move(ObjBuffer)); } - JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; } + JITLinkMemoryManager &getMemoryManager() override { return *Layer.MemMgr; } MemoryBufferRef getObjectBuffer() const override { return ObjBuffer->getMemBufferRef(); @@ -47,18 +47,28 @@ public: MR.failMaterialization(); } - void lookup(const DenseSet<StringRef> &Symbols, + void lookup(const LookupMap &Symbols, std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override { - JITDylibSearchList SearchOrder; + JITDylibSearchOrder SearchOrder; MR.getTargetJITDylib().withSearchOrderDo( - [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; }); + [&](const JITDylibSearchOrder &O) { SearchOrder = O; }); auto &ES = Layer.getExecutionSession(); - SymbolNameSet InternedSymbols; - for (auto &S : Symbols) - InternedSymbols.insert(ES.intern(S)); + SymbolLookupSet LookupSet; + for (auto &KV : Symbols) { + orc::SymbolLookupFlags LookupFlags; + switch (KV.second) { + case jitlink::SymbolLookupFlags::RequiredSymbol: + LookupFlags = orc::SymbolLookupFlags::RequiredSymbol; + break; + case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol: + LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol; + break; + } + LookupSet.add(ES.intern(KV.first), LookupFlags); + } // OnResolve -- De-intern the symbols and pass the result to the linker. auto OnResolve = [this, LookupContinuation = std::move(LC)]( @@ -74,8 +84,9 @@ public: } }; - ES.lookup(SearchOrder, std::move(InternedSymbols), SymbolState::Resolved, - std::move(OnResolve), [this](const SymbolDependenceMap &Deps) { + ES.lookup(LookupKind::Static, SearchOrder, std::move(LookupSet), + SymbolState::Resolved, std::move(OnResolve), + [this](const SymbolDependenceMap &Deps) { registerDependencies(Deps); }); } @@ -317,9 +328,9 @@ private: ObjectLinkingLayer::Plugin::~Plugin() {} -ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES, - JITLinkMemoryManager &MemMgr) - : ObjectLayer(ES), MemMgr(MemMgr) {} +ObjectLinkingLayer::ObjectLinkingLayer( + ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr) + : ObjectLayer(ES), MemMgr(std::move(MemMgr)) {} ObjectLinkingLayer::~ObjectLinkingLayer() { if (auto Err = removeAllModules()) diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp index 815517321b76..d18eb38a4142 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp @@ -21,12 +21,18 @@ void ObjectTransformLayer::emit(MaterializationResponsibility R, std::unique_ptr<MemoryBuffer> O) { assert(O && "Module must not be null"); - if (auto TransformedObj = Transform(std::move(O))) - BaseLayer.emit(std::move(R), std::move(*TransformedObj)); - else { - R.failMaterialization(); - getExecutionSession().reportError(TransformedObj.takeError()); + // If there is a transform set then apply it. + if (Transform) { + if (auto TransformedObj = Transform(std::move(O))) + O = std::move(*TransformedObj); + else { + R.failMaterialization(); + getExecutionSession().reportError(TransformedObj.takeError()); + return; + } } + + BaseLayer.emit(std::move(R), std::move(O)); } } // End namespace orc. diff --git a/llvm/lib/ExecutionEngine/Orc/OrcError.cpp b/llvm/lib/ExecutionEngine/Orc/OrcError.cpp deleted file mode 100644 index e6e9a095319c..000000000000 --- a/llvm/lib/ExecutionEngine/Orc/OrcError.cpp +++ /dev/null @@ -1,115 +0,0 @@ -//===---------------- OrcError.cpp - Error codes for ORC ------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Error codes for ORC. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/OrcError.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" - -using namespace llvm; -using namespace llvm::orc; - -namespace { - -// FIXME: This class is only here to support the transition to llvm::Error. It -// will be removed once this transition is complete. Clients should prefer to -// deal with the Error value directly, rather than converting to error_code. -class OrcErrorCategory : public std::error_category { -public: - const char *name() const noexcept override { return "orc"; } - - std::string message(int condition) const override { - switch (static_cast<OrcErrorCode>(condition)) { - case OrcErrorCode::UnknownORCError: - return "Unknown ORC error"; - case OrcErrorCode::DuplicateDefinition: - return "Duplicate symbol definition"; - case OrcErrorCode::JITSymbolNotFound: - return "JIT symbol not found"; - case OrcErrorCode::RemoteAllocatorDoesNotExist: - return "Remote allocator does not exist"; - case OrcErrorCode::RemoteAllocatorIdAlreadyInUse: - return "Remote allocator Id already in use"; - case OrcErrorCode::RemoteMProtectAddrUnrecognized: - return "Remote mprotect call references unallocated memory"; - case OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist: - return "Remote indirect stubs owner does not exist"; - case OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse: - return "Remote indirect stubs owner Id already in use"; - case OrcErrorCode::RPCConnectionClosed: - return "RPC connection closed"; - case OrcErrorCode::RPCCouldNotNegotiateFunction: - return "Could not negotiate RPC function"; - case OrcErrorCode::RPCResponseAbandoned: - return "RPC response abandoned"; - case OrcErrorCode::UnexpectedRPCCall: - return "Unexpected RPC call"; - case OrcErrorCode::UnexpectedRPCResponse: - return "Unexpected RPC response"; - case OrcErrorCode::UnknownErrorCodeFromRemote: - return "Unknown error returned from remote RPC function " - "(Use StringError to get error message)"; - case OrcErrorCode::UnknownResourceHandle: - return "Unknown resource handle"; - } - llvm_unreachable("Unhandled error code"); - } -}; - -static ManagedStatic<OrcErrorCategory> OrcErrCat; -} - -namespace llvm { -namespace orc { - -char DuplicateDefinition::ID = 0; -char JITSymbolNotFound::ID = 0; - -std::error_code orcError(OrcErrorCode ErrCode) { - typedef std::underlying_type<OrcErrorCode>::type UT; - return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat); -} - - -DuplicateDefinition::DuplicateDefinition(std::string SymbolName) - : SymbolName(std::move(SymbolName)) {} - -std::error_code DuplicateDefinition::convertToErrorCode() const { - return orcError(OrcErrorCode::DuplicateDefinition); -} - -void DuplicateDefinition::log(raw_ostream &OS) const { - OS << "Duplicate definition of symbol '" << SymbolName << "'"; -} - -const std::string &DuplicateDefinition::getSymbolName() const { - return SymbolName; -} - -JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName) - : SymbolName(std::move(SymbolName)) {} - -std::error_code JITSymbolNotFound::convertToErrorCode() const { - typedef std::underlying_type<OrcErrorCode>::type UT; - return std::error_code(static_cast<UT>(OrcErrorCode::JITSymbolNotFound), - *OrcErrCat); -} - -void JITSymbolNotFound::log(raw_ostream &OS) const { - OS << "Could not find symbol '" << SymbolName << "'"; -} - -const std::string &JITSymbolNotFound::getSymbolName() const { - return SymbolName; -} - -} -} diff --git a/llvm/lib/ExecutionEngine/Orc/RPCUtils.cpp b/llvm/lib/ExecutionEngine/Orc/RPCUtils.cpp deleted file mode 100644 index 367b3639f841..000000000000 --- a/llvm/lib/ExecutionEngine/Orc/RPCUtils.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===--------------- RPCUtils.cpp - RPCUtils implementation ---------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// RPCUtils implementation. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/RPCUtils.h" - -char llvm::orc::rpc::RPCFatalError::ID = 0; -char llvm::orc::rpc::ConnectionClosed::ID = 0; -char llvm::orc::rpc::ResponseAbandoned::ID = 0; -char llvm::orc::rpc::CouldNotNegotiate::ID = 0; - -namespace llvm { -namespace orc { -namespace rpc { - -std::error_code ConnectionClosed::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCConnectionClosed); -} - -void ConnectionClosed::log(raw_ostream &OS) const { - OS << "RPC connection already closed"; -} - -std::error_code ResponseAbandoned::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCResponseAbandoned); -} - -void ResponseAbandoned::log(raw_ostream &OS) const { - OS << "RPC response abandoned"; -} - -CouldNotNegotiate::CouldNotNegotiate(std::string Signature) - : Signature(std::move(Signature)) {} - -std::error_code CouldNotNegotiate::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCCouldNotNegotiateFunction); -} - -void CouldNotNegotiate::log(raw_ostream &OS) const { - OS << "Could not negotiate RPC function " << Signature; -} - - -} // end namespace rpc -} // end namespace orc -} // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp index 939cd539d1fb..a92264c0be14 100644 --- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -19,11 +19,11 @@ public: void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) { auto &ES = MR.getTargetJITDylib().getExecutionSession(); - SymbolNameSet InternedSymbols; + SymbolLookupSet InternedSymbols; // Intern the requested symbols: lookup takes interned strings. for (auto &S : Symbols) - InternedSymbols.insert(ES.intern(S)); + InternedSymbols.add(ES.intern(S)); // Build an OnResolve callback to unwrap the interned strings and pass them // to the OnResolved callback. @@ -46,11 +46,12 @@ public: MR.addDependenciesForAll(Deps); }; - JITDylibSearchList SearchOrder; + JITDylibSearchOrder SearchOrder; MR.getTargetJITDylib().withSearchOrderDo( - [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; }); - ES.lookup(SearchOrder, InternedSymbols, SymbolState::Resolved, - std::move(OnResolvedWithUnwrap), RegisterDependencies); + [&](const JITDylibSearchOrder &JDs) { SearchOrder = JDs; }); + ES.lookup(LookupKind::Static, SearchOrder, InternedSymbols, + SymbolState::Resolved, std::move(OnResolvedWithUnwrap), + RegisterDependencies); } Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) { @@ -77,6 +78,12 @@ RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer( ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager) : ObjectLayer(ES), GetMemoryManager(GetMemoryManager) {} +RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { + std::lock_guard<std::mutex> Lock(RTDyldLayerMutex); + for (auto &MemMgr : MemMgrs) + MemMgr->deregisterEHFrames(); +} + void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, std::unique_ptr<MemoryBuffer> O) { assert(O && "Object must not be null"); |