[PATCH] llvm-symbolizer: speedup symbol lookup

Dmitry Vyukov dvyukov at google.com
Thu Feb 14 02:47:16 PST 2013


Hi samsonov,

replace linear scan with std::map

http://llvm-reviews.chandlerc.com/D407

Files:
  llvm-symbolizer/LLVMSymbolize.h
  llvm-symbolizer/LLVMSymbolize.cpp

Index: llvm-symbolizer/LLVMSymbolize.h
===================================================================
--- llvm-symbolizer/LLVMSymbolize.h
+++ llvm-symbolizer/LLVMSymbolize.h
@@ -63,11 +63,8 @@
 };
 
 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 @@
   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 Variables;
 };
 
 }  // namespace symbolize
Index: llvm-symbolizer/LLVMSymbolize.cpp
===================================================================
--- llvm-symbolizer/LLVMSymbolize.cpp
+++ llvm-symbolizer/LLVMSymbolize.cpp
@@ -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,56 @@
                         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 : Variables;
+    SymbolDesc d = {SymbolAddress, SymbolAddress + SymbolSize};
+    m.insert(std::make_pair(d, 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 : Variables;
+  SymbolDesc d = {Address, Address + 1};
+  SymbolMapTy::const_iterator it = m.find(d);
+  if (it == m.end())
+    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 +150,6 @@
                                 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 +220,6 @@
     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 +231,7 @@
   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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D407.1.patch
Type: text/x-patch
Size: 6013 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130214/e3a56f06/attachment.bin>


More information about the llvm-commits mailing list