[llvm] r330356 - [ORC] Make VSO symbol resolution/finalization operations private.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 19 11:42:49 PDT 2018
Author: lhames
Date: Thu Apr 19 11:42:49 2018
New Revision: 330356
URL: http://llvm.org/viewvc/llvm-project?rev=330356&view=rev
Log:
[ORC] Make VSO symbol resolution/finalization operations private.
This forces these operations to be carried out via a
MaterializationResponsibility instance, ensuring responsibility is explicitly
tracked.
Modified:
llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
llvm/trunk/lib/ExecutionEngine/Orc/Core.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=330356&r1=330355&r2=330356&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h Thu Apr 19 11:42:49 2018
@@ -207,19 +207,49 @@ createSymbolResolver(LookupFlagsFn &&Loo
}
/// @brief Tracks responsibility for materialization.
+///
+/// An instance of this class is passed to MaterializationUnits when their
+/// materialize method is called. It allows MaterializationUnits to resolve and
+/// finalize symbols, or abandon materialization by notifying any unmaterialized
+/// symbols of an error.
class MaterializationResponsibility {
public:
+ /// @brief Create a MaterializationResponsibility for the given VSO and
+ /// initial symbols.
MaterializationResponsibility(VSO &V, SymbolFlagsMap SymbolFlags);
+
MaterializationResponsibility(MaterializationResponsibility &&) = default;
MaterializationResponsibility &
operator=(MaterializationResponsibility &&) = default;
+
+ /// @brief Destruct a MaterializationResponsibility instance. In debug mode
+ /// this asserts that all symbols being tracked have been either
+ /// finalized or notified of an error.
~MaterializationResponsibility();
- MaterializationResponsibility takeResponsibility(SymbolNameSet Symbols);
+
+ /// @brief Returns the target VSO that these symbols are being materialized
+ /// into.
const VSO &getTargetVSO() const { return V; }
+
+ /// @brief Resolves the given symbols. Individual calls to this method may
+ /// resolve a subset of the symbols, but all symbols must have been
+ /// resolved prior to calling finalize.
void resolve(const SymbolMap &Symbols);
+
+ /// @brief Finalizes all symbols tracked by this instance.
void finalize();
+
+ /// @brief Notify all unfinalized symbols that an error has occurred.
+ /// This method should be called if materialization of any symbol is
+ /// abandoned.
void notifyMaterializationFailed();
+ /// @brief Transfers responsibility for the given symbols to a new
+ /// MaterializationResponsibility class. This is useful if a
+ /// MaterializationUnit wants to transfer responsibility for a subset
+ /// of symbols to another MaterializationUnit or utility.
+ MaterializationResponsibility delegate(SymbolNameSet Symbols);
+
private:
VSO &V;
SymbolFlagsMap SymbolFlags;
@@ -262,6 +292,7 @@ private:
/// (since a VSO's address is fixed).
class VSO {
friend class ExecutionSession;
+ friend class MaterializationResponsibility;
public:
enum RelativeLinkageStrength {
@@ -316,16 +347,6 @@ public:
/// @brief Adds the given symbols to the mapping as lazy symbols.
Error defineLazy(std::unique_ptr<MaterializationUnit> Source);
- /// @brief Add the given symbol/address mappings to the dylib, but do not
- /// mark the symbols as finalized yet.
- void resolve(const SymbolMap &SymbolValues);
-
- /// @brief Finalize the given symbols.
- void finalize(const SymbolNameSet &SymbolsToFinalize);
-
- /// @brief Notify the VSO that the given symbols failed to materialized.
- void notifyMaterializationFailed(const SymbolNameSet &Names);
-
/// @brief Look up the flags for the given symbols.
///
/// Returns the flags for the give symbols, together with the set of symbols
@@ -348,6 +369,16 @@ public:
SymbolNameSet Symbols);
private:
+ /// @brief Add the given symbol/address mappings to the dylib, but do not
+ /// mark the symbols as finalized yet.
+ void resolve(const SymbolMap &SymbolValues);
+
+ /// @brief Finalize the given symbols.
+ void finalize(const SymbolNameSet &SymbolsToFinalize);
+
+ /// @brief Notify the VSO that the given symbols failed to materialized.
+ void notifyMaterializationFailed(const SymbolNameSet &Names);
+
class UnmaterializedInfo {
public:
UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU);
@@ -390,6 +421,11 @@ private:
void replaceWith(VSO &V, SymbolStringPtr Name, JITSymbolFlags Flags,
UnmaterializedInfoIterator NewUMII);
+ // Abandon old definition and move to materializing state.
+ // There is no need to call notifyMaterializing after this.
+ void replaceMaterializing(VSO &V, SymbolStringPtr Name,
+ JITSymbolFlags NewFlags);
+
// Notify this entry that it is being materialized.
void notifyMaterializing();
Modified: llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp?rev=330356&r1=330355&r2=330356&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp Thu Apr 19 11:42:49 2018
@@ -170,19 +170,6 @@ MaterializationResponsibility::~Material
"All symbols should have been explicitly materialized or failed");
}
-MaterializationResponsibility
-MaterializationResponsibility::takeResponsibility(SymbolNameSet Symbols) {
- SymbolFlagsMap ExtractedFlags;
-
- for (auto &S : Symbols) {
- auto I = SymbolFlags.find(S);
- ExtractedFlags.insert(*I);
- SymbolFlags.erase(I);
- }
-
- return MaterializationResponsibility(V, std::move(ExtractedFlags));
-}
-
void MaterializationResponsibility::resolve(const SymbolMap &Symbols) {
#ifndef NDEBUG
for (auto &KV : Symbols) {
@@ -212,6 +199,19 @@ void MaterializationResponsibility::noti
V.notifyMaterializationFailed(SymbolNames);
}
+MaterializationResponsibility
+MaterializationResponsibility::delegate(SymbolNameSet Symbols) {
+ SymbolFlagsMap ExtractedFlags;
+
+ for (auto &S : Symbols) {
+ auto I = SymbolFlags.find(S);
+ ExtractedFlags.insert(*I);
+ SymbolFlags.erase(I);
+ }
+
+ return MaterializationResponsibility(V, std::move(ExtractedFlags));
+}
+
VSO::Materializer::Materializer(std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility R)
: MU(std::move(MU)), R(std::move(R)) {}
@@ -239,6 +239,14 @@ VSO::SymbolTableEntry::SymbolTableEntry(
this->Flags |= JITSymbolFlags::Lazy;
}
+VSO::SymbolTableEntry::SymbolTableEntry(JITSymbolFlags Flags)
+ : Flags(Flags), Address(0) {
+ // We *don't* expect isMaterializing to be set here. That's for the VSO to do.
+ assert(!Flags.isLazy() && "Initial flags include lazy?");
+ assert(!Flags.isMaterializing() && "Initial flags include materializing");
+ this->Flags |= JITSymbolFlags::Materializing;
+}
+
VSO::SymbolTableEntry::SymbolTableEntry(JITEvaluatedSymbol Sym)
: Flags(Sym.getFlags()), Address(Sym.getAddress()) {
assert(!Flags.isLazy() && !Flags.isMaterializing() &&
@@ -295,6 +303,23 @@ void VSO::SymbolTableEntry::replaceWith(
UMII = std::move(NewUMII);
}
+void VSO::SymbolTableEntry::replaceMaterializing(VSO &V, SymbolStringPtr Name,
+ JITSymbolFlags NewFlags) {
+ assert(!NewFlags.isWeak() &&
+ "Can't define a lazy symbol in materializing mode");
+ assert(!NewFlags.isLazy() && !NewFlags.isMaterializing() &&
+ "Flags should not be in lazy or materializing state");
+ if (Flags.isLazy()) {
+ UMII->discard(V, Name);
+ if (UMII->Symbols.empty())
+ V.UnmaterializedInfos.erase(UMII);
+ }
+ destroy();
+ Flags = NewFlags;
+ Flags |= JITSymbolFlags::Materializing;
+ Address = 0;
+}
+
void VSO::SymbolTableEntry::notifyMaterializing() {
assert(Flags.isLazy() && "Can only start materializing from lazy state");
UMII.~UnmaterializedInfoIterator();
@@ -378,7 +403,6 @@ Error VSO::define(SymbolMap NewSymbols)
}
Error VSO::defineLazy(std::unique_ptr<MaterializationUnit> MU) {
-
auto UMII = UnmaterializedInfos.insert(UnmaterializedInfos.end(),
UnmaterializedInfo(std::move(MU)));
@@ -424,77 +448,6 @@ Error VSO::defineLazy(std::unique_ptr<Ma
return Err;
}
-void VSO::resolve(const SymbolMap &SymbolValues) {
- for (auto &KV : SymbolValues) {
- auto I = Symbols.find(KV.first);
- assert(I != Symbols.end() && "Resolving symbol not present in this dylib");
- I->second.resolve(*this, KV.second);
-
- auto J = MaterializingInfos.find(KV.first);
- if (J == MaterializingInfos.end())
- continue;
-
- assert(J->second.PendingFinalization.empty() &&
- "Queries already pending finalization?");
- for (auto &Q : J->second.PendingResolution)
- Q->resolve(KV.first, KV.second);
- J->second.PendingFinalization = std::move(J->second.PendingResolution);
- J->second.PendingResolution = MaterializingInfo::QueryList();
- }
-}
-
-void VSO::notifyMaterializationFailed(const SymbolNameSet &Names) {
- assert(!Names.empty() && "Failed to materialize empty set?");
-
- std::map<std::shared_ptr<AsynchronousSymbolQuery>, SymbolNameSet>
- ResolutionFailures;
- std::map<std::shared_ptr<AsynchronousSymbolQuery>, SymbolNameSet>
- FinalizationFailures;
-
- for (auto &S : Names) {
- auto I = Symbols.find(S);
- assert(I != Symbols.end() && "Symbol not present in this VSO");
-
- auto J = MaterializingInfos.find(S);
- if (J != MaterializingInfos.end()) {
- if (J->second.PendingFinalization.empty()) {
- for (auto &Q : J->second.PendingResolution)
- ResolutionFailures[Q].insert(S);
- } else {
- for (auto &Q : J->second.PendingFinalization)
- FinalizationFailures[Q].insert(S);
- }
- MaterializingInfos.erase(J);
- }
- Symbols.erase(I);
- }
-
- for (auto &KV : ResolutionFailures)
- KV.first->notifyMaterializationFailed(
- make_error<FailedToResolve>(std::move(KV.second)));
-
- for (auto &KV : FinalizationFailures)
- KV.first->notifyMaterializationFailed(
- make_error<FailedToFinalize>(std::move(KV.second)));
-}
-
-void VSO::finalize(const SymbolNameSet &SymbolsToFinalize) {
- for (auto &S : SymbolsToFinalize) {
- auto I = Symbols.find(S);
- assert(I != Symbols.end() && "Finalizing symbol not present in this dylib");
-
- auto J = MaterializingInfos.find(S);
- if (J != MaterializingInfos.end()) {
- assert(J->second.PendingResolution.empty() &&
- "Queries still pending resolution?");
- for (auto &Q : J->second.PendingFinalization)
- Q->finalizeSymbol();
- MaterializingInfos.erase(J);
- }
- I->second.finalize();
- }
-}
-
SymbolNameSet VSO::lookupFlags(SymbolFlagsMap &Flags, SymbolNameSet Names) {
for (SymbolNameSet::iterator I = Names.begin(), E = Names.end(); I != E;) {
@@ -580,6 +533,77 @@ VSO::LookupResult VSO::lookup(std::share
return {std::move(Materializers), std::move(Names)};
}
+void VSO::resolve(const SymbolMap &SymbolValues) {
+ for (auto &KV : SymbolValues) {
+ auto I = Symbols.find(KV.first);
+ assert(I != Symbols.end() && "Resolving symbol not present in this dylib");
+ I->second.resolve(*this, KV.second);
+
+ auto J = MaterializingInfos.find(KV.first);
+ if (J == MaterializingInfos.end())
+ continue;
+
+ assert(J->second.PendingFinalization.empty() &&
+ "Queries already pending finalization?");
+ for (auto &Q : J->second.PendingResolution)
+ Q->resolve(KV.first, KV.second);
+ J->second.PendingFinalization = std::move(J->second.PendingResolution);
+ J->second.PendingResolution = MaterializingInfo::QueryList();
+ }
+}
+
+void VSO::notifyMaterializationFailed(const SymbolNameSet &Names) {
+ assert(!Names.empty() && "Failed to materialize empty set?");
+
+ std::map<std::shared_ptr<AsynchronousSymbolQuery>, SymbolNameSet>
+ ResolutionFailures;
+ std::map<std::shared_ptr<AsynchronousSymbolQuery>, SymbolNameSet>
+ FinalizationFailures;
+
+ for (auto &S : Names) {
+ auto I = Symbols.find(S);
+ assert(I != Symbols.end() && "Symbol not present in this VSO");
+
+ auto J = MaterializingInfos.find(S);
+ if (J != MaterializingInfos.end()) {
+ if (J->second.PendingFinalization.empty()) {
+ for (auto &Q : J->second.PendingResolution)
+ ResolutionFailures[Q].insert(S);
+ } else {
+ for (auto &Q : J->second.PendingFinalization)
+ FinalizationFailures[Q].insert(S);
+ }
+ MaterializingInfos.erase(J);
+ }
+ Symbols.erase(I);
+ }
+
+ for (auto &KV : ResolutionFailures)
+ KV.first->notifyMaterializationFailed(
+ make_error<FailedToResolve>(std::move(KV.second)));
+
+ for (auto &KV : FinalizationFailures)
+ KV.first->notifyMaterializationFailed(
+ make_error<FailedToFinalize>(std::move(KV.second)));
+}
+
+void VSO::finalize(const SymbolNameSet &SymbolsToFinalize) {
+ for (auto &S : SymbolsToFinalize) {
+ auto I = Symbols.find(S);
+ assert(I != Symbols.end() && "Finalizing symbol not present in this dylib");
+
+ auto J = MaterializingInfos.find(S);
+ if (J != MaterializingInfos.end()) {
+ assert(J->second.PendingResolution.empty() &&
+ "Queries still pending resolution?");
+ for (auto &Q : J->second.PendingFinalization)
+ Q->finalizeSymbol();
+ MaterializingInfos.erase(J);
+ }
+ I->second.finalize();
+ }
+}
+
Expected<SymbolMap> lookup(const std::vector<VSO *> &VSOs, SymbolNameSet Names,
MaterializationDispatcher DispatchMaterialization) {
#if LLVM_ENABLE_THREADS
More information about the llvm-commits
mailing list