[PECOFF] Split ExportedSymbolRenameFile.
authorRui Ueyama <ruiu@google.com>
Thu, 17 Jul 2014 22:17:10 +0000 (22:17 +0000)
committerRui Ueyama <ruiu@google.com>
Thu, 17 Jul 2014 22:17:10 +0000 (22:17 +0000)
The code to manage resolvable symbols is now separated from
ExportedSymbolRenameFile so that other class can reuse it.
I'm planning to use it to find the entry function symbol
based on resolvable symbols.

llvm-svn: 213322

lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h

index 931b1e4..131d55d 100644 (file)
@@ -161,6 +161,45 @@ private:
   mutable llvm::BumpPtrAllocator _alloc;
 };
 
+class ResolvableSymbols {
+public:
+  void add(File *file) {
+    std::lock_guard<std::mutex> lock(_mutex);
+    if (_seen.count(file) > 0)
+      return;
+    _seen.insert(file);
+    _queue.insert(file);
+  }
+
+  const std::set<std::string> &defined() {
+    readAllSymbols();
+    return _defined;
+  }
+
+private:
+  // Files are read lazily, so that it has no runtime overhead if
+  // no one accesses this class.
+  void readAllSymbols() {
+    std::lock_guard<std::mutex> lock(_mutex);
+    for (File *file : _queue) {
+      if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
+        for (const std::string &sym : archive->getDefinedSymbols())
+          _defined.insert(sym);
+        continue;
+      }
+      for (const DefinedAtom *atom : file->defined())
+        if (!atom->name().empty())
+          _defined.insert(atom->name());
+    }
+    _queue.clear();
+  }
+
+  std::set<std::string> _defined;
+  std::set<File *> _seen;
+  std::set<File *> _queue;
+  std::mutex _mutex;
+};
+
 // A ExportedSymbolRenameFile is a virtual archive file for dllexported symbols.
 //
 // One usually has to specify the exact symbol name to resolve it. That's true
@@ -199,18 +238,11 @@ public:
       _exportedSyms.insert(desc.name);
   }
 
-  void addResolvableSymbols(File *file) {
-    std::lock_guard<std::mutex> lock(_mutex);
-    if (_seen.count(file) > 0)
-      return;
-    _seen.insert(file);
-    _queue.insert(file);
-  }
+  void addResolvableSymbols(File *file) { _syms.add(file); }
 
   const File *find(StringRef sym, bool dataSymbolOnly) const override {
     if (_exportedSyms.count(sym) == 0)
       return nullptr;
-    readAllSymbols();
     std::string replace;
     if (!findSymbolWithAtsignSuffix(sym.str(), replace))
       return nullptr;
@@ -218,29 +250,13 @@ public:
   }
 
 private:
-  // Files are read lazily, so that it has no runtime overhead if
-  // there's no dllexported stdcall functions.
-  void readAllSymbols() const {
-    std::lock_guard<std::mutex> lock(_mutex);
-    for (File *file : _queue) {
-      if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
-        for (const std::string &sym : archive->getDefinedSymbols())
-          _defined.insert(sym);
-        continue;
-      }
-      for (const DefinedAtom *atom : file->defined())
-        if (!atom->name().empty())
-          _defined.insert(atom->name());
-    }
-    _queue.clear();
-  }
-
   // Find a symbol that starts with a given symbol name followed
   // by @number suffix.
   bool findSymbolWithAtsignSuffix(std::string sym, std::string &res) const {
     sym.append("@");
-    auto it = _defined.lower_bound(sym);
-    for (auto e = _defined.end(); it != e; ++it) {
+    const std::set<std::string> &defined = _syms.defined();
+    auto it = defined.lower_bound(sym);
+    for (auto e = defined.end(); it != e; ++it) {
       if (!StringRef(*it).startswith(sym))
         return false;
       if (it->size() == sym.size())
@@ -255,10 +271,7 @@ private:
   }
 
   std::set<std::string> _exportedSyms;
-  std::set<File *> _seen;
-  mutable std::set<std::string> _defined;
-  mutable std::set<File *> _queue;
-  mutable std::mutex _mutex;
+  mutable ResolvableSymbols _syms;
   mutable llvm::BumpPtrAllocator _alloc;
 };