[llvm] r337608 - Revert r337595 "[ORC] Add new symbol lookup methods to ExecutionSessionBase in preparation for"
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 20 13:20:45 PDT 2018
Author: rnk
Date: Fri Jul 20 13:20:45 2018
New Revision: 337608
URL: http://llvm.org/viewvc/llvm-project?rev=337608&view=rev
Log:
Revert r337595 "[ORC] Add new symbol lookup methods to ExecutionSessionBase in preparation for"
Breaks the build with LLVM_ENABLE_THREADS=OFF.
Modified:
llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h
llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp
llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h Fri Jul 20 13:20:45 2018
@@ -69,23 +69,8 @@ raw_ostream &operator<<(raw_ostream &OS,
/// A list of VSO pointers.
using VSOList = std::vector<VSO *>;
-/// Render a VSOList.
raw_ostream &operator<<(raw_ostream &OS, const VSOList &VSOs);
-/// Callback to notify client that symbols have been resolved.
-using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
-
-/// Callback to notify client that symbols are ready for execution.
-using SymbolsReadyCallback = std::function<void(Error)>;
-
-/// Callback to register the dependencies for a given query.
-using RegisterDependenciesFunction =
- std::function<void(const SymbolDependenceMap &)>;
-
-/// This can be used as the value for a RegisterDependenciesFunction if there
-/// are no dependants to register with.
-extern RegisterDependenciesFunction NoDependenciesToRegister;
-
/// Used to notify a VSO that the given set of symbols failed to materialize.
class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
public:
@@ -137,9 +122,6 @@ public:
/// into.
VSO &getTargetVSO() const { return V; }
- /// Returns the symbol flags map for this responsibility instance.
- SymbolFlagsMap getSymbols() { return SymbolFlags; }
-
/// Returns the names of any symbols covered by this
/// MaterializationResponsibility object that have queries pending. This
/// information can be used to return responsibility for unrequested symbols
@@ -241,9 +223,6 @@ private:
virtual void discard(const VSO &V, SymbolStringPtr Name) = 0;
};
-using MaterializationUnitList =
- std::vector<std::unique_ptr<MaterializationUnit>>;
-
/// A MaterializationUnit implementation for pre-existing absolute symbols.
///
/// All symbols will be resolved and marked ready as soon as the unit is
@@ -343,9 +322,6 @@ buildSimpleReexportsAliasMap(VSO &Source
/// Base utilities for ExecutionSession.
class ExecutionSessionBase {
- // FIXME: Remove this when we remove the old ORC layers.
- friend class VSO;
-
public:
/// For reporting errors.
using ErrorReporter = std::function<void(Error)>;
@@ -396,50 +372,11 @@ public:
void releaseVModule(VModuleKey Key) { /* FIXME: Recycle keys */
}
- void legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err);
-
- using LegacyAsyncLookupFunction = std::function<SymbolNameSet(
- std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names)>;
-
- /// A legacy lookup function for JITSymbolResolverAdapter.
- /// Do not use -- this will be removed soon.
- Expected<SymbolMap>
- legacyLookup(ExecutionSessionBase &ES, LegacyAsyncLookupFunction AsyncLookup,
- SymbolNameSet Names, bool WaiUntilReady,
- RegisterDependenciesFunction RegisterDependencies);
-
- /// Search the given VSO list for the given symbols.
- ///
- ///
- /// The OnResolve callback will be called once all requested symbols are
- /// resolved, or if an error occurs prior to resolution.
- ///
- /// The OnReady callback will be called once all requested symbols are ready,
- /// or if an error occurs after resolution but before all symbols are ready.
- ///
- /// If all symbols are found, the RegisterDependencies function will be called
- /// while the session lock is held. This gives clients a chance to register
- /// dependencies for on the queried symbols for any symbols they are
- /// materializing (if a MaterializationResponsibility instance is present,
- /// this can be implemented by calling
- /// MaterializationResponsibility::addDependencies). If there are no
- /// dependenant symbols for this query (e.g. it is being made by a top level
- /// client to get an address to call) then the value NoDependenciesToRegister
- /// can be used.
- void lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
- SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
- RegisterDependenciesFunction RegisterDependencies);
-
- /// Blocking version of lookup above. Returns the resolved symbol map.
- /// If WaitUntilReady is true (the default), will not return until all
- /// requested symbols are ready (or an error occurs). If WaitUntilReady is
- /// false, will return as soon as all requested symbols are resolved,
- /// or an error occurs. If WaitUntilReady is false and an error occurs
- /// after resolution, the function will return a success value, but the
- /// error will be reported via reportErrors.
- Expected<SymbolMap> lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
- RegisterDependenciesFunction RegisterDependencies,
- bool WaitUntilReady = true);
+ /// Cause the given query to fail with the given Error.
+ ///
+ /// This should only be used by legacy APIs and will be deprecated in the
+ /// future.
+ void failQuery(AsynchronousSymbolQuery &Q, Error Err);
/// Materialize the given unit.
void dispatchMaterialization(VSO &V,
@@ -457,20 +394,12 @@ private:
MU->doMaterialize(V);
}
- void runOutstandingMUs();
-
mutable std::recursive_mutex SessionMutex;
std::shared_ptr<SymbolStringPool> SSP;
VModuleKey LastKey = 0;
ErrorReporter ReportError = logErrorsToStdErr;
DispatchMaterializationFunction DispatchMaterialization =
materializeOnCurrentThread;
-
- // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
- // with callbacks from asynchronous queries.
- mutable std::recursive_mutex OutstandingMUsMutex;
- std::vector<std::pair<VSO *, std::unique_ptr<MaterializationUnit>>>
- OutstandingMUs;
};
/// A symbol query that returns results via a callback when results are
@@ -482,6 +411,21 @@ class AsynchronousSymbolQuery {
friend class VSO;
public:
+ class ResolutionResult {
+ public:
+ ResolutionResult(SymbolMap Symbols, const SymbolDependenceMap &Dependencies)
+ : Symbols(std::move(Symbols)), Dependencies(Dependencies) {}
+
+ SymbolMap Symbols;
+ const SymbolDependenceMap &Dependencies;
+ };
+
+ /// Callback to notify client that symbols have been resolved.
+ using SymbolsResolvedCallback =
+ std::function<void(Expected<ResolutionResult>)>;
+
+ /// Callback to notify client that symbols are ready for execution.
+ using SymbolsReadyCallback = std::function<void(Error)>;
/// Create a query for the given symbols, notify-resolved and
/// notify-ready callbacks.
@@ -541,7 +485,6 @@ private:
class VSO {
friend class AsynchronousSymbolQuery;
friend class ExecutionSession;
- friend class ExecutionSessionBase;
friend class MaterializationResponsibility;
public:
using FallbackDefinitionGeneratorFunction =
@@ -550,6 +493,9 @@ public:
using AsynchronousSymbolQuerySet =
std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
+ using MaterializationUnitList =
+ std::vector<std::unique_ptr<MaterializationUnit>>;
+
VSO(const VSO &) = delete;
VSO &operator=(const VSO &) = delete;
VSO(VSO &&) = delete;
@@ -601,10 +547,8 @@ public:
void removeFromSearchOrder(VSO &V);
/// Do something with the search order (run under the session lock).
- template <typename Func>
- auto withSearchOrderDo(Func &&F)
- -> decltype(F(std::declval<const VSOList &>())) {
- return ES.runSessionLocked([&]() { return F(SearchOrder); });
+ template <typename Func> void withSearchOrderDo(Func F) {
+ ES.runSessionLocked([&]() { F(SearchOrder); });
}
/// Define all symbols provided by the materialization unit to be part
@@ -635,10 +579,6 @@ public:
/// the flags for each symbol in Flags. Returns any unresolved symbols.
SymbolFlagsMap lookupFlags(const SymbolNameSet &Names);
- /// Dump current VSO state to OS.
- void dump(raw_ostream &OS);
-
- /// FIXME: Remove this when we remove the old ORC layers.
/// Search the given VSOs in order for the symbols in Symbols. Results
/// (once they become available) will be returned via the given Query.
///
@@ -646,8 +586,11 @@ public:
/// and the query will not be applied. The Query is not failed and can be
/// re-used in a subsequent lookup once the symbols have been added, or
/// manually failed.
- SymbolNameSet legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
- SymbolNameSet Names);
+ SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
+ SymbolNameSet Names);
+
+ /// Dump current VSO state to OS.
+ void dump(raw_ostream &OS);
private:
using AsynchronousSymbolQueryList =
@@ -686,12 +629,6 @@ private:
SymbolNameSet lookupFlagsImpl(SymbolFlagsMap &Flags,
const SymbolNameSet &Names);
- void lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved, MaterializationUnitList &MUs);
-
- void lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved, MaterializationUnitList &MUs);
-
LookupImplActionFlags
lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
@@ -710,8 +647,8 @@ private:
SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags);
- void addDependencies(const SymbolStringPtr &Name,
- const SymbolDependenceMap &Dependants);
+ void addDependencies(const SymbolFlagsMap &Dependents,
+ const SymbolDependenceMap &Dependencies);
void resolve(const SymbolMap &Resolved);
@@ -719,6 +656,8 @@ private:
void notifyFailed(const SymbolNameSet &FailedSymbols);
+ void runOutstandingMUs();
+
ExecutionSessionBase &ES;
std::string VSOName;
SymbolMap Symbols;
@@ -726,6 +665,11 @@ private:
MaterializingInfosMap MaterializingInfos;
FallbackDefinitionGeneratorFunction FallbackDefinitionGenerator;
VSOList SearchOrder;
+
+ // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
+ // with callbacks from asynchronous queries.
+ mutable std::recursive_mutex OutstandingMUsMutex;
+ std::vector<std::unique_ptr<MaterializationUnit>> OutstandingMUs;
};
/// An ExecutionSession represents a running JIT program.
@@ -749,6 +693,15 @@ private:
std::vector<std::unique_ptr<VSO>> VSOs;
};
+using AsynchronousLookupFunction = std::function<SymbolNameSet(
+ std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names)>;
+
+/// Perform a blocking lookup on the given symbols.
+Expected<SymbolMap> blockingLookup(ExecutionSessionBase &ES,
+ AsynchronousLookupFunction AsyncLookup,
+ SymbolNameSet Names, bool WaiUntilReady,
+ MaterializationResponsibility *MR = nullptr);
+
/// Look up the given names in the given VSOs.
/// VSOs will be searched in order and no VSO pointer may be null.
/// All symbols must be found within the given VSOs or an error
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h Fri Jul 20 13:20:45 2018
@@ -146,11 +146,11 @@ lookupWithLegacyFn(ExecutionSession &ES,
Query.notifySymbolReady();
NewSymbolsResolved = true;
} else {
- ES.legacyFailQuery(Query, Addr.takeError());
+ ES.failQuery(Query, Addr.takeError());
return SymbolNameSet();
}
} else if (auto Err = Sym.takeError()) {
- ES.legacyFailQuery(Query, std::move(Err));
+ ES.failQuery(Query, std::move(Err));
return SymbolNameSet();
} else
SymbolsNotFound.insert(S);
Modified: llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp Fri Jul 20 13:20:45 2018
@@ -23,9 +23,6 @@ namespace orc {
char FailedToMaterialize::ID = 0;
char SymbolsNotFound::ID = 0;
-RegisterDependenciesFunction NoDependenciesToRegister =
- RegisterDependenciesFunction();
-
void MaterializationUnit::anchor() {}
raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
@@ -141,359 +138,18 @@ void SymbolsNotFound::log(raw_ostream &O
OS << "Symbols not found: " << Symbols;
}
-void ExecutionSessionBase::legacyFailQuery(AsynchronousSymbolQuery &Q,
- Error Err) {
- assert(!!Err && "Error should be in failure state");
-
- bool SendErrorToQuery;
- runSessionLocked([&]() {
+void ExecutionSessionBase::failQuery(AsynchronousSymbolQuery &Q, Error Err) {
+ bool DeliveredError = true;
+ runSessionLocked([&]() -> void {
Q.detach();
- SendErrorToQuery = Q.canStillFail();
- });
-
- if (SendErrorToQuery)
- Q.handleFailed(std::move(Err));
- else
- reportError(std::move(Err));
-}
-
-Expected<SymbolMap> ExecutionSessionBase::legacyLookup(
- ExecutionSessionBase &ES, LegacyAsyncLookupFunction AsyncLookup,
- SymbolNameSet Names, bool WaitUntilReady,
- RegisterDependenciesFunction RegisterDependencies) {
-#if LLVM_ENABLE_THREADS
- // In the threaded case we use promises to return the results.
- std::promise<SymbolMap> PromisedResult;
- std::mutex ErrMutex;
- Error ResolutionError = Error::success();
- std::promise<void> PromisedReady;
- Error ReadyError = Error::success();
- auto OnResolve = [&](Expected<SymbolMap> R) {
- if (R)
- PromisedResult.set_value(std::move(*R));
- else {
- {
- ErrorAsOutParameter _(&ResolutionError);
- std::lock_guard<std::mutex> Lock(ErrMutex);
- ResolutionError = R.takeError();
- }
- PromisedResult.set_value(SymbolMap());
- }
- };
-
- std::function<void(Error)> OnReady;
- if (WaitUntilReady) {
- OnReady = [&](Error Err) {
- if (Err) {
- ErrorAsOutParameter _(&ReadyError);
- std::lock_guard<std::mutex> Lock(ErrMutex);
- ReadyError = std::move(Err);
- }
- PromisedReady.set_value();
- };
- } else {
- OnReady = [&](Error Err) {
- if (Err)
- ES.reportError(std::move(Err));
- };
- }
-
-#else
- SymbolMap Result;
- Error ResolutionError = Error::success();
- Error ReadyError = Error::success();
-
- auto OnResolve = [&](Expected<SymbolMap> R) {
- ErrorAsOutParameter _(&ResolutionError);
- if (R)
- Result = std::move(*R);
+ if (Q.canStillFail())
+ Q.handleFailed(std::move(Err));
else
- ResolutionError = R.takeError();
- };
-
- std::function<void(Error)> OnReady;
- if (WaitUntilReady) {
- OnReady = [&](Error Err) {
- ErrorAsOutParameter _(&ReadyError);
- if (Err)
- ReadyError = std::move(Err);
- };
- } else {
- OnReady = [&](Error Err) {
- if (Err)
- ES.reportError(std::move(Err));
- };
- }
-#endif
-
- auto Query = std::make_shared<AsynchronousSymbolQuery>(
- Names, std::move(OnResolve), std::move(OnReady));
- // FIXME: This should be run session locked along with the registration code
- // and error reporting below.
- SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
-
- // If the query was lodged successfully then register the dependencies,
- // otherwise fail it with an error.
- if (UnresolvedSymbols.empty())
- RegisterDependencies(Query->QueryRegistrations);
- else {
- bool DeliverError = runSessionLocked([&]() {
- Query->detach();
- return Query->canStillFail();
- });
- auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols));
- if (DeliverError)
- Query->handleFailed(std::move(Err));
- else
- ES.reportError(std::move(Err));
- }
-
-#if LLVM_ENABLE_THREADS
- auto ResultFuture = PromisedResult.get_future();
- auto Result = ResultFuture.get();
-
- {
- std::lock_guard<std::mutex> Lock(ErrMutex);
- if (ResolutionError) {
- // ReadyError will never be assigned. Consume the success value.
- cantFail(std::move(ReadyError));
- return std::move(ResolutionError);
- }
- }
-
- if (WaitUntilReady) {
- auto ReadyFuture = PromisedReady.get_future();
- ReadyFuture.get();
-
- {
- std::lock_guard<std::mutex> Lock(ErrMutex);
- if (ReadyError)
- return std::move(ReadyError);
- }
- } else
- cantFail(std::move(ReadyError));
-
- return std::move(Result);
-
-#else
- if (ResolutionError) {
- // ReadyError will never be assigned. Consume the success value.
- cantFail(std::move(ReadyError));
- return std::move(ResolutionError);
- }
-
- if (ReadyError)
- return std::move(ReadyError);
-
- return Result;
-#endif
-}
-
-void ExecutionSessionBase::lookup(
- const VSOList &VSOs, const SymbolNameSet &Symbols,
- SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
- RegisterDependenciesFunction RegisterDependencies) {
-
- // lookup can be re-entered recursively if running on a single thread. Run any
- // outstanding MUs in case this query depends on them, otherwise the main
- // thread will starve waiting for a result from an MU that it failed to run.
- runOutstandingMUs();
-
- auto Unresolved = std::move(Symbols);
- std::map<VSO *, MaterializationUnitList> MUsMap;
- auto Q = std::make_shared<AsynchronousSymbolQuery>(
- Symbols, std::move(OnResolve), std::move(OnReady));
- bool QueryIsFullyResolved = false;
- bool QueryIsFullyReady = false;
- bool QueryFailed = false;
-
- runSessionLocked([&]() {
- for (auto *V : VSOs) {
- assert(V && "VSOList entries must not be null");
- assert(!MUsMap.count(V) &&
- "VSOList should not contain duplicate entries");
- V->lodgeQuery(Q, Unresolved, MUsMap[V]);
- }
-
- if (Unresolved.empty()) {
- // Query lodged successfully.
-
- // Record whether this query is fully ready / resolved. We will use
- // this to call handleFullyResolved/handleFullyReady outside the session
- // lock.
- QueryIsFullyResolved = Q->isFullyResolved();
- QueryIsFullyReady = Q->isFullyReady();
-
- // Call the register dependencies function.
- if (RegisterDependencies && !Q->QueryRegistrations.empty())
- RegisterDependencies(Q->QueryRegistrations);
- } else {
- // Query failed due to unresolved symbols.
- QueryFailed = true;
-
- // Disconnect the query from its dependencies.
- Q->detach();
-
- // Replace the MUs.
- for (auto &KV : MUsMap)
- for (auto &MU : KV.second)
- KV.first->replace(std::move(MU));
- }
+ DeliveredError = false;
});
- if (QueryFailed) {
- Q->handleFailed(make_error<SymbolsNotFound>(std::move(Unresolved)));
- return;
- } else {
- if (QueryIsFullyResolved)
- Q->handleFullyResolved();
- if (QueryIsFullyReady)
- Q->handleFullyReady();
- }
-
- // Move the MUs to the OutstandingMUs list, then materialize.
- {
- std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
-
- for (auto &KV : MUsMap)
- for (auto &MU : KV.second)
- OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU)));
- }
-
- runOutstandingMUs();
-}
-
-Expected<SymbolMap>
-ExecutionSessionBase::lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
- RegisterDependenciesFunction RegisterDependencies,
- bool WaitUntilReady) {
-#if LLVM_ENABLE_THREADS
- // In the threaded case we use promises to return the results.
- std::promise<SymbolMap> PromisedResult;
- std::mutex ErrMutex;
- Error ResolutionError = Error::success();
- std::promise<void> PromisedReady;
- Error ReadyError = Error::success();
- auto OnResolve = [&](Expected<SymbolMap> R) {
- if (R)
- PromisedResult.set_value(std::move(*R));
- else {
- {
- ErrorAsOutParameter _(&ResolutionError);
- std::lock_guard<std::mutex> Lock(ErrMutex);
- ResolutionError = R.takeError();
- }
- PromisedResult.set_value(SymbolMap());
- }
- };
-
- std::function<void(Error)> OnReady;
- if (WaitUntilReady) {
- OnReady = [&](Error Err) {
- if (Err) {
- ErrorAsOutParameter _(&ReadyError);
- std::lock_guard<std::mutex> Lock(ErrMutex);
- ReadyError = std::move(Err);
- }
- PromisedReady.set_value();
- };
- } else {
- OnReady = [&](Error Err) {
- if (Err)
- reportError(std::move(Err));
- };
- }
-
-#else
- SymbolMap Result;
- Error ResolutionError = Error::success();
- Error ReadyError = Error::success();
-
- auto OnResolve = [&](Expected<SymbolMap> R) {
- ErrorAsOutParameter _(&ResolutionError);
- if (R)
- Result = std::move(R->Symbols);
- else
- ResolutionError = R.takeError();
- };
-
- std::function<void(Error)> OnReady;
- if (WaitUntilReady) {
- OnReady = [&](Error Err) {
- ErrorAsOutParameter _(&ReadyError);
- if (Err)
- ReadyError = std::move(Err);
- };
- } else {
- OnReady = [&](Error Err) {
- if (Err)
- reportError(std::move(Err));
- };
- }
-#endif
-
- // Perform the asynchronous lookup.
- lookup(VSOs, Symbols, OnResolve, OnReady, RegisterDependencies);
-
-#if LLVM_ENABLE_THREADS
- auto ResultFuture = PromisedResult.get_future();
- auto Result = ResultFuture.get();
-
- {
- std::lock_guard<std::mutex> Lock(ErrMutex);
- if (ResolutionError) {
- // ReadyError will never be assigned. Consume the success value.
- cantFail(std::move(ReadyError));
- return std::move(ResolutionError);
- }
- }
-
- if (WaitUntilReady) {
- auto ReadyFuture = PromisedReady.get_future();
- ReadyFuture.get();
-
- {
- std::lock_guard<std::mutex> Lock(ErrMutex);
- if (ReadyError)
- return std::move(ReadyError);
- }
- } else
- cantFail(std::move(ReadyError));
-
- return std::move(Result);
-
-#else
- if (ResolutionError) {
- // ReadyError will never be assigned. Consume the success value.
- cantFail(std::move(ReadyError));
- return std::move(ResolutionError);
- }
-
- if (ReadyError)
- return std::move(ReadyError);
-
- return Result;
-#endif
-}
-
-void ExecutionSessionBase::runOutstandingMUs() {
- while (1) {
- std::pair<VSO *, std::unique_ptr<MaterializationUnit>> VSOAndMU;
-
- {
- std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
- if (!OutstandingMUs.empty()) {
- VSOAndMU = std::move(OutstandingMUs.back());
- OutstandingMUs.pop_back();
- }
- }
-
- if (VSOAndMU.first) {
- assert(VSOAndMU.second && "VSO, but no MU?");
- dispatchMaterialization(*VSOAndMU.first, std::move(VSOAndMU.second));
- } else
- break;
- }
+ if (!DeliveredError)
+ reportError(std::move(Err));
}
AsynchronousSymbolQuery::AsynchronousSymbolQuery(
@@ -505,6 +161,12 @@ AsynchronousSymbolQuery::AsynchronousSym
for (auto &S : Symbols)
ResolvedSymbols[S] = nullptr;
+
+ // If the query is empty it is trivially resolved/ready.
+ if (Symbols.empty()) {
+ handleFullyResolved();
+ handleFullyReady();
+ }
}
void AsynchronousSymbolQuery::resolve(const SymbolStringPtr &Name,
@@ -521,7 +183,8 @@ void AsynchronousSymbolQuery::handleFull
assert(NotYetResolvedCount == 0 && "Not fully resolved?");
assert(NotifySymbolsResolved &&
"NotifySymbolsResolved already called or error occurred");
- NotifySymbolsResolved(std::move(ResolvedSymbols));
+ NotifySymbolsResolved(
+ ResolutionResult(std::move(ResolvedSymbols), QueryRegistrations));
NotifySymbolsResolved = SymbolsResolvedCallback();
}
@@ -686,8 +349,7 @@ MaterializationResponsibility::delegate(
void MaterializationResponsibility::addDependencies(
const SymbolDependenceMap &Dependencies) {
- for (auto &KV : SymbolFlags)
- V.addDependencies(KV.first, Dependencies);
+ V.addDependencies(SymbolFlags, Dependencies);
}
AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
@@ -722,9 +384,8 @@ ReExportsMaterializationUnit::ReExportsM
void ReExportsMaterializationUnit::materialize(
MaterializationResponsibility R) {
- auto &ES = R.getTargetVSO().getExecutionSession();
- VSO &TgtV = R.getTargetVSO();
- VSO &SrcV = SourceVSO ? *SourceVSO : TgtV;
+ VSO &SrcV = SourceVSO ? *SourceVSO : R.getTargetVSO();
+ auto &ES = SrcV.getExecutionSession();
// Find the set of requested aliases and aliasees. Return any unrequested
// aliases back to the VSO so as to not prematurely materialize any aliasees.
@@ -773,8 +434,9 @@ void ReExportsMaterializationUnit::mater
auto Tmp = I++;
// Chain detected. Skip this symbol for this round.
- if (&SrcV == &TgtV && (QueryAliases.count(Tmp->second.Aliasee) ||
- RequestedAliases.count(Tmp->second.Aliasee)))
+ if (&SrcV == &R.getTargetVSO() &&
+ (QueryAliases.count(Tmp->second.Aliasee) ||
+ RequestedAliases.count(Tmp->second.Aliasee)))
continue;
ResponsibilitySymbols.insert(Tmp->first);
@@ -797,32 +459,49 @@ void ReExportsMaterializationUnit::mater
QueryInfos.pop_back();
- auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
- R.addDependencies(Deps);
- };
+ auto OnResolve =
+ [QueryInfo,
+ &SrcV](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ if (RR) {
+ SymbolMap ResolutionMap;
+ SymbolNameSet Resolved;
+ for (auto &KV : QueryInfo->Aliases) {
+ assert(RR->Symbols.count(KV.second.Aliasee) &&
+ "Result map missing entry?");
+ ResolutionMap[KV.first] = JITEvaluatedSymbol(
+ RR->Symbols[KV.second.Aliasee].getAddress(),
+ KV.second.AliasFlags);
+
+ // FIXME: We're creating a SymbolFlagsMap and a std::map of
+ // std::sets just to add one dependency here. This needs a
+ // re-think.
+ Resolved.insert(KV.first);
+ }
+ QueryInfo->R.resolve(ResolutionMap);
- auto OnResolve = [QueryInfo](Expected<SymbolMap> Result) {
- if (Result) {
- SymbolMap ResolutionMap;
- for (auto &KV : QueryInfo->Aliases) {
- assert(Result->count(KV.second.Aliasee) &&
- "Result map missing entry?");
- ResolutionMap[KV.first] = JITEvaluatedSymbol(
- (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
- }
- QueryInfo->R.resolve(ResolutionMap);
- QueryInfo->R.finalize();
- } else {
- auto &ES = QueryInfo->R.getTargetVSO().getExecutionSession();
- ES.reportError(Result.takeError());
- QueryInfo->R.failMaterialization();
- }
- };
+ SymbolDependenceMap Deps;
+ Deps[&SrcV] = std::move(Resolved);
+ QueryInfo->R.addDependencies(Deps);
+
+ QueryInfo->R.finalize();
+ } else {
+ auto &ES = QueryInfo->R.getTargetVSO().getExecutionSession();
+ ES.reportError(RR.takeError());
+ QueryInfo->R.failMaterialization();
+ }
+ };
auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
- ES.lookup({&SrcV}, QuerySymbols, std::move(OnResolve), std::move(OnReady),
- std::move(RegisterDependencies));
+ auto Q = std::make_shared<AsynchronousSymbolQuery>(
+ QuerySymbols, std::move(OnResolve), std::move(OnReady));
+
+ auto Unresolved = SrcV.lookup(Q, std::move(QuerySymbols));
+
+ if (!Unresolved.empty()) {
+ ES.failQuery(*Q, make_error<SymbolsNotFound>(std::move(Unresolved)));
+ return;
+ }
}
}
@@ -963,35 +642,40 @@ SymbolNameSet VSO::getRequestedSymbols(c
});
}
-void VSO::addDependencies(const SymbolStringPtr &Name,
+void VSO::addDependencies(const SymbolFlagsMap &Dependants,
const SymbolDependenceMap &Dependencies) {
- assert(Symbols.count(Name) && "Name not in symbol table");
- assert((Symbols[Name].getFlags().isLazy() ||
- Symbols[Name].getFlags().isMaterializing()) &&
- "Symbol is not lazy or materializing");
-
- auto &MI = MaterializingInfos[Name];
- assert(!MI.IsFinalized && "Can not add dependencies to finalized symbol");
-
- for (auto &KV : Dependencies) {
- assert(KV.first && "Null VSO in dependency?");
- auto &OtherVSO = *KV.first;
- auto &DepsOnOtherVSO = MI.UnfinalizedDependencies[&OtherVSO];
-
- for (auto &OtherSymbol : KV.second) {
- auto &OtherMI = OtherVSO.MaterializingInfos[OtherSymbol];
-
- if (OtherMI.IsFinalized)
- transferFinalizedNodeDependencies(MI, Name, OtherMI);
- else if (&OtherVSO != this || OtherSymbol != Name) {
- OtherMI.Dependants[this].insert(Name);
- DepsOnOtherVSO.insert(OtherSymbol);
+ ES.runSessionLocked([&, this]() {
+ for (auto &KV : Dependants) {
+ const auto &Name = KV.first;
+ assert(Symbols.count(Name) && "Name not in symbol table");
+ assert((Symbols[Name].getFlags().isLazy() ||
+ Symbols[Name].getFlags().isMaterializing()) &&
+ "Symbol is not lazy or materializing");
+
+ auto &MI = MaterializingInfos[Name];
+ assert(!MI.IsFinalized && "Can not add dependencies to finalized symbol");
+
+ for (auto &KV : Dependencies) {
+ assert(KV.first && "Null VSO in dependency?");
+ auto &OtherVSO = *KV.first;
+ auto &DepsOnOtherVSO = MI.UnfinalizedDependencies[&OtherVSO];
+
+ for (auto &OtherSymbol : KV.second) {
+ auto &OtherMI = OtherVSO.MaterializingInfos[OtherSymbol];
+
+ if (OtherMI.IsFinalized)
+ transferFinalizedNodeDependencies(MI, Name, OtherMI);
+ else if (&OtherVSO != this || OtherSymbol != Name) {
+ OtherMI.Dependants[this].insert(Name);
+ DepsOnOtherVSO.insert(OtherSymbol);
+ }
+ }
+
+ if (DepsOnOtherVSO.empty())
+ MI.UnfinalizedDependencies.erase(&OtherVSO);
}
}
-
- if (DepsOnOtherVSO.empty())
- MI.UnfinalizedDependencies.erase(&OtherVSO);
- }
+ });
}
void VSO::resolve(const SymbolMap &Resolved) {
@@ -1172,6 +856,25 @@ void VSO::notifyFailed(const SymbolNameS
Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
}
+void VSO::runOutstandingMUs() {
+ while (1) {
+ std::unique_ptr<MaterializationUnit> MU;
+
+ {
+ std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
+ if (!OutstandingMUs.empty()) {
+ MU = std::move(OutstandingMUs.back());
+ OutstandingMUs.pop_back();
+ }
+ }
+
+ if (MU)
+ ES.dispatchMaterialization(*this, std::move(MU));
+ else
+ break;
+ }
+}
+
void VSO::setSearchOrder(VSOList NewSearchOrder, bool SearchThisVSOFirst) {
if (SearchThisVSOFirst && NewSearchOrder.front() != this)
NewSearchOrder.insert(NewSearchOrder.begin(), this);
@@ -1236,89 +939,11 @@ SymbolNameSet VSO::lookupFlagsImpl(Symbo
return Unresolved;
}
-void VSO::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved, MaterializationUnitList &MUs) {
- assert(Q && "Query can not be null");
-
- lodgeQueryImpl(Q, Unresolved, MUs);
- if (FallbackDefinitionGenerator && !Unresolved.empty()) {
- auto FallbackDefs = FallbackDefinitionGenerator(*this, Unresolved);
- if (!FallbackDefs.empty()) {
- for (auto &D : FallbackDefs)
- Unresolved.erase(D);
- lodgeQueryImpl(Q, FallbackDefs, MUs);
- assert(FallbackDefs.empty() &&
- "All fallback defs should have been found by lookupImpl");
- }
- }
-}
-
-void VSO::lodgeQueryImpl(
- std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved,
- std::vector<std::unique_ptr<MaterializationUnit>> &MUs) {
- for (auto I = Unresolved.begin(), E = Unresolved.end(); I != E;) {
- auto TmpI = I++;
- auto Name = *TmpI;
-
- // 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 in V, remove it frome the Unresolved set and add it
- // to the added set.
- Unresolved.erase(TmpI);
-
- // If the symbol has an address then resolve it.
- if (SymI->second.getAddress() != 0)
- Q->resolve(Name, SymI->second);
-
- // If the symbol is lazy, get the MaterialiaztionUnit for it.
- if (SymI->second.getFlags().isLazy()) {
- assert(SymI->second.getAddress() == 0 &&
- "Lazy symbol should not have a resolved address");
- assert(!SymI->second.getFlags().isMaterializing() &&
- "Materializing and lazy should not both be set");
- 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);
- auto Flags = SymK->second.getFlags();
- Flags &= ~JITSymbolFlags::Lazy;
- Flags |= JITSymbolFlags::Materializing;
- SymK->second.setFlags(Flags);
- UnmaterializedInfos.erase(KV.first);
- }
-
- // Add MU to the list of MaterializationUnits to be materialized.
- MUs.push_back(std::move(MU));
- } else if (!SymI->second.getFlags().isMaterializing()) {
- // The symbol is neither lazy nor materializing. Finalize it and
- // continue.
- Q->notifySymbolReady();
- continue;
- }
-
- // Add the query to the PendingQueries list.
- assert(SymI->second.getFlags().isMaterializing() &&
- "By this line the symbol should be materializing");
- auto &MI = MaterializingInfos[Name];
- MI.PendingQueries.push_back(Q);
- Q->addQueryDependence(*this, Name);
- }
-}
-
-SymbolNameSet VSO::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
- SymbolNameSet Names) {
+SymbolNameSet VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
+ SymbolNameSet Names) {
assert(Q && "Query can not be null");
- ES.runOutstandingMUs();
+ runOutstandingMUs();
LookupImplActionFlags ActionFlags = None;
std::vector<std::unique_ptr<MaterializationUnit>> MUs;
@@ -1353,11 +978,11 @@ SymbolNameSet VSO::legacyLookup(std::sha
// callbacks from asynchronous queries.
// Add MUs to the OutstandingMUs list.
{
- std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex);
+ std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
for (auto &MU : MUs)
- ES.OutstandingMUs.push_back(make_pair(this, std::move(MU)));
+ OutstandingMUs.push_back(std::move(MU));
}
- ES.runOutstandingMUs();
+ runOutstandingMUs();
// Dispatch any required MaterializationUnits for materialization.
// for (auto &MU : MUs)
@@ -1618,6 +1243,133 @@ VSO &ExecutionSession::createVSO(std::st
});
}
+Expected<SymbolMap> blockingLookup(ExecutionSessionBase &ES,
+ AsynchronousLookupFunction AsyncLookup,
+ SymbolNameSet Names, bool WaitUntilReady,
+ MaterializationResponsibility *MR) {
+
+#if LLVM_ENABLE_THREADS
+ // In the threaded case we use promises to return the results.
+ std::promise<SymbolMap> PromisedResult;
+ std::mutex ErrMutex;
+ Error ResolutionError = Error::success();
+ std::promise<void> PromisedReady;
+ Error ReadyError = Error::success();
+ auto OnResolve =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ if (Result) {
+ if (MR)
+ MR->addDependencies(Result->Dependencies);
+ PromisedResult.set_value(std::move(Result->Symbols));
+ } else {
+ {
+ ErrorAsOutParameter _(&ResolutionError);
+ std::lock_guard<std::mutex> Lock(ErrMutex);
+ ResolutionError = Result.takeError();
+ }
+ PromisedResult.set_value(SymbolMap());
+ }
+ };
+
+ std::function<void(Error)> OnReady;
+ if (WaitUntilReady) {
+ OnReady = [&](Error Err) {
+ if (Err) {
+ ErrorAsOutParameter _(&ReadyError);
+ std::lock_guard<std::mutex> Lock(ErrMutex);
+ ReadyError = std::move(Err);
+ }
+ PromisedReady.set_value();
+ };
+ } else {
+ OnReady = [&](Error Err) {
+ if (Err)
+ ES.reportError(std::move(Err));
+ };
+ }
+
+#else
+ SymbolMap Result;
+ Error ResolutionError = Error::success();
+ Error ReadyError = Error::success();
+
+ auto OnResolve = [&](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
+ ErrorAsOutParameter _(&ResolutionError);
+ if (R) {
+ if (MR)
+ MR->addDependencies(R->Dependencies);
+ Result = std::move(R->Symbols);
+ } else
+ ResolutionError = R.takeError();
+ };
+
+ std::function<void(Error)> OnReady;
+ if (WaitUntilReady) {
+ OnReady = [&](Error Err) {
+ ErrorAsOutParameter _(&ReadyError);
+ if (Err)
+ ReadyError = std::move(Err);
+ };
+ } else {
+ OnReady = [&](Error Err) {
+ if (Err)
+ ES.reportError(std::move(Err));
+ };
+ }
+#endif
+
+ auto Query = std::make_shared<AsynchronousSymbolQuery>(
+ Names, std::move(OnResolve), std::move(OnReady));
+
+ SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
+
+ // If there are unresolved symbols then the query will never return.
+ // Fail it with ES.failQuery.
+ if (!UnresolvedSymbols.empty())
+ ES.failQuery(*Query,
+ make_error<SymbolsNotFound>(std::move(UnresolvedSymbols)));
+
+#if LLVM_ENABLE_THREADS
+ auto ResultFuture = PromisedResult.get_future();
+ auto Result = ResultFuture.get();
+
+ {
+ std::lock_guard<std::mutex> Lock(ErrMutex);
+ if (ResolutionError) {
+ // ReadyError will never be assigned. Consume the success value.
+ cantFail(std::move(ReadyError));
+ return std::move(ResolutionError);
+ }
+ }
+
+ if (WaitUntilReady) {
+ auto ReadyFuture = PromisedReady.get_future();
+ ReadyFuture.get();
+
+ {
+ std::lock_guard<std::mutex> Lock(ErrMutex);
+ if (ReadyError)
+ return std::move(ReadyError);
+ }
+ } else
+ cantFail(std::move(ReadyError));
+
+ return std::move(Result);
+
+#else
+ if (ResolutionError) {
+ // ReadyError will never be assigned. Consume the success value.
+ cantFail(std::move(ReadyError));
+ return std::move(ResolutionError);
+ }
+
+ if (ReadyError)
+ return std::move(ReadyError);
+
+ return Result;
+#endif
+}
+
Expected<SymbolMap> lookup(const VSOList &VSOs, SymbolNameSet Names) {
if (VSOs.empty())
@@ -1625,7 +1377,18 @@ Expected<SymbolMap> lookup(const VSOList
auto &ES = (*VSOs.begin())->getExecutionSession();
- return ES.lookup(VSOs, Names, NoDependenciesToRegister, true);
+ auto LookupFn = [&](std::shared_ptr<AsynchronousSymbolQuery> Q,
+ SymbolNameSet Unresolved) {
+ for (auto *V : VSOs) {
+ assert(V && "VSOs entries must not be null");
+ if (Unresolved.empty())
+ break;
+ Unresolved = V->lookup(Q, std::move(Unresolved));
+ }
+ return Unresolved;
+ };
+
+ return blockingLookup(ES, std::move(LookupFn), Names, true);
}
/// Look up a symbol by searching a list of VSOs.
Modified: llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp Fri Jul 20 13:20:45 2018
@@ -29,14 +29,8 @@ JITSymbolResolverAdapter::lookup(const L
return R.lookup(std::move(Q), std::move(Unresolved));
};
- auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
- if (MR)
- MR->addDependencies(Deps);
- };
-
- auto InternedResult =
- ES.legacyLookup(ES, std::move(LookupFn), std::move(InternedSymbols),
- false, RegisterDependencies);
+ auto InternedResult = blockingLookup(ES, std::move(LookupFn),
+ std::move(InternedSymbols), false, MR);
if (!InternedResult)
return InternedResult.takeError();
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h Fri Jul 20 13:20:45 2018
@@ -156,11 +156,11 @@ private:
Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
Query->notifySymbolReady();
} else {
- Stack.ES.legacyFailQuery(*Query, Addr.takeError());
+ Stack.ES.failQuery(*Query, Addr.takeError());
return orc::SymbolNameSet();
}
} else if (auto Err = Sym.takeError()) {
- Stack.ES.legacyFailQuery(*Query, std::move(Err));
+ Stack.ES.failQuery(*Query, std::move(Err));
return orc::SymbolNameSet();
} else
UnresolvedSymbols.insert(S);
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h Fri Jul 20 13:20:45 2018
@@ -178,11 +178,11 @@ class OrcMCJITReplacement : public Execu
Query->notifySymbolReady();
NewSymbolsResolved = true;
} else {
- M.ES.legacyFailQuery(*Query, Addr.takeError());
+ M.ES.failQuery(*Query, Addr.takeError());
return SymbolNameSet();
}
} else if (auto Err = Sym.takeError()) {
- M.ES.legacyFailQuery(*Query, std::move(Err));
+ M.ES.failQuery(*Query, std::move(Err));
return SymbolNameSet();
} else {
if (auto Sym2 = M.ClientResolver->findSymbol(*S)) {
@@ -191,11 +191,11 @@ class OrcMCJITReplacement : public Execu
Query->notifySymbolReady();
NewSymbolsResolved = true;
} else {
- M.ES.legacyFailQuery(*Query, Addr.takeError());
+ M.ES.failQuery(*Query, Addr.takeError());
return SymbolNameSet();
}
} else if (auto Err = Sym2.takeError()) {
- M.ES.legacyFailQuery(*Query, std::move(Err));
+ M.ES.failQuery(*Query, std::move(Err));
return SymbolNameSet();
} else
UnresolvedSymbols.insert(S);
Modified: llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp Fri Jul 20 13:20:45 2018
@@ -16,23 +16,30 @@ using namespace llvm::orc;
class VSOSearchOrderResolver : public JITSymbolResolver {
public:
- VSOSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
+ VSOSearchOrderResolver(ExecutionSession &ES,
+ MaterializationResponsibility &MR)
+ : ES(ES), MR(MR) {}
Expected<LookupResult> lookup(const LookupSet &Symbols) {
- auto &ES = MR.getTargetVSO().getExecutionSession();
SymbolNameSet InternedSymbols;
for (auto &S : Symbols)
InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
- auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
- MR.addDependencies(Deps);
+ auto AsyncLookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Q,
+ SymbolNameSet Names) {
+ SymbolNameSet Unresolved = std::move(Names);
+ MR.getTargetVSO().withSearchOrderDo([&](const VSOList &SearchOrder) {
+ for (auto *V : SearchOrder) {
+ assert(V && "VSOList entry can not be null");
+ Unresolved = V->lookup(Q, std::move(Unresolved));
+ }
+ });
+ return Unresolved;
};
- auto InternedResult =
- MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
- return ES.lookup(VSOs, InternedSymbols, RegisterDependencies, false);
- });
+ auto InternedResult = blockingLookup(
+ ES, std::move(AsyncLookup), std::move(InternedSymbols), false, &MR);
if (!InternedResult)
return InternedResult.takeError();
@@ -45,8 +52,6 @@ public:
}
Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
- auto &ES = MR.getTargetVSO().getExecutionSession();
-
SymbolNameSet InternedSymbols;
for (auto &S : Symbols)
@@ -70,6 +75,7 @@ public:
}
private:
+ ExecutionSession &ES;
MaterializationResponsibility &MR;
};
@@ -100,7 +106,7 @@ void RTDyldObjectLinkingLayer2::emit(Mat
auto MemoryManager = GetMemoryManager(K);
- VSOSearchOrderResolver Resolver(R);
+ VSOSearchOrderResolver Resolver(ES, R);
auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
RTDyld->setProcessAllSections(ProcessAllSections);
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp Fri Jul 20 13:20:45 2018
@@ -59,57 +59,51 @@ private:
DestructorFunction Destructor;
};
-TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
+
+TEST_F(CoreAPIsStandardTest, AsynchronousSymbolQuerySuccessfulResolutionOnly) {
bool OnResolutionRun = false;
bool OnReadyRun = false;
-
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
- auto &Resolved = *Result;
- auto I = Resolved.find(Foo);
- EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
- EXPECT_EQ(I->second.getAddress(), FooAddr)
- << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
+ auto &Resolved = Result->Symbols;
+ auto I = Resolved.find(Foo);
+ EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
+ EXPECT_EQ(I->second.getAddress(), FooAddr)
+ << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
OnReadyRun = true;
};
- std::shared_ptr<MaterializationResponsibility> FooMR;
-
- cantFail(V.define(llvm::make_unique<SimpleMaterializationUnit>(
- SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
- [&](MaterializationResponsibility R) {
- FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
- })));
-
- ES.lookup({&V}, {Foo}, OnResolution, OnReady, NoDependenciesToRegister);
+ AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
- EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
- EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
+ Q.resolve(Foo, FooSym);
- FooMR->resolve({{Foo, FooSym}});
+ EXPECT_TRUE(Q.isFullyResolved()) << "Expected query to be fully resolved";
- EXPECT_TRUE(OnResolutionRun) << "Should have been resolved";
- EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
+ if (!Q.isFullyResolved())
+ return;
- FooMR->finalize();
+ Q.handleFullyResolved();
- EXPECT_TRUE(OnReadyRun) << "Should have been marked ready";
+ EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
+ EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
}
TEST_F(CoreAPIsStandardTest, ExecutionSessionFailQuery) {
bool OnResolutionRun = false;
bool OnReadyRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
- auto Msg = toString(Result.takeError());
- EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
+ auto Msg = toString(Result.takeError());
+ EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
OnReadyRun = true;
@@ -117,28 +111,62 @@ TEST_F(CoreAPIsStandardTest, ExecutionSe
AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
- ES.legacyFailQuery(Q,
- make_error<StringError>("xyz", inconvertibleErrorCode()));
+ ES.failQuery(Q, make_error<StringError>("xyz", inconvertibleErrorCode()));
EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
}
-TEST_F(CoreAPIsStandardTest, EmptyLookup) {
- bool OnResolvedRun = false;
+TEST_F(CoreAPIsStandardTest, SimpleAsynchronousSymbolQueryAgainstVSO) {
+ bool OnResolutionRun = false;
bool OnReadyRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- cantFail(std::move(Result));
- OnResolvedRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_TRUE(!!Result) << "Query unexpectedly returned error";
+ auto &Resolved = Result->Symbols;
+ auto I = Resolved.find(Foo);
+ EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
+ EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
+ << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
OnReadyRun = true;
};
- ES.lookup({&V}, {}, OnResolution, OnReady, NoDependenciesToRegister);
+ SymbolNameSet Names({Foo});
+
+ auto Q =
+ std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
+
+ auto Defs = absoluteSymbols({{Foo, FooSym}});
+ cantFail(V.define(Defs));
+ assert(Defs == nullptr && "Defs should have been accepted");
+ V.lookup(Q, Names);
+
+ EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
+ EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
+}
+
+TEST_F(CoreAPIsStandardTest, EmptyVSOAndQueryLookup) {
+ bool OnResolvedRun = false;
+ bool OnReadyRun = false;
+
+ auto Q = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet(),
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
+ OnResolvedRun = true;
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ OnReadyRun = true;
+ });
+
+ V.lookup(std::move(Q), {});
EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
@@ -154,8 +182,8 @@ TEST_F(CoreAPIsStandardTest, ChainedVSOL
auto Q = std::make_shared<AsynchronousSymbolQuery>(
SymbolNameSet({Foo}),
- [&](Expected<SymbolMap> Result) {
- cantFail(std::move(Result));
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
OnResolvedRun = true;
},
[&](Error Err) {
@@ -163,7 +191,7 @@ TEST_F(CoreAPIsStandardTest, ChainedVSOL
OnReadyRun = true;
});
- V2.legacyLookup(Q, V.legacyLookup(Q, {Foo}));
+ V2.lookup(Q, V.lookup(Q, {Foo}));
EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
@@ -240,15 +268,20 @@ TEST_F(CoreAPIsStandardTest, TestTrivial
cantFail(V.define(FooMU));
bool FooReady = false;
- auto OnResolution = [](Expected<SymbolMap> R) { cantFail(std::move(R)); };
- auto OnReady = [&](Error Err) {
- cantFail(std::move(Err));
- FooReady = true;
- };
+ auto Q =
+ std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({ Foo }),
+ [](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
+ cantFail(std::move(R));
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ FooReady = true;
+ });
- ES.lookup({&V}, {Foo}, std::move(OnResolution), std::move(OnReady),
- NoDependenciesToRegister);
+ V.lookup(std::move(Q), { Foo });
+ FooR->addDependencies({{&V, {Foo}}});
FooR->resolve({{Foo, FooSym}});
FooR->finalize();
@@ -290,52 +323,54 @@ TEST_F(CoreAPIsStandardTest, TestCircula
// Query each of the symbols to trigger materialization.
bool FooResolved = false;
bool FooReady = false;
-
- auto OnFooResolution = [&](Expected<SymbolMap> Result) {
- cantFail(std::move(Result));
- FooResolved = true;
- };
-
- auto OnFooReady = [&](Error Err) {
- cantFail(std::move(Err));
- FooReady = true;
- };
-
- // Issue a lookup for Foo. Use NoDependenciesToRegister: We're going to add
- // the dependencies manually below.
- ES.lookup({&V}, {Foo}, std::move(OnFooResolution), std::move(OnFooReady),
- NoDependenciesToRegister);
+ auto FooQ = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Foo}),
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
+ FooResolved = true;
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ FooReady = true;
+ });
+ {
+ auto Unresolved = V.lookup(FooQ, {Foo});
+ EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Foo\"";
+ }
bool BarResolved = false;
bool BarReady = false;
- auto OnBarResolution = [&](Expected<SymbolMap> Result) {
- cantFail(std::move(Result));
- BarResolved = true;
- };
-
- auto OnBarReady = [&](Error Err) {
- cantFail(std::move(Err));
- BarReady = true;
- };
-
- ES.lookup({&V}, {Bar}, std::move(OnBarResolution), std::move(OnBarReady),
- NoDependenciesToRegister);
+ auto BarQ = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Bar}),
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
+ BarResolved = true;
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ BarReady = true;
+ });
+ {
+ auto Unresolved = V.lookup(BarQ, {Bar});
+ EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Bar\"";
+ }
bool BazResolved = false;
bool BazReady = false;
-
- auto OnBazResolution = [&](Expected<SymbolMap> Result) {
- cantFail(std::move(Result));
- BazResolved = true;
- };
-
- auto OnBazReady = [&](Error Err) {
- cantFail(std::move(Err));
- BazReady = true;
- };
-
- ES.lookup({&V}, {Baz}, std::move(OnBazResolution), std::move(OnBazReady),
- NoDependenciesToRegister);
+ auto BazQ = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Baz}),
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
+ BazResolved = true;
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ BazReady = true;
+ });
+ {
+ auto Unresolved = V.lookup(BazQ, {Baz});
+ EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Baz\"";
+ }
// Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
FooR->addDependencies({{&V, SymbolNameSet({Bar})}});
@@ -443,23 +478,28 @@ TEST_F(CoreAPIsStandardTest, AddAndMater
bool OnResolutionRun = false;
bool OnReadyRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
- auto I = Result->find(Foo);
- EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
- EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
- << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
+ auto I = Result->Symbols.find(Foo);
+ EXPECT_NE(I, Result->Symbols.end())
+ << "Could not find symbol definition";
+ EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
+ << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
OnReadyRun = true;
};
- ES.lookup({&V}, Names, std::move(OnResolution), std::move(OnReady),
- NoDependenciesToRegister);
+ auto Q =
+ std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
+ auto Unresolved = V.lookup(std::move(Q), Names);
+
+ EXPECT_TRUE(Unresolved.empty()) << "Could not find Foo in dylib";
EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
@@ -674,14 +714,13 @@ TEST_F(CoreAPIsStandardTest, TestMateria
});
cantFail(V.define(MU));
- auto OnResolution = [](Expected<SymbolMap> Result) {
- cantFail(std::move(Result));
- };
-
- auto OnReady = [](Error Err) { cantFail(std::move(Err)); };
-
- ES.lookup({&V}, {Foo}, std::move(OnResolution), std::move(OnReady),
- NoDependenciesToRegister);
+ auto Q = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Foo}),
+ [](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
+ cantFail(std::move(R));
+ },
+ [](Error Err) { cantFail(std::move(Err)); });
+ V.lookup(std::move(Q), SymbolNameSet({Foo}));
auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp?rev=337608&r1=337607&r2=337608&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp Fri Jul 20 13:20:45 2018
@@ -24,7 +24,7 @@ TEST_F(LegacyAPIsStandardTest, TestLambd
auto Resolver = createSymbolResolver(
[&](const SymbolNameSet &Symbols) { return V.lookupFlags(Symbols); },
[&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
- return V.legacyLookup(std::move(Q), Symbols);
+ return V.lookup(std::move(Q), Symbols);
});
SymbolNameSet Symbols({Foo, Bar, Baz});
@@ -42,17 +42,21 @@ TEST_F(LegacyAPIsStandardTest, TestLambd
bool OnResolvedRun = false;
- auto OnResolved = [&](Expected<SymbolMap> Result) {
- OnResolvedRun = true;
- EXPECT_TRUE(!!Result) << "Unexpected error";
- EXPECT_EQ(Result->size(), 2U) << "Unexpected number of resolved symbols";
- EXPECT_EQ(Result->count(Foo), 1U) << "Missing lookup result for foo";
- EXPECT_EQ(Result->count(Bar), 1U) << "Missing lookup result for bar";
- EXPECT_EQ((*Result)[Foo].getAddress(), FooSym.getAddress())
- << "Incorrect address for foo";
- EXPECT_EQ((*Result)[Bar].getAddress(), BarSym.getAddress())
- << "Incorrect address for bar";
- };
+ auto OnResolved =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ OnResolvedRun = true;
+ EXPECT_TRUE(!!Result) << "Unexpected error";
+ EXPECT_EQ(Result->Symbols.size(), 2U)
+ << "Unexpected number of resolved symbols";
+ EXPECT_EQ(Result->Symbols.count(Foo), 1U)
+ << "Missing lookup result for foo";
+ EXPECT_EQ(Result->Symbols.count(Bar), 1U)
+ << "Missing lookup result for bar";
+ EXPECT_EQ(Result->Symbols[Foo].getAddress(), FooSym.getAddress())
+ << "Incorrect address for foo";
+ EXPECT_EQ(Result->Symbols[Bar].getAddress(), BarSym.getAddress())
+ << "Incorrect address for bar";
+ };
auto OnReady = [&](Error Err) {
EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
};
@@ -81,7 +85,7 @@ TEST(LegacyAPIInteropTest, QueryAgainstV
auto Lookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
SymbolNameSet Symbols) {
- return V.legacyLookup(std::move(Query), Symbols);
+ return V.lookup(std::move(Query), Symbols);
};
auto UnderlyingResolver =
@@ -154,18 +158,22 @@ TEST(LegacyAPIInteropTset, LegacyLookupH
bool OnResolvedRun = false;
bool OnReadyRun = false;
- auto OnResolved = [&](Expected<SymbolMap> Result) {
- OnResolvedRun = true;
- EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
-
- EXPECT_EQ(Result->size(), 2U) << "Wrong number of symbols resolved";
- EXPECT_EQ(Result->count(Foo), 1U) << "Result for foo missing";
- EXPECT_EQ(Result->count(Bar), 1U) << "Result for bar missing";
- EXPECT_EQ((*Result)[Foo].getAddress(), FooAddr) << "Wrong address for foo";
- EXPECT_EQ((*Result)[Foo].getFlags(), FooFlags) << "Wrong flags for foo";
- EXPECT_EQ((*Result)[Bar].getAddress(), BarAddr) << "Wrong address for bar";
- EXPECT_EQ((*Result)[Bar].getFlags(), BarFlags) << "Wrong flags for bar";
- };
+ auto OnResolved =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ OnResolvedRun = true;
+ EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
+
+ auto &Resolved = Result->Symbols;
+ EXPECT_EQ(Resolved.size(), 2U) << "Wrong number of symbols resolved";
+ EXPECT_EQ(Resolved.count(Foo), 1U) << "Result for foo missing";
+ EXPECT_EQ(Resolved.count(Bar), 1U) << "Result for bar missing";
+ EXPECT_EQ(Resolved[Foo].getAddress(), FooAddr)
+ << "Wrong address for foo";
+ EXPECT_EQ(Resolved[Foo].getFlags(), FooFlags) << "Wrong flags for foo";
+ EXPECT_EQ(Resolved[Bar].getAddress(), BarAddr)
+ << "Wrong address for bar";
+ EXPECT_EQ(Resolved[Bar].getFlags(), BarFlags) << "Wrong flags for bar";
+ };
auto OnReady = [&](Error Err) {
EXPECT_FALSE(!!Err) << "Finalization unexpectedly failed";
OnReadyRun = true;
More information about the llvm-commits
mailing list