[llvm] r337595 - [ORC] Add new symbol lookup methods to ExecutionSessionBase in preparation for
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 20 14:31:35 PDT 2018
Hi Reid,
No worries. Thanks for doing that!
I'll investigate and re-apply once I have a fix.
Cheers,
Lang.
On Fri, Jul 20, 2018 at 1:28 PM Reid Kleckner <rnk at google.com> wrote:
> I had to revert this in r337608 because it broke the
> LLVM_ENABLE_THREADS=OFF build. Unfortunately, the two code paths are very
> different, and I couldn't find a quick fix.
>
> On Fri, Jul 20, 2018 at 11:37 AM Lang Hames via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: lhames
>> Date: Fri Jul 20 11:31:53 2018
>> New Revision: 337595
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=337595&view=rev
>> Log:
>> [ORC] Add new symbol lookup methods to ExecutionSessionBase in
>> preparation for
>> deprecating SymbolResolver and AsynchronousSymbolQuery.
>>
>> Both lookup overloads take a VSO search order to perform the lookup. The
>> first
>> overload is non-blocking and takes OnResolved and OnReady callbacks. The
>> second
>> is blocking, takes a boolean flag to indicate whether to wait until all
>> symbols
>> are ready, and returns a SymbolMap. Both overloads take a
>> RegisterDependencies
>> function to register symbol dependencies (if any) on the query.
>>
>> 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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h Fri Jul 20
>> 11:31:53 2018
>> @@ -69,8 +69,23 @@ 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:
>> @@ -122,6 +137,9 @@ 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
>> @@ -223,6 +241,9 @@ 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
>> @@ -322,6 +343,9 @@ 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)>;
>> @@ -372,11 +396,50 @@ public:
>> void releaseVModule(VModuleKey Key) { /* FIXME: Recycle keys */
>> }
>>
>> - /// 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);
>> + 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);
>>
>> /// Materialize the given unit.
>> void dispatchMaterialization(VSO &V,
>> @@ -394,12 +457,20 @@ 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
>> @@ -411,21 +482,6 @@ 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.
>> @@ -485,6 +541,7 @@ private:
>> class VSO {
>> friend class AsynchronousSymbolQuery;
>> friend class ExecutionSession;
>> + friend class ExecutionSessionBase;
>> friend class MaterializationResponsibility;
>> public:
>> using FallbackDefinitionGeneratorFunction =
>> @@ -493,9 +550,6 @@ 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;
>> @@ -547,8 +601,10 @@ public:
>> void removeFromSearchOrder(VSO &V);
>>
>> /// Do something with the search order (run under the session lock).
>> - template <typename Func> void withSearchOrderDo(Func F) {
>> - ES.runSessionLocked([&]() { F(SearchOrder); });
>> + template <typename Func>
>> + auto withSearchOrderDo(Func &&F)
>> + -> decltype(F(std::declval<const VSOList &>())) {
>> + return ES.runSessionLocked([&]() { return F(SearchOrder); });
>> }
>>
>> /// Define all symbols provided by the materialization unit to be part
>> @@ -579,6 +635,10 @@ 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.
>> ///
>> @@ -586,11 +646,8 @@ 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 lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
>> - SymbolNameSet Names);
>> -
>> - /// Dump current VSO state to OS.
>> - void dump(raw_ostream &OS);
>> + SymbolNameSet legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
>> + SymbolNameSet Names);
>>
>> private:
>> using AsynchronousSymbolQueryList =
>> @@ -629,6 +686,12 @@ 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,
>> @@ -647,8 +710,8 @@ private:
>>
>> SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags);
>>
>> - void addDependencies(const SymbolFlagsMap &Dependents,
>> - const SymbolDependenceMap &Dependencies);
>> + void addDependencies(const SymbolStringPtr &Name,
>> + const SymbolDependenceMap &Dependants);
>>
>> void resolve(const SymbolMap &Resolved);
>>
>> @@ -656,8 +719,6 @@ private:
>>
>> void notifyFailed(const SymbolNameSet &FailedSymbols);
>>
>> - void runOutstandingMUs();
>> -
>> ExecutionSessionBase &ES;
>> std::string VSOName;
>> SymbolMap Symbols;
>> @@ -665,11 +726,6 @@ 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.
>> @@ -693,15 +749,6 @@ 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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h Fri Jul 20
>> 11:31:53 2018
>> @@ -146,11 +146,11 @@ lookupWithLegacyFn(ExecutionSession &ES,
>> Query.notifySymbolReady();
>> NewSymbolsResolved = true;
>> } else {
>> - ES.failQuery(Query, Addr.takeError());
>> + ES.legacyFailQuery(Query, Addr.takeError());
>> return SymbolNameSet();
>> }
>> } else if (auto Err = Sym.takeError()) {
>> - ES.failQuery(Query, std::move(Err));
>> + ES.legacyFailQuery(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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp Fri Jul 20 11:31:53 2018
>> @@ -23,6 +23,9 @@ 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) {
>> @@ -138,20 +141,361 @@ void SymbolsNotFound::log(raw_ostream &O
>> OS << "Symbols not found: " << Symbols;
>> }
>>
>> -void ExecutionSessionBase::failQuery(AsynchronousSymbolQuery &Q, Error
>> Err) {
>> - bool DeliveredError = true;
>> - runSessionLocked([&]() -> void {
>> +void ExecutionSessionBase::legacyFailQuery(AsynchronousSymbolQuery &Q,
>> + Error Err) {
>> + assert(!!Err && "Error should be in failure state");
>> +
>> + bool SendErrorToQuery;
>> + runSessionLocked([&]() {
>> Q.detach();
>> - if (Q.canStillFail())
>> - Q.handleFailed(std::move(Err));
>> - else
>> - DeliveredError = false;
>> + SendErrorToQuery = Q.canStillFail();
>> });
>>
>> - if (!DeliveredError)
>> + 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);
>> + 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));
>> + }
>> + });
>> +
>> + 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;
>> + }
>> +}
>> +
>> AsynchronousSymbolQuery::AsynchronousSymbolQuery(
>> const SymbolNameSet &Symbols, SymbolsResolvedCallback
>> NotifySymbolsResolved,
>> SymbolsReadyCallback NotifySymbolsReady)
>> @@ -161,12 +505,6 @@ 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,
>> @@ -183,8 +521,7 @@ void AsynchronousSymbolQuery::handleFull
>> assert(NotYetResolvedCount == 0 && "Not fully resolved?");
>> assert(NotifySymbolsResolved &&
>> "NotifySymbolsResolved already called or error occurred");
>> - NotifySymbolsResolved(
>> - ResolutionResult(std::move(ResolvedSymbols), QueryRegistrations));
>> + NotifySymbolsResolved(std::move(ResolvedSymbols));
>> NotifySymbolsResolved = SymbolsResolvedCallback();
>> }
>>
>> @@ -349,7 +686,8 @@ MaterializationResponsibility::delegate(
>>
>> void MaterializationResponsibility::addDependencies(
>> const SymbolDependenceMap &Dependencies) {
>> - V.addDependencies(SymbolFlags, Dependencies);
>> + for (auto &KV : SymbolFlags)
>> + V.addDependencies(KV.first, Dependencies);
>> }
>>
>> AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
>> @@ -384,8 +722,9 @@ ReExportsMaterializationUnit::ReExportsM
>> void ReExportsMaterializationUnit::materialize(
>> MaterializationResponsibility R) {
>>
>> - VSO &SrcV = SourceVSO ? *SourceVSO : R.getTargetVSO();
>> - auto &ES = SrcV.getExecutionSession();
>> + auto &ES = R.getTargetVSO().getExecutionSession();
>> + VSO &TgtV = R.getTargetVSO();
>> + VSO &SrcV = SourceVSO ? *SourceVSO : TgtV;
>>
>> // Find the set of requested aliases and aliasees. Return any
>> unrequested
>> // aliases back to the VSO so as to not prematurely materialize any
>> aliasees.
>> @@ -434,9 +773,8 @@ void ReExportsMaterializationUnit::mater
>> auto Tmp = I++;
>>
>> // Chain detected. Skip this symbol for this round.
>> - if (&SrcV == &R.getTargetVSO() &&
>> - (QueryAliases.count(Tmp->second.Aliasee) ||
>> - RequestedAliases.count(Tmp->second.Aliasee)))
>> + if (&SrcV == &TgtV && (QueryAliases.count(Tmp->second.Aliasee) ||
>> +
>> RequestedAliases.count(Tmp->second.Aliasee)))
>> continue;
>>
>> ResponsibilitySymbols.insert(Tmp->first);
>> @@ -459,49 +797,32 @@ void ReExportsMaterializationUnit::mater
>>
>> QueryInfos.pop_back();
>>
>> - 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 RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
>> + R.addDependencies(Deps);
>> + };
>>
>> - 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 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();
>> + }
>> + };
>>
>> auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
>>
>> - 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;
>> - }
>> + ES.lookup({&SrcV}, QuerySymbols, std::move(OnResolve),
>> std::move(OnReady),
>> + std::move(RegisterDependencies));
>> }
>> }
>>
>> @@ -642,40 +963,35 @@ SymbolNameSet VSO::getRequestedSymbols(c
>> });
>> }
>>
>> -void VSO::addDependencies(const SymbolFlagsMap &Dependants,
>> +void VSO::addDependencies(const SymbolStringPtr &Name,
>> const SymbolDependenceMap &Dependencies) {
>> - 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);
>> + 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);
>> + }
>> }
>>
>> void VSO::resolve(const SymbolMap &Resolved) {
>> @@ -856,25 +1172,6 @@ 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);
>> @@ -939,11 +1236,89 @@ SymbolNameSet VSO::lookupFlagsImpl(Symbo
>> return Unresolved;
>> }
>>
>> -SymbolNameSet VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
>> - SymbolNameSet Names) {
>> +void VSO::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
>> + SymbolNameSet &Unresolved, MaterializationUnitList
>> &MUs) {
>> assert(Q && "Query can not be null");
>>
>> - runOutstandingMUs();
>> + 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) {
>> + assert(Q && "Query can not be null");
>> +
>> + ES.runOutstandingMUs();
>>
>> LookupImplActionFlags ActionFlags = None;
>> std::vector<std::unique_ptr<MaterializationUnit>> MUs;
>> @@ -978,11 +1353,11 @@ SymbolNameSet VSO::lookup(std::shared_pt
>> // callbacks from asynchronous queries.
>> // Add MUs to the OutstandingMUs list.
>> {
>> - std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
>> + std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex);
>> for (auto &MU : MUs)
>> - OutstandingMUs.push_back(std::move(MU));
>> + ES.OutstandingMUs.push_back(make_pair(this, std::move(MU)));
>> }
>> - runOutstandingMUs();
>> + ES.runOutstandingMUs();
>>
>> // Dispatch any required MaterializationUnits for materialization.
>> // for (auto &MU : MUs)
>> @@ -1243,133 +1618,6 @@ 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())
>> @@ -1377,18 +1625,7 @@ Expected<SymbolMap> lookup(const VSOList
>>
>> auto &ES = (*VSOs.begin())->getExecutionSession();
>>
>> - 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);
>> + return ES.lookup(VSOs, Names, NoDependenciesToRegister, 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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp Fri Jul 20 11:31:53 2018
>> @@ -29,8 +29,14 @@ JITSymbolResolverAdapter::lookup(const L
>> return R.lookup(std::move(Q), std::move(Unresolved));
>> };
>>
>> - auto InternedResult = blockingLookup(ES, std::move(LookupFn),
>> - std::move(InternedSymbols),
>> false, MR);
>> + auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
>> + if (MR)
>> + MR->addDependencies(Deps);
>> + };
>> +
>> + auto InternedResult =
>> + ES.legacyLookup(ES, std::move(LookupFn),
>> std::move(InternedSymbols),
>> + false, RegisterDependencies);
>>
>> 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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h Fri Jul 20
>> 11:31:53 2018
>> @@ -156,11 +156,11 @@ private:
>> Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
>> Query->notifySymbolReady();
>> } else {
>> - Stack.ES.failQuery(*Query, Addr.takeError());
>> + Stack.ES.legacyFailQuery(*Query, Addr.takeError());
>> return orc::SymbolNameSet();
>> }
>> } else if (auto Err = Sym.takeError()) {
>> - Stack.ES.failQuery(*Query, std::move(Err));
>> + Stack.ES.legacyFailQuery(*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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h Fri Jul 20
>> 11:31:53 2018
>> @@ -178,11 +178,11 @@ class OrcMCJITReplacement : public Execu
>> Query->notifySymbolReady();
>> NewSymbolsResolved = true;
>> } else {
>> - M.ES.failQuery(*Query, Addr.takeError());
>> + M.ES.legacyFailQuery(*Query, Addr.takeError());
>> return SymbolNameSet();
>> }
>> } else if (auto Err = Sym.takeError()) {
>> - M.ES.failQuery(*Query, std::move(Err));
>> + M.ES.legacyFailQuery(*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.failQuery(*Query, Addr.takeError());
>> + M.ES.legacyFailQuery(*Query, Addr.takeError());
>> return SymbolNameSet();
>> }
>> } else if (auto Err = Sym2.takeError()) {
>> - M.ES.failQuery(*Query, std::move(Err));
>> + M.ES.legacyFailQuery(*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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
>> (original)
>> +++ llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp Fri
>> Jul 20 11:31:53 2018
>> @@ -16,30 +16,23 @@ using namespace llvm::orc;
>>
>> class VSOSearchOrderResolver : public JITSymbolResolver {
>> public:
>> - VSOSearchOrderResolver(ExecutionSession &ES,
>> - MaterializationResponsibility &MR)
>> - : ES(ES), MR(MR) {}
>> + VSOSearchOrderResolver(MaterializationResponsibility &MR) : 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 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 RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
>> + MR.addDependencies(Deps);
>> };
>>
>> - auto InternedResult = blockingLookup(
>> - ES, std::move(AsyncLookup), std::move(InternedSymbols), false,
>> &MR);
>> + auto InternedResult =
>> + MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
>> + return ES.lookup(VSOs, InternedSymbols, RegisterDependencies,
>> false);
>> + });
>>
>> if (!InternedResult)
>> return InternedResult.takeError();
>> @@ -52,6 +45,8 @@ public:
>> }
>>
>> Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
>> + auto &ES = MR.getTargetVSO().getExecutionSession();
>> +
>> SymbolNameSet InternedSymbols;
>>
>> for (auto &S : Symbols)
>> @@ -75,7 +70,6 @@ public:
>> }
>>
>> private:
>> - ExecutionSession &ES;
>> MaterializationResponsibility &MR;
>> };
>>
>> @@ -106,7 +100,7 @@ void RTDyldObjectLinkingLayer2::emit(Mat
>>
>> auto MemoryManager = GetMemoryManager(K);
>>
>> - VSOSearchOrderResolver Resolver(ES, R);
>> + VSOSearchOrderResolver Resolver(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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp (original)
>> +++ llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp Fri Jul 20
>> 11:31:53 2018
>> @@ -59,51 +59,57 @@ private:
>> DestructorFunction Destructor;
>> };
>>
>> -
>> -TEST_F(CoreAPIsStandardTest,
>> AsynchronousSymbolQuerySuccessfulResolutionOnly) {
>> +TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
>> bool OnResolutionRun = false;
>> bool OnReadyRun = false;
>> - 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 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 OnReady = [&](Error Err) {
>> cantFail(std::move(Err));
>> OnReadyRun = true;
>> };
>>
>> - AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
>> + std::shared_ptr<MaterializationResponsibility> FooMR;
>>
>> - Q.resolve(Foo, FooSym);
>> + cantFail(V.define(llvm::make_unique<SimpleMaterializationUnit>(
>> + SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
>> + [&](MaterializationResponsibility R) {
>> + FooMR =
>> std::make_shared<MaterializationResponsibility>(std::move(R));
>> + })));
>>
>> - EXPECT_TRUE(Q.isFullyResolved()) << "Expected query to be fully
>> resolved";
>> + ES.lookup({&V}, {Foo}, OnResolution, OnReady,
>> NoDependenciesToRegister);
>>
>> - if (!Q.isFullyResolved())
>> - return;
>> + EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
>> + EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
>>
>> - Q.handleFullyResolved();
>> + FooMR->resolve({{Foo, FooSym}});
>>
>> - EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
>> - EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
>> + EXPECT_TRUE(OnResolutionRun) << "Should have been resolved";
>> + EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
>> +
>> + FooMR->finalize();
>> +
>> + EXPECT_TRUE(OnReadyRun) << "Should have been marked ready";
>> }
>>
>> TEST_F(CoreAPIsStandardTest, ExecutionSessionFailQuery) {
>> bool OnResolutionRun = false;
>> bool OnReadyRun = false;
>>
>> - 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 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 OnReady = [&](Error Err) {
>> cantFail(std::move(Err));
>> OnReadyRun = true;
>> @@ -111,62 +117,28 @@ TEST_F(CoreAPIsStandardTest, ExecutionSe
>>
>> AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
>>
>> - ES.failQuery(Q, make_error<StringError>("xyz",
>> inconvertibleErrorCode()));
>> + ES.legacyFailQuery(Q,
>> + make_error<StringError>("xyz",
>> inconvertibleErrorCode()));
>>
>> EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
>> EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
>> }
>>
>> -TEST_F(CoreAPIsStandardTest, SimpleAsynchronousSymbolQueryAgainstVSO) {
>> - bool OnResolutionRun = false;
>> +TEST_F(CoreAPIsStandardTest, EmptyLookup) {
>> + bool OnResolvedRun = false;
>> bool OnReadyRun = false;
>>
>> - 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 OnResolution = [&](Expected<SymbolMap> Result) {
>> + cantFail(std::move(Result));
>> + OnResolvedRun = true;
>> + };
>>
>> auto OnReady = [&](Error Err) {
>> cantFail(std::move(Err));
>> OnReadyRun = true;
>> };
>>
>> - 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), {});
>> + ES.lookup({&V}, {}, OnResolution, OnReady, NoDependenciesToRegister);
>>
>> EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
>> EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
>> @@ -182,8 +154,8 @@ TEST_F(CoreAPIsStandardTest, ChainedVSOL
>>
>> auto Q = std::make_shared<AsynchronousSymbolQuery>(
>> SymbolNameSet({Foo}),
>> - [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
>> - cantFail(std::move(RR));
>> + [&](Expected<SymbolMap> Result) {
>> + cantFail(std::move(Result));
>> OnResolvedRun = true;
>> },
>> [&](Error Err) {
>> @@ -191,7 +163,7 @@ TEST_F(CoreAPIsStandardTest, ChainedVSOL
>> OnReadyRun = true;
>> });
>>
>> - V2.lookup(Q, V.lookup(Q, {Foo}));
>> + V2.legacyLookup(Q, V.legacyLookup(Q, {Foo}));
>>
>> EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
>> EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
>> @@ -268,20 +240,15 @@ TEST_F(CoreAPIsStandardTest, TestTrivial
>> cantFail(V.define(FooMU));
>>
>> bool FooReady = false;
>> - auto Q =
>> - std::make_shared<AsynchronousSymbolQuery>(
>> - SymbolNameSet({ Foo }),
>> - [](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
>> - cantFail(std::move(R));
>> - },
>> - [&](Error Err) {
>> - cantFail(std::move(Err));
>> - FooReady = true;
>> - });
>> + auto OnResolution = [](Expected<SymbolMap> R) {
>> cantFail(std::move(R)); };
>> + auto OnReady = [&](Error Err) {
>> + cantFail(std::move(Err));
>> + FooReady = true;
>> + };
>>
>> - V.lookup(std::move(Q), { Foo });
>> + ES.lookup({&V}, {Foo}, std::move(OnResolution), std::move(OnReady),
>> + NoDependenciesToRegister);
>>
>> - FooR->addDependencies({{&V, {Foo}}});
>> FooR->resolve({{Foo, FooSym}});
>> FooR->finalize();
>>
>> @@ -323,54 +290,52 @@ TEST_F(CoreAPIsStandardTest, TestCircula
>> // Query each of the symbols to trigger materialization.
>> bool FooResolved = false;
>> bool FooReady = false;
>> - 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\"";
>> - }
>> +
>> + 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);
>>
>> bool BarResolved = false;
>> bool BarReady = false;
>> - 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\"";
>> - }
>> + 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);
>>
>> bool BazResolved = false;
>> bool BazReady = false;
>> - 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\"";
>> - }
>> +
>> + 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);
>>
>> // Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
>> FooR->addDependencies({{&V, SymbolNameSet({Bar})}});
>> @@ -478,28 +443,23 @@ TEST_F(CoreAPIsStandardTest, AddAndMater
>> bool OnResolutionRun = false;
>> bool OnReadyRun = false;
>>
>> - 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 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 OnReady = [&](Error Err) {
>> cantFail(std::move(Err));
>> OnReadyRun = true;
>> };
>>
>> - auto Q =
>> - std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution,
>> OnReady);
>> + ES.lookup({&V}, Names, std::move(OnResolution), std::move(OnReady),
>> + NoDependenciesToRegister);
>>
>> - 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";
>> @@ -714,13 +674,14 @@ TEST_F(CoreAPIsStandardTest, TestMateria
>> });
>>
>> cantFail(V.define(MU));
>> - 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 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 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=337595&r1=337594&r2=337595&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
>> (original)
>> +++ llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp Fri
>> Jul 20 11:31:53 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.lookup(std::move(Q), Symbols);
>> + return V.legacyLookup(std::move(Q), Symbols);
>> });
>>
>> SymbolNameSet Symbols({Foo, Bar, Baz});
>> @@ -42,21 +42,17 @@ TEST_F(LegacyAPIsStandardTest, TestLambd
>>
>> bool OnResolvedRun = false;
>>
>> - 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 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 OnReady = [&](Error Err) {
>> EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
>> };
>> @@ -85,7 +81,7 @@ TEST(LegacyAPIInteropTest, QueryAgainstV
>>
>> auto Lookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
>> SymbolNameSet Symbols) {
>> - return V.lookup(std::move(Query), Symbols);
>> + return V.legacyLookup(std::move(Query), Symbols);
>> };
>>
>> auto UnderlyingResolver =
>> @@ -158,22 +154,18 @@ TEST(LegacyAPIInteropTset, LegacyLookupH
>>
>> bool OnResolvedRun = false;
>> bool OnReadyRun = false;
>> - 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) << "
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180720/987eedab/attachment-0001.html>
More information about the llvm-commits
mailing list