[llvm] r175158 - llvm-symbolizer: speedup symbol lookup

Dmitry Vyukov dvyukov at google.com
Thu Feb 14 05:06:18 PST 2013


Author: dvyukov
Date: Thu Feb 14 07:06:18 2013
New Revision: 175158

URL: http://llvm.org/viewvc/llvm-project?rev=175158&view=rev
Log:
llvm-symbolizer: speedup symbol lookup

Modified:
    llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
    llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h

Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp?rev=175158&r1=175157&r2=175158&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp (original)
+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp Thu Feb 14 07:06:18 2013
@@ -21,6 +21,12 @@
 namespace llvm {
 namespace symbolize {
 
+static bool error(error_code ec) {
+  if (!ec) return false;
+  errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
+  return true;
+}
+
 static uint32_t getDILineInfoSpecifierFlags(
     const LLVMSymbolizer::Options &Opts) {
   uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
@@ -37,6 +43,58 @@ static void patchFunctionNameInDILineInf
                         LineInfo.getLine(), LineInfo.getColumn());
 }
 
+ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
+    : Module(Obj)
+    , DebugInfoContext(DICtx) {
+  error_code ec;
+  for (symbol_iterator si = Module->begin_symbols(),
+                       se = Module->end_symbols();
+                       si != se; si.increment(ec)) {
+    if (error(ec))
+      return;
+    SymbolRef::Type SymbolType;
+    if (error(si->getType(SymbolType)))
+      continue;
+    if (SymbolType != SymbolRef::ST_Function
+        && SymbolType != SymbolRef::ST_Data)
+      continue;
+    uint64_t SymbolAddress;
+    if (error(si->getAddress(SymbolAddress))
+        || SymbolAddress == UnknownAddressOrSize)
+      continue;
+    uint64_t SymbolSize;
+    if (error(si->getSize(SymbolSize))
+        || SymbolSize == UnknownAddressOrSize)
+      continue;
+    StringRef SymbolName;
+    if (error(si->getName(SymbolName)))
+      continue;
+    // FIXME: If a function has alias, there are two entries in symbol table
+    // with same address size. Make sure we choose the correct one.
+    SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ?
+        Functions : Objects;
+    SymbolDesc SD = {SymbolAddress, SymbolAddress + SymbolSize};
+    M.insert(std::make_pair(SD, SymbolName));
+  }
+}
+
+bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
+                                        std::string &Name, uint64_t &Addr,
+                                        uint64_t &Size) const {
+  const SymbolMapTy& M = Type == SymbolRef::ST_Function ?
+      Functions : Objects;
+  SymbolDesc SD = {Address, Address + 1};
+  SymbolMapTy::const_iterator it = M.find(SD);
+  if (it == M.end())
+    return false;
+  if (Address < it->first.Addr || Address >= it->first.AddrEnd)
+    return false;
+  Name = it->second.str();
+  Addr = it->first.Addr;
+  Size = it->first.AddrEnd - it->first.Addr;
+  return true;
+}
+
 DILineInfo ModuleInfo::symbolizeCode(uint64_t ModuleOffset,
     const LLVMSymbolizer::Options& Opts) const {
   DILineInfo LineInfo;
@@ -94,44 +152,6 @@ bool ModuleInfo::symbolizeData(uint64_t
                                 ModuleOffset, Name, Start, Size);
 }
 
-static bool error(error_code ec) {
-  if (!ec) return false;
-  errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
-  return true;
-}
-
-bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
-                                        std::string &Name, uint64_t &Addr,
-                                        uint64_t &Size) const {
-  assert(Module);
-  error_code ec;
-  for (symbol_iterator si = Module->begin_symbols(),
-                       se = Module->end_symbols();
-                       si != se; si.increment(ec)) {
-    if (error(ec)) return false;
-    uint64_t SymbolAddress;
-    uint64_t SymbolSize;
-    SymbolRef::Type SymbolType;
-    if (error(si->getAddress(SymbolAddress)) ||
-        SymbolAddress == UnknownAddressOrSize) continue;
-    if (error(si->getSize(SymbolSize)) ||
-        SymbolSize == UnknownAddressOrSize) continue;
-    if (error(si->getType(SymbolType))) continue;
-    // FIXME: If a function has alias, there are two entries in symbol table
-    // with same address size. Make sure we choose the correct one.
-    if (SymbolAddress <= Address && Address < SymbolAddress + SymbolSize &&
-        SymbolType == Type) {
-      StringRef SymbolName;
-      if (error(si->getName(SymbolName))) continue;
-      Name = SymbolName.str();
-      Addr = SymbolAddress;
-      Size = SymbolSize;
-      return true;
-    }
-  }
-  return false;
-}
-
 const char LLVMSymbolizer::kBadString[] = "??";
 
 std::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
@@ -202,7 +222,6 @@ ModuleInfo *LLVMSymbolizer::getOrCreateM
     return I->second;
 
   ObjectFile *Obj = getObjectFile(ModuleName);
-  ObjectFile *DbgObj = Obj;
   if (Obj == 0) {
     // Module name doesn't point to a valid object file.
     Modules.insert(make_pair(ModuleName, (ModuleInfo*)0));
@@ -214,6 +233,7 @@ ModuleInfo *LLVMSymbolizer::getOrCreateM
   if (getObjectEndianness(Obj, IsLittleEndian)) {
     // On Darwin we may find DWARF in separate object file in
     // resource directory.
+    ObjectFile *DbgObj = Obj;
     if (isa<MachOObjectFile>(Obj)) {
       const std::string &ResourceName = getDarwinDWARFResourceForModule(
           ModuleName);

Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h?rev=175158&r1=175157&r2=175158&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h (original)
+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h Thu Feb 14 07:06:18 2013
@@ -63,11 +63,8 @@ private:
 };
 
 class ModuleInfo {
-  OwningPtr<ObjectFile> Module;
-  OwningPtr<DIContext> DebugInfoContext;
  public:
-  ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
-      : Module(Obj), DebugInfoContext(DICtx) {}
+  ModuleInfo(ObjectFile *Obj, DIContext *DICtx);
 
   DILineInfo symbolizeCode(
       uint64_t ModuleOffset, const LLVMSymbolizer::Options& Opts) const;
@@ -80,6 +77,19 @@ class ModuleInfo {
   bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
                               std::string &Name, uint64_t &Addr,
                               uint64_t &Size) const;
+  OwningPtr<ObjectFile> Module;
+  OwningPtr<DIContext> DebugInfoContext;
+
+  struct SymbolDesc {
+    uint64_t Addr;
+    uint64_t AddrEnd;
+    friend bool operator<(const SymbolDesc& s1, const SymbolDesc& s2) {
+      return s1.AddrEnd <= s2.Addr;
+    }
+  };
+  typedef std::map<SymbolDesc, StringRef> SymbolMapTy;
+  SymbolMapTy Functions;
+  SymbolMapTy Objects;
 };
 
 }  // namespace symbolize





More information about the llvm-commits mailing list