[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