#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
#include <condition_variable>
#include <future>
#include <optional>
#define DEBUG_TYPE …
namespace llvm {
namespace orc {
char ResourceTrackerDefunct::ID = …;
char FailedToMaterialize::ID = …;
char SymbolsNotFound::ID = …;
char SymbolsCouldNotBeRemoved::ID = …;
char MissingSymbolDefinitions::ID = …;
char UnexpectedSymbolDefinitions::ID = …;
char UnsatisfiedSymbolDependencies::ID = …;
char MaterializationTask::ID = …;
char LookupTask::ID = …;
RegisterDependenciesFunction NoDependenciesToRegister = …;
void MaterializationUnit::anchor() { … }
ResourceTracker::ResourceTracker(JITDylibSP JD) { … }
ResourceTracker::~ResourceTracker() { … }
Error ResourceTracker::remove() { … }
void ResourceTracker::transferTo(ResourceTracker &DstRT) { … }
void ResourceTracker::makeDefunct() { … }
ResourceManager::~ResourceManager() = default;
ResourceTrackerDefunct::ResourceTrackerDefunct(ResourceTrackerSP RT)
: … { … }
std::error_code ResourceTrackerDefunct::convertToErrorCode() const { … }
void ResourceTrackerDefunct::log(raw_ostream &OS) const { … }
FailedToMaterialize::FailedToMaterialize(
std::shared_ptr<SymbolStringPool> SSP,
std::shared_ptr<SymbolDependenceMap> Symbols)
: … { … }
FailedToMaterialize::~FailedToMaterialize() { … }
std::error_code FailedToMaterialize::convertToErrorCode() const { … }
void FailedToMaterialize::log(raw_ostream &OS) const { … }
UnsatisfiedSymbolDependencies::UnsatisfiedSymbolDependencies(
std::shared_ptr<SymbolStringPool> SSP, JITDylibSP JD,
SymbolNameSet FailedSymbols, SymbolDependenceMap BadDeps,
std::string Explanation)
: … { … }
std::error_code UnsatisfiedSymbolDependencies::convertToErrorCode() const { … }
void UnsatisfiedSymbolDependencies::log(raw_ostream &OS) const { … }
SymbolsNotFound::SymbolsNotFound(std::shared_ptr<SymbolStringPool> SSP,
SymbolNameSet Symbols)
: … { … }
SymbolsNotFound::SymbolsNotFound(std::shared_ptr<SymbolStringPool> SSP,
SymbolNameVector Symbols)
: … { … }
std::error_code SymbolsNotFound::convertToErrorCode() const { … }
void SymbolsNotFound::log(raw_ostream &OS) const { … }
SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(
std::shared_ptr<SymbolStringPool> SSP, SymbolNameSet Symbols)
: … { … }
std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const { … }
void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const { … }
std::error_code MissingSymbolDefinitions::convertToErrorCode() const { … }
void MissingSymbolDefinitions::log(raw_ostream &OS) const { … }
std::error_code UnexpectedSymbolDefinitions::convertToErrorCode() const { … }
void UnexpectedSymbolDefinitions::log(raw_ostream &OS) const { … }
AsynchronousSymbolQuery::AsynchronousSymbolQuery(
const SymbolLookupSet &Symbols, SymbolState RequiredState,
SymbolsResolvedCallback NotifyComplete)
: … { … }
void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
const SymbolStringPtr &Name, ExecutorSymbolDef Sym) { … }
void AsynchronousSymbolQuery::handleComplete(ExecutionSession &ES) { … }
void AsynchronousSymbolQuery::handleFailed(Error Err) { … }
void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
SymbolStringPtr Name) { … }
void AsynchronousSymbolQuery::removeQueryDependence(
JITDylib &JD, const SymbolStringPtr &Name) { … }
void AsynchronousSymbolQuery::dropSymbol(const SymbolStringPtr &Name) { … }
void AsynchronousSymbolQuery::detach() { … }
AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
SymbolMap Symbols)
: … { … }
StringRef AbsoluteSymbolsMaterializationUnit::getName() const { … }
void AbsoluteSymbolsMaterializationUnit::materialize(
std::unique_ptr<MaterializationResponsibility> R) { … }
void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
const SymbolStringPtr &Name) { … }
MaterializationUnit::Interface
AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) { … }
ReExportsMaterializationUnit::ReExportsMaterializationUnit(
JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
SymbolAliasMap Aliases)
: … { … }
StringRef ReExportsMaterializationUnit::getName() const { … }
void ReExportsMaterializationUnit::materialize(
std::unique_ptr<MaterializationResponsibility> R) { … }
void ReExportsMaterializationUnit::discard(const JITDylib &JD,
const SymbolStringPtr &Name) { … }
MaterializationUnit::Interface
ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) { … }
Expected<SymbolAliasMap> buildSimpleReexportsAliasMap(JITDylib &SourceJD,
SymbolNameSet Symbols) { … }
class InProgressLookupState { … };
class InProgressLookupFlagsState : public InProgressLookupState { … };
class InProgressFullLookupState : public InProgressLookupState { … };
ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
JITDylibLookupFlags SourceJDLookupFlags,
SymbolPredicate Allow)
: … { … }
Error ReexportsGenerator::tryToGenerate(LookupState &LS, LookupKind K,
JITDylib &JD,
JITDylibLookupFlags JDLookupFlags,
const SymbolLookupSet &LookupSet) { … }
LookupState::LookupState(std::unique_ptr<InProgressLookupState> IPLS)
: … { … }
void LookupState::reset(InProgressLookupState *IPLS) { … }
LookupState::LookupState() = default;
LookupState::LookupState(LookupState &&) = default;
LookupState &LookupState::operator=(LookupState &&) = default;
LookupState::~LookupState() = default;
void LookupState::continueLookup(Error Err) { … }
DefinitionGenerator::~DefinitionGenerator() { … }
JITDylib::~JITDylib() { … }
Error JITDylib::clear() { … }
ResourceTrackerSP JITDylib::getDefaultResourceTracker() { … }
ResourceTrackerSP JITDylib::createResourceTracker() { … }
void JITDylib::removeGenerator(DefinitionGenerator &G) { … }
Expected<SymbolFlagsMap>
JITDylib::defineMaterializing(MaterializationResponsibility &FromMR,
SymbolFlagsMap SymbolFlags) { … }
Error JITDylib::replace(MaterializationResponsibility &FromMR,
std::unique_ptr<MaterializationUnit> MU) { … }
Expected<std::unique_ptr<MaterializationResponsibility>>
JITDylib::delegate(MaterializationResponsibility &FromMR,
SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol) { … }
SymbolNameSet
JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const { … }
Error JITDylib::resolve(MaterializationResponsibility &MR,
const SymbolMap &Resolved) { … }
void JITDylib::unlinkMaterializationResponsibility(
MaterializationResponsibility &MR) { … }
void JITDylib::shrinkMaterializationInfoMemory() { … }
void JITDylib::setLinkOrder(JITDylibSearchOrder NewLinkOrder,
bool LinkAgainstThisJITDylibFirst) { … }
void JITDylib::addToLinkOrder(const JITDylibSearchOrder &NewLinks) { … }
void JITDylib::addToLinkOrder(JITDylib &JD, JITDylibLookupFlags JDLookupFlags) { … }
void JITDylib::replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
JITDylibLookupFlags JDLookupFlags) { … }
void JITDylib::removeFromLinkOrder(JITDylib &JD) { … }
Error JITDylib::remove(const SymbolNameSet &Names) { … }
void JITDylib::dump(raw_ostream &OS) { … }
void JITDylib::MaterializingInfo::addQuery(
std::shared_ptr<AsynchronousSymbolQuery> Q) { … }
void JITDylib::MaterializingInfo::removeQuery(
const AsynchronousSymbolQuery &Q) { … }
JITDylib::AsynchronousSymbolQueryList
JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) { … }
JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
: … { … }
std::pair<JITDylib::AsynchronousSymbolQuerySet,
std::shared_ptr<SymbolDependenceMap>>
JITDylib::IL_removeTracker(ResourceTracker &RT) { … }
void JITDylib::transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT) { … }
Error JITDylib::defineImpl(MaterializationUnit &MU) { … }
void JITDylib::installMaterializationUnit(
std::unique_ptr<MaterializationUnit> MU, ResourceTracker &RT) { … }
void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
const SymbolNameSet &QuerySymbols) { … }
Platform::~Platform() = default;
Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
ExecutionSession &ES,
const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) { … }
void Platform::lookupInitSymbolsAsync(
unique_function<void(Error)> OnComplete, ExecutionSession &ES,
const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) { … }
void MaterializationTask::printDescription(raw_ostream &OS) { … }
void MaterializationTask::run() { … }
void LookupTask::printDescription(raw_ostream &OS) { … }
void LookupTask::run() { … }
ExecutionSession::ExecutionSession(std::unique_ptr<ExecutorProcessControl> EPC)
: … { … }
ExecutionSession::~ExecutionSession() { … }
Error ExecutionSession::endSession() { … }
void ExecutionSession::registerResourceManager(ResourceManager &RM) { … }
void ExecutionSession::deregisterResourceManager(ResourceManager &RM) { … }
JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) { … }
JITDylib &ExecutionSession::createBareJITDylib(std::string Name) { … }
Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) { … }
Error ExecutionSession::removeJITDylibs(std::vector<JITDylibSP> JDsToRemove) { … }
Expected<std::vector<JITDylibSP>>
JITDylib::getDFSLinkOrder(ArrayRef<JITDylibSP> JDs) { … }
Expected<std::vector<JITDylibSP>>
JITDylib::getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs) { … }
Expected<std::vector<JITDylibSP>> JITDylib::getDFSLinkOrder() { … }
Expected<std::vector<JITDylibSP>> JITDylib::getReverseDFSLinkOrder() { … }
void ExecutionSession::lookupFlags(
LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet,
unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) { … }
Expected<SymbolFlagsMap>
ExecutionSession::lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
SymbolLookupSet LookupSet) { … }
void ExecutionSession::lookup(
LookupKind K, const JITDylibSearchOrder &SearchOrder,
SymbolLookupSet Symbols, SymbolState RequiredState,
SymbolsResolvedCallback NotifyComplete,
RegisterDependenciesFunction RegisterDependencies) { … }
Expected<SymbolMap>
ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
SymbolLookupSet Symbols, LookupKind K,
SymbolState RequiredState,
RegisterDependenciesFunction RegisterDependencies) { … }
Expected<ExecutorSymbolDef>
ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
SymbolStringPtr Name, SymbolState RequiredState) { … }
Expected<ExecutorSymbolDef>
ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,
SymbolState RequiredState) { … }
Expected<ExecutorSymbolDef>
ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,
SymbolState RequiredState) { … }
Error ExecutionSession::registerJITDispatchHandlers(
JITDylib &JD, JITDispatchHandlerAssociationMap WFs) { … }
void ExecutionSession::runJITDispatchHandler(SendResultFunction SendResult,
ExecutorAddr HandlerFnTagAddr,
ArrayRef<char> ArgBuffer) { … }
void ExecutionSession::dump(raw_ostream &OS) { … }
#ifdef EXPENSIVE_CHECKS
bool ExecutionSession::verifySessionState(Twine Phase) {
return runSessionLocked([&]() {
bool AllOk = true;
DenseSet<JITDylib::EmissionDepUnit *> EDUsToCheck;
for (auto &JD : JDs) {
auto LogFailure = [&]() -> raw_fd_ostream & {
auto &Stream = errs();
if (AllOk)
Stream << "ERROR: Bad ExecutionSession state detected " << Phase
<< "\n";
Stream << " In JITDylib " << JD->getName() << ", ";
AllOk = false;
return Stream;
};
if (JD->State != JITDylib::Open) {
LogFailure()
<< "state is not Open, but JD is in ExecutionSession list.";
}
for (auto &[Sym, Entry] : JD->Symbols) {
if (Entry.getState() < SymbolState::Resolved) {
if (Entry.getAddress()) {
LogFailure() << "symbol " << Sym << " has state "
<< Entry.getState()
<< " (not-yet-resolved) but non-null address "
<< Entry.getAddress() << ".\n";
}
}
auto UMIItr = JD->UnmaterializedInfos.find(Sym);
if (Entry.hasMaterializerAttached()) {
if (UMIItr == JD->UnmaterializedInfos.end()) {
LogFailure() << "symbol " << Sym
<< " entry claims materializer attached, but "
"UnmaterializedInfos has no corresponding entry.\n";
}
} else if (UMIItr != JD->UnmaterializedInfos.end()) {
LogFailure()
<< "symbol " << Sym
<< " entry claims no materializer attached, but "
"UnmaterializedInfos has an unexpected entry for it.\n";
}
}
for (auto &[Sym, UMI] : JD->UnmaterializedInfos) {
auto SymItr = JD->Symbols.find(Sym);
if (SymItr == JD->Symbols.end()) {
LogFailure()
<< "symbol " << Sym
<< " has UnmaterializedInfos entry, but no Symbols entry.\n";
}
}
for (auto &[Sym, MII] : JD->MaterializingInfos) {
auto SymItr = JD->Symbols.find(Sym);
if (SymItr == JD->Symbols.end()) {
LogFailure()
<< "symbol " << Sym
<< " has MaterializingInfos entry, but no Symbols entry.\n";
} else {
if (SymItr->second.getState() == SymbolState::Ready) {
LogFailure()
<< "symbol " << Sym
<< " is in Ready state, should not have MaterializingInfo.\n";
}
auto CurState = static_cast<SymbolState>(
static_cast<std::underlying_type_t<SymbolState>>(
SymItr->second.getState()) + 1);
for (auto &Q : MII.PendingQueries) {
if (Q->getRequiredState() != CurState) {
if (Q->getRequiredState() > CurState)
CurState = Q->getRequiredState();
else
LogFailure() << "symbol " << Sym
<< " has stale or misordered queries.\n";
}
}
if (MII.DefiningEDU) {
EDUsToCheck.insert(MII.DefiningEDU.get());
if (MII.DefiningEDU->JD != JD.get()) {
LogFailure() << "symbol " << Sym
<< " has DefiningEDU with incorrect JD"
<< (llvm::is_contained(JDs, MII.DefiningEDU->JD)
? " (JD not currently in ExecutionSession"
: "")
<< "\n";
}
if (SymItr->second.getState() != SymbolState::Emitted) {
LogFailure()
<< "symbol " << Sym
<< " has DefiningEDU, but is not in Emitted state.\n";
}
}
for (auto &DepEDU : MII.DependantEDUs) {
if (!llvm::is_contained(JDs, DepEDU->JD)) {
LogFailure() << "symbol " << Sym << " has DependantEDU "
<< (void *)DepEDU << " with JD (" << DepEDU->JD
<< ") that isn't in ExecutionSession.\n";
}
}
}
}
}
for (auto *EDU : EDUsToCheck) {
assert(EDU->JD->State == JITDylib::Open && "EDU->JD is not Open");
auto LogFailure = [&]() -> raw_fd_ostream & {
AllOk = false;
auto &Stream = errs();
Stream << "In EDU defining " << EDU->JD->getName() << ": { ";
for (auto &[Sym, Flags] : EDU->Symbols)
Stream << Sym << " ";
Stream << "}, ";
return Stream;
};
if (EDU->Symbols.empty())
LogFailure() << "no symbols defined.\n";
else {
for (auto &[Sym, Flags] : EDU->Symbols) {
if (!Sym)
LogFailure() << "null symbol defined.\n";
else {
if (!EDU->JD->Symbols.count(SymbolStringPtr(Sym))) {
LogFailure() << "symbol " << Sym
<< " isn't present in JD's symbol table.\n";
}
}
}
}
for (auto &[DepJD, Symbols] : EDU->Dependencies) {
if (!llvm::is_contained(JDs, DepJD)) {
LogFailure() << "dependant symbols listed for JD that isn't in "
"ExecutionSession.\n";
} else {
for (auto &DepSym : Symbols) {
if (!DepJD->Symbols.count(SymbolStringPtr(DepSym))) {
LogFailure()
<< "dependant symbol " << DepSym
<< " does not appear in symbol table for dependant JD "
<< DepJD->getName() << ".\n";
}
}
}
}
}
return AllOk;
});
}
#endif
void ExecutionSession::dispatchOutstandingMUs() { … }
Error ExecutionSession::removeResourceTracker(ResourceTracker &RT) { … }
void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT,
ResourceTracker &SrcRT) { … }
void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) { … }
Error ExecutionSession::IL_updateCandidatesFor(
JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
SymbolLookupSet &Candidates, SymbolLookupSet *NonCandidates) { … }
void ExecutionSession::OL_resumeLookupAfterGeneration(
InProgressLookupState &IPLS) { … }
void ExecutionSession::OL_applyQueryPhase1(
std::unique_ptr<InProgressLookupState> IPLS, Error Err) { … }
void ExecutionSession::OL_completeLookup(
std::unique_ptr<InProgressLookupState> IPLS,
std::shared_ptr<AsynchronousSymbolQuery> Q,
RegisterDependenciesFunction RegisterDependencies) { … }
void ExecutionSession::OL_completeLookupFlags(
std::unique_ptr<InProgressLookupState> IPLS,
unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) { … }
void ExecutionSession::OL_destroyMaterializationResponsibility(
MaterializationResponsibility &MR) { … }
SymbolNameSet ExecutionSession::OL_getRequestedSymbols(
const MaterializationResponsibility &MR) { … }
Error ExecutionSession::OL_notifyResolved(MaterializationResponsibility &MR,
const SymbolMap &Symbols) { … }
template <typename HandleNewDepFn>
void ExecutionSession::propagateExtraEmitDeps(
std::deque<JITDylib::EmissionDepUnit *> Worklist, EDUInfosMap &EDUInfos,
HandleNewDepFn HandleNewDep) { … }
ExecutionSession::EDUInfosMap ExecutionSession::simplifyDepGroups(
MaterializationResponsibility &MR,
ArrayRef<SymbolDependenceGroup> EmittedDeps) { … }
void ExecutionSession::IL_makeEDUReady(
std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
JITDylib::AsynchronousSymbolQuerySet &Queries) { … }
void ExecutionSession::IL_makeEDUEmitted(
std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
JITDylib::AsynchronousSymbolQuerySet &Queries) { … }
bool ExecutionSession::IL_removeEDUDependence(JITDylib::EmissionDepUnit &EDU,
JITDylib &DepJD,
NonOwningSymbolStringPtr DepSym,
EDUInfosMap &EDUInfos) { … }
Error ExecutionSession::makeJDClosedError(JITDylib::EmissionDepUnit &EDU,
JITDylib &ClosedJD) { … }
Error ExecutionSession::makeUnsatisfiedDepsError(JITDylib::EmissionDepUnit &EDU,
JITDylib &BadJD,
SymbolNameSet BadDeps) { … }
Expected<JITDylib::AsynchronousSymbolQuerySet>
ExecutionSession::IL_emit(MaterializationResponsibility &MR,
EDUInfosMap EDUInfos) { … }
Error ExecutionSession::OL_notifyEmitted(
MaterializationResponsibility &MR,
ArrayRef<SymbolDependenceGroup> DepGroups) { … }
Error ExecutionSession::OL_defineMaterializing(
MaterializationResponsibility &MR, SymbolFlagsMap NewSymbolFlags) { … }
std::pair<JITDylib::AsynchronousSymbolQuerySet,
std::shared_ptr<SymbolDependenceMap>>
ExecutionSession::IL_failSymbols(JITDylib &JD,
const SymbolNameVector &SymbolsToFail) { … }
void ExecutionSession::OL_notifyFailed(MaterializationResponsibility &MR) { … }
Error ExecutionSession::OL_replace(MaterializationResponsibility &MR,
std::unique_ptr<MaterializationUnit> MU) { … }
Expected<std::unique_ptr<MaterializationResponsibility>>
ExecutionSession::OL_delegate(MaterializationResponsibility &MR,
const SymbolNameSet &Symbols) { … }
#ifndef NDEBUG
void ExecutionSession::dumpDispatchInfo(Task &T) {
runSessionLocked([&]() {
dbgs() << "Dispatching: ";
T.printDescription(dbgs());
dbgs() << "\n";
});
}
#endif
}
}