Remove SymbolBody::PlaceholderKind.

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
This commit is contained in:
Rui Ueyama 2016-07-18 01:35:00 +00:00
parent d6328526ba
commit e33579072d
6 changed files with 20 additions and 24 deletions

View File

@ -1465,7 +1465,6 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
case SymbolBody::LazyArchiveKind: case SymbolBody::LazyArchiveKind:
case SymbolBody::LazyObjectKind: case SymbolBody::LazyObjectKind:
break; break;
case SymbolBody::PlaceholderKind:
case SymbolBody::DefinedBitcodeKind: case SymbolBody::DefinedBitcodeKind:
llvm_unreachable("should have been replaced"); llvm_unreachable("should have been replaced");
} }

View 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 // 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. // if a new symbol with the same name is inserted into the symbol table.
template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) { template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) {
Symbol *S; Symtab.insert({Name, {-1, true}});
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);
} }
// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM. // 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. // Find an existing symbol or create and insert a new one.
template <class ELFT> template <class ELFT>
std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) { std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
unsigned NumSyms = SymVector.size(); auto P = Symtab.insert({Name, {(int)SymVector.size(), false}});
auto P = Symtab.insert(std::make_pair(Name, NumSyms)); SymIndex &V = P.first->second;
bool IsNew = P.second; bool IsNew = P.second;
if (V.Idx == -1) {
IsNew = true;
V = {(int)SymVector.size(), true};
}
Symbol *Sym; Symbol *Sym;
if (IsNew) { if (IsNew) {
Sym = new (Alloc) Symbol; Sym = new (Alloc) Symbol;
@ -196,12 +191,10 @@ std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
Sym->IsUsedInRegularObj = false; Sym->IsUsedInRegularObj = false;
Sym->ExportDynamic = false; Sym->ExportDynamic = false;
Sym->VersionId = Config->DefaultSymbolVersion; Sym->VersionId = Config->DefaultSymbolVersion;
Sym->Traced = false; Sym->Traced = V.Traced;
SymVector.push_back(Sym); SymVector.push_back(Sym);
} else { } else {
Sym = SymVector[P.first->second]; Sym = SymVector[V.Idx];
if (Sym->body()->kind() == SymbolBody::PlaceholderKind)
IsNew = true;
} }
return {Sym, IsNew}; return {Sym, IsNew};
} }
@ -449,7 +442,10 @@ template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
auto It = Symtab.find(Name); auto It = Symtab.find(Name);
if (It == Symtab.end()) if (It == Symtab.end())
return nullptr; 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. // Returns a list of defined symbols that match with a given glob pattern.

View File

@ -101,6 +101,11 @@ private:
std::map<std::string, SymbolBody *> getDemangledSyms(); 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 // 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. // 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 // The default hashing of StringRef produces different results on 32 and 64
@ -108,7 +113,7 @@ private:
// but a bit inefficient. // but a bit inefficient.
// FIXME: Experiment with passing in a custom hashing or sorting the symbols // FIXME: Experiment with passing in a custom hashing or sorting the symbols
// once symbol resolution is finished. // once symbol resolution is finished.
llvm::DenseMap<SymName, unsigned> Symtab; llvm::DenseMap<SymName, SymIndex> Symtab;
std::vector<Symbol *> SymVector; std::vector<Symbol *> SymVector;
llvm::BumpPtrAllocator Alloc; llvm::BumpPtrAllocator Alloc;

View File

@ -79,7 +79,6 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body,
case SymbolBody::LazyObjectKind: case SymbolBody::LazyObjectKind:
assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer"); assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
return 0; return 0;
case SymbolBody::PlaceholderKind:
case SymbolBody::DefinedBitcodeKind: case SymbolBody::DefinedBitcodeKind:
llvm_unreachable("should have been replaced"); llvm_unreachable("should have been replaced");
} }

View File

@ -51,7 +51,6 @@ public:
UndefinedKind, UndefinedKind,
LazyArchiveKind, LazyArchiveKind,
LazyObjectKind, LazyObjectKind,
PlaceholderKind,
}; };
SymbolBody(Kind K) : SymbolKind(K) {} SymbolBody(Kind K) : SymbolKind(K) {}

View File

@ -698,8 +698,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
std::vector<DefinedCommon *> CommonSymbols; std::vector<DefinedCommon *> CommonSymbols;
for (Symbol *S : Symtab.getSymbols()) { for (Symbol *S : Symtab.getSymbols()) {
SymbolBody *Body = S->body(); SymbolBody *Body = S->body();
if (Body->kind() == SymbolBody::PlaceholderKind)
continue;
// We only report undefined symbols in regular objects. This means that we // 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. // will accept an undefined reference in bitcode if it can be optimized out.