Remove SymbolBody::PlaceholderKind.
authorRui Ueyama <ruiu@google.com>
Mon, 18 Jul 2016 01:35:00 +0000 (01:35 +0000)
committerRui Ueyama <ruiu@google.com>
Mon, 18 Jul 2016 01:35:00 +0000 (01:35 +0000)
In the last patch for --trace-symbol, I introduced a new symbol type
PlaceholderKind and store it to SymVector storage. It made all code
that iterates over SymVector to recognize and skip PlaceholderKind
symbols. I found that that's annoying.

In this patch, I removed PlaceholderKind and stop storing them to SymVector.
Now the information whether a symbol is being watched by --trace-symbol
is stored to the Symtab hash table.

llvm-svn: 275747

lld/ELF/OutputSections.cpp
lld/ELF/SymbolTable.cpp
lld/ELF/SymbolTable.h
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/ELF/Writer.cpp

index fd97c6b..50b9401 100644 (file)
@@ -1465,7 +1465,6 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
   case SymbolBody::LazyArchiveKind:
   case SymbolBody::LazyObjectKind:
     break;
-  case SymbolBody::PlaceholderKind:
   case SymbolBody::DefinedBitcodeKind:
     llvm_unreachable("should have been replaced");
   }
index d02c8d6..78c1298 100644 (file)
@@ -143,17 +143,7 @@ DefinedRegular<ELFT> *SymbolTable<ELFT>::addIgnored(StringRef Name,
 // Set a flag for --trace-symbol so that we can print out a log message
 // if a new symbol with the same name is inserted into the symbol table.
 template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) {
-  Symbol *S;
-  bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name);
-  assert(WasInserted);
-
-  S->Traced = true;
-
-  // We created a new symbol just to turn on Trace flag.
-  // Write a dummy SymbolBody so that trace() does not affect
-  // normal symbol operations.
-  new (S->body()) SymbolBody(SymbolBody::PlaceholderKind);
+  Symtab.insert({Name, {-1, true}});
 }
 
 // Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
@@ -184,10 +174,15 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
 // Find an existing symbol or create and insert a new one.
 template <class ELFT>
 std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
-  unsigned NumSyms = SymVector.size();
-  auto P = Symtab.insert(std::make_pair(Name, NumSyms));
+  auto P = Symtab.insert({Name, {(int)SymVector.size(), false}});
+  SymIndex &V = P.first->second;
   bool IsNew = P.second;
 
+  if (V.Idx == -1) {
+    IsNew = true;
+    V = {(int)SymVector.size(), true};
+  }
+
   Symbol *Sym;
   if (IsNew) {
     Sym = new (Alloc) Symbol;
@@ -196,12 +191,10 @@ std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
     Sym->IsUsedInRegularObj = false;
     Sym->ExportDynamic = false;
     Sym->VersionId = Config->DefaultSymbolVersion;
-    Sym->Traced = false;
+    Sym->Traced = V.Traced;
     SymVector.push_back(Sym);
   } else {
-    Sym = SymVector[P.first->second];
-    if (Sym->body()->kind() == SymbolBody::PlaceholderKind)
-      IsNew = true;
+    Sym = SymVector[V.Idx];
   }
   return {Sym, IsNew};
 }
@@ -449,7 +442,10 @@ template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
   auto It = Symtab.find(Name);
   if (It == Symtab.end())
     return nullptr;
-  return SymVector[It->second]->body();
+  SymIndex V = It->second;
+  if (V.Idx == -1)
+    return nullptr;
+  return SymVector[V.Idx]->body();
 }
 
 // Returns a list of defined symbols that match with a given glob pattern.
index 727f2e9..40415b6 100644 (file)
@@ -101,6 +101,11 @@ private:
 
   std::map<std::string, SymbolBody *> getDemangledSyms();
 
+  struct SymIndex {
+    int Idx : 31;
+    unsigned Traced : 1;
+  };
+
   // The order the global symbols are in is not defined. We can use an arbitrary
   // order, but it has to be reproducible. That is true even when cross linking.
   // The default hashing of StringRef produces different results on 32 and 64
@@ -108,7 +113,7 @@ private:
   // but a bit inefficient.
   // FIXME: Experiment with passing in a custom hashing or sorting the symbols
   // once symbol resolution is finished.
-  llvm::DenseMap<SymName, unsigned> Symtab;
+  llvm::DenseMap<SymName, SymIndex> Symtab;
   std::vector<Symbol *> SymVector;
   llvm::BumpPtrAllocator Alloc;
 
index 4f95281..d6a605d 100644 (file)
@@ -79,7 +79,6 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body,
   case SymbolBody::LazyObjectKind:
     assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
     return 0;
-  case SymbolBody::PlaceholderKind:
   case SymbolBody::DefinedBitcodeKind:
     llvm_unreachable("should have been replaced");
   }
index 6847f46..aa9a87d 100644 (file)
@@ -51,7 +51,6 @@ public:
     UndefinedKind,
     LazyArchiveKind,
     LazyObjectKind,
-    PlaceholderKind,
   };
 
   SymbolBody(Kind K) : SymbolKind(K) {}
index 60152fe..387bec3 100644 (file)
@@ -698,8 +698,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
   std::vector<DefinedCommon *> CommonSymbols;
   for (Symbol *S : Symtab.getSymbols()) {
     SymbolBody *Body = S->body();
-    if (Body->kind() == SymbolBody::PlaceholderKind)
-      continue;
 
     // We only report undefined symbols in regular objects. This means that we
     // will accept an undefined reference in bitcode if it can be optimized out.