[lld] r218343 - [PECOFF] Change export table type.

Rui Ueyama ruiu at google.com
Tue Sep 23 17:09:37 PDT 2014


Author: ruiu
Date: Tue Sep 23 19:09:36 2014
New Revision: 218343

URL: http://llvm.org/viewvc/llvm-project?rev=218343&view=rev
Log:
[PECOFF] Change export table type.

This patch changes the type of export table set from std::set to
std::vector. The new code is slightly inefficient, but because
export table elements are actually mutable, std::vector is better
here. No functionality change.

Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=218343&r1=218342&r2=218343&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Tue Sep 23 19:09:36 2014
@@ -252,8 +252,8 @@ public:
   ArrayRef<uint8_t> getDosStub() const { return _dosStub; }
 
   void addDllExport(ExportDesc &desc);
-  std::set<ExportDesc> &getDllExports() { return _dllExports; }
-  const std::set<ExportDesc> &getDllExports() const { return _dllExports; }
+  std::vector<ExportDesc> &getDllExports() { return _dllExports; }
+  const std::vector<ExportDesc> &getDllExports() const { return _dllExports; }
 
   StringRef allocate(StringRef ref) const {
     _allocMutex.lock();
@@ -385,7 +385,7 @@ private:
   std::map<std::string, uint32_t> _sectionClearMask;
 
   // DLLExport'ed symbols.
-  std::set<ExportDesc> _dllExports;
+  std::vector<ExportDesc> _dllExports;
 
   // List of files that will be removed on destruction.
   std::vector<std::unique_ptr<llvm::FileRemover> > _tempFiles;

Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp?rev=218343&r1=218342&r2=218343&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp Tue Sep 23 19:09:36 2014
@@ -29,17 +29,21 @@ namespace lld {
 namespace pecoff {
 
 static void assignOrdinals(PECOFFLinkingContext &ctx) {
-  std::set<PECOFFLinkingContext::ExportDesc> exports;
+  std::vector<PECOFFLinkingContext::ExportDesc> &exports = ctx.getDllExports();
   int maxOrdinal = -1;
-  for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports())
+  for (PECOFFLinkingContext::ExportDesc &desc : exports)
     maxOrdinal = std::max(maxOrdinal, desc.ordinal);
+
+  std::sort(exports.begin(), exports.end(),
+            [](const PECOFFLinkingContext::ExportDesc &a,
+               const PECOFFLinkingContext::ExportDesc &b) {
+    return a.name.compare(b.name) < 0;
+  });
+
   int nextOrdinal = (maxOrdinal == -1) ? 1 : (maxOrdinal + 1);
-  for (PECOFFLinkingContext::ExportDesc desc : ctx.getDllExports()) {
+  for (PECOFFLinkingContext::ExportDesc &desc : exports)
     if (desc.ordinal == -1)
       desc.ordinal = nextOrdinal++;
-    exports.insert(desc);
-  }
-  ctx.getDllExports().swap(exports);
 }
 
 static StringRef removeStdcallSuffix(StringRef sym) {
@@ -63,8 +67,7 @@ static bool getExportedAtoms(PECOFFLinki
   for (const DefinedAtom *atom : file->defined())
     definedAtoms[removeStdcallSuffix(atom->name())] = atom;
 
-  std::set<PECOFFLinkingContext::ExportDesc> exports;
-  for (PECOFFLinkingContext::ExportDesc desc : ctx.getDllExports()) {
+  for (PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
     auto it = definedAtoms.find(desc.name);
     if (it == definedAtoms.end()) {
       llvm::errs() << "Symbol <" << desc.name
@@ -82,9 +85,7 @@ static bool getExportedAtoms(PECOFFLinki
 
     if (desc.externalName.empty())
       desc.externalName = removeLeadingUnderscore(atom->name());
-    exports.insert(desc);
   }
-  ctx.getDllExports().swap(exports);
   std::sort(ret.begin(), ret.end(),
             [](const TableEntry &a, const TableEntry &b) {
     return a.exportName.compare(b.exportName) < 0;

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=218343&r1=218342&r2=218343&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Tue Sep 23 19:09:36 2014
@@ -272,11 +272,23 @@ static bool sameExportDesc(const PECOFFL
 
 void PECOFFLinkingContext::addDllExport(ExportDesc &desc) {
   addInitialUndefinedSymbol(allocate(desc.name));
-  auto existing = _dllExports.insert(desc);
-  if (existing.second || sameExportDesc(*existing.first, desc))
+
+  // Scan the vector to look for existing entry. It's not very fast,
+  // but because the number of exported symbol is usually not that
+  // much, it should be okay.
+  ExportDesc *existing = nullptr;
+  for (ExportDesc &e : _dllExports) {
+    if (e.name == desc.name) {
+      existing = &e;
+      break;
+    }
+  }
+  if (existing && !sameExportDesc(*existing, desc)) {
+    llvm::errs() << "Export symbol '" << desc.name
+                 << "' specified more than once.\n";
     return;
-  llvm::errs() << "Export symbol '" << desc.name
-               << "' specified more than once.\n";
+  }
+  _dllExports.push_back(desc);
 }
 
 std::string PECOFFLinkingContext::getOutputImportLibraryPath() const {

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=218343&r1=218342&r2=218343&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Tue Sep 23 19:09:36 2014
@@ -158,43 +158,39 @@ TEST_F(WinLinkParserTest, AlternateName)
 
 TEST_F(WinLinkParserTest, Export) {
   EXPECT_TRUE(parse("link.exe", "/export:foo", "a.out", nullptr));
-  const std::set<PECOFFLinkingContext::ExportDesc> &exports =
+  const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
       _context.getDllExports();
   EXPECT_EQ(1U, exports.size());
-  auto it = exports.begin();
-  EXPECT_EQ("_foo", it->name);
-  EXPECT_EQ(-1, it->ordinal);
-  EXPECT_FALSE(it->noname);
-  EXPECT_FALSE(it->isData);
+  EXPECT_EQ("_foo", exports[0].name);
+  EXPECT_EQ(-1, exports[0].ordinal);
+  EXPECT_FALSE(exports[0].noname);
+  EXPECT_FALSE(exports[0].isData);
 }
 
 TEST_F(WinLinkParserTest, ExportWithOptions) {
   EXPECT_TRUE(parse("link.exe", "/export:foo, at 8,noname,data",
                     "/export:bar, at 10,data", "a.out", nullptr));
-  const std::set<PECOFFLinkingContext::ExportDesc> &exports =
+  const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
       _context.getDllExports();
   EXPECT_EQ(2U, exports.size());
-  auto it = exports.begin();
-  EXPECT_EQ("_bar", it->name);
-  EXPECT_EQ(10, it->ordinal);
-  EXPECT_FALSE(it->noname);
-  EXPECT_TRUE(it->isData);
-  ++it;
-  EXPECT_EQ("_foo", it->name);
-  EXPECT_EQ(8, it->ordinal);
-  EXPECT_TRUE(it->noname);
-  EXPECT_TRUE(it->isData);
+  EXPECT_EQ("_foo", exports[0].name);
+  EXPECT_EQ(8, exports[0].ordinal);
+  EXPECT_TRUE(exports[0].noname);
+  EXPECT_TRUE(exports[0].isData);
+  EXPECT_EQ("_bar", exports[1].name);
+  EXPECT_EQ(10, exports[1].ordinal);
+  EXPECT_FALSE(exports[1].noname);
+  EXPECT_TRUE(exports[1].isData);
 }
 
 TEST_F(WinLinkParserTest, ExportDuplicateExports) {
   EXPECT_TRUE(
       parse("link.exe", "/export:foo", "/export:foo, at 2", "a.out", nullptr));
-  const std::set<PECOFFLinkingContext::ExportDesc> &exports =
+  const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
       _context.getDllExports();
   EXPECT_EQ(1U, exports.size());
-  auto it = exports.begin();
-  EXPECT_EQ("_foo", it->name);
-  EXPECT_EQ(-1, it->ordinal);
+  EXPECT_EQ("_foo", exports[0].name);
+  EXPECT_EQ(-1, exports[0].ordinal);
 }
 
 TEST_F(WinLinkParserTest, ExportDuplicateOrdinals) {





More information about the llvm-commits mailing list