[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