]> granicus.if.org Git - llvm/commitdiff
dwarfdump: Delay parsing abbreviations until they're needed
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 19 Sep 2017 15:13:55 +0000 (15:13 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 19 Sep 2017 15:13:55 +0000 (15:13 +0000)
This speeds up dumping specific DIEs by not parsing abbreviations for
units that are not used.

(this is also handy to have in eventually to speed up llvm-symbolizer
for .dwp files, where parsing most of the DWP file can be avoided by
using the index)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313635 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
include/llvm/DebugInfo/DWARF/DWARFUnit.h
lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
lib/DebugInfo/DWARF/DWARFUnit.cpp

index 963f285c109c996b10d89519d69c29aa29a212b0..d277ec382ba56be432497b84179e9414311f061a 100644 (file)
@@ -56,8 +56,9 @@ class DWARFDebugAbbrev {
   using DWARFAbbreviationDeclarationSetMap =
       std::map<uint64_t, DWARFAbbreviationDeclarationSet>;
 
-  DWARFAbbreviationDeclarationSetMap AbbrDeclSets;
+  mutable DWARFAbbreviationDeclarationSetMap AbbrDeclSets;
   mutable DWARFAbbreviationDeclarationSetMap::const_iterator PrevAbbrOffsetPos;
+  mutable Optional<DataExtractor> Data;
 
 public:
   DWARFDebugAbbrev();
@@ -66,10 +67,11 @@ public:
   getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const;
 
   void dump(raw_ostream &OS) const;
+  void parse() const;
   void extract(DataExtractor Data);
-  bool empty() const { return begin() == end(); }
 
   DWARFAbbreviationDeclarationSetMap::const_iterator begin() const {
+    parse();
     return AbbrDeclSets.begin();
   }
 
index 6e85e71e5b34ca219962aede36e937af648967b4..ebe8cc66d4f703a8ef828c3222898eaac63212a1 100644 (file)
@@ -139,7 +139,8 @@ class DWARFUnit {
 
   uint32_t Offset;
   uint32_t Length;
-  const DWARFAbbreviationDeclarationSet *Abbrevs;
+  mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
+  uint64_t AbbrOffset;
   uint8_t UnitType;
   llvm::Optional<BaseAddress> BaseAddr;
   /// The compile unit debug information entry items.
@@ -231,9 +232,7 @@ public:
     return FormParams.getDwarfOffsetByteSize();
   }
 
-  const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
-    return Abbrevs;
-  }
+  const DWARFAbbreviationDeclarationSet *getAbbreviations() const;
 
   uint8_t getUnitType() const { return UnitType; }
 
index 76dd2e4c21bcc0f3058c3c5542e31d499437a3d5..4830c36a8ee791209e558571c8e3b5d2995e4bb0 100644 (file)
@@ -68,9 +68,7 @@ DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
   return &Decls[AbbrCode - FirstAbbrCode];
 }
 
-DWARFDebugAbbrev::DWARFDebugAbbrev() {
-  clear();
-}
+DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
 
 void DWARFDebugAbbrev::clear() {
   AbbrDeclSets.clear();
@@ -79,18 +77,29 @@ void DWARFDebugAbbrev::clear() {
 
 void DWARFDebugAbbrev::extract(DataExtractor Data) {
   clear();
+  this->Data = Data;
+}
 
+void DWARFDebugAbbrev::parse() const {
+  if (!Data)
+    return;
   uint32_t Offset = 0;
   DWARFAbbreviationDeclarationSet AbbrDecls;
-  while (Data.isValidOffset(Offset)) {
+  auto I = AbbrDeclSets.begin();
+  while (Data->isValidOffset(Offset)) {
+    while (I != AbbrDeclSets.end() && I->first < Offset)
+      ++I;
     uint32_t CUAbbrOffset = Offset;
-    if (!AbbrDecls.extract(Data, &Offset))
+    if (!AbbrDecls.extract(*Data, &Offset))
       break;
-    AbbrDeclSets[CUAbbrOffset] = std::move(AbbrDecls);
+    AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
   }
+  Data = None;
 }
 
 void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
+  parse();
+
   if (AbbrDeclSets.empty()) {
     OS << "< EMPTY >\n";
     return;
@@ -115,5 +124,16 @@ DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
     return &(Pos->second);
   }
 
+  if (Data && CUAbbrOffset < Data->getData().size()) {
+    uint32_t Offset = CUAbbrOffset;
+    DWARFAbbreviationDeclarationSet AbbrDecls;
+    if (!AbbrDecls.extract(*Data, &Offset))
+      return nullptr;
+    PrevAbbrOffsetPos =
+        AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
+            .first;
+    return &PrevAbbrOffsetPos->second;
+  }
+
   return nullptr;
 }
index 813960ca95d783e5ebcf45f0c66a8ee2449462d6..4467b4ac30944080b4cd136e482b5139b0867a2b 100644 (file)
@@ -94,7 +94,6 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
   // FIXME: Support DWARF64.
   FormParams.Format = DWARF32;
   FormParams.Version = debug_info.getU16(offset_ptr);
-  uint64_t AbbrOffset;
   if (FormParams.Version >= 5) {
     UnitType = debug_info.getU8(offset_ptr);
     FormParams.AddrSize = debug_info.getU8(offset_ptr);
@@ -124,9 +123,7 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
 
   // Keep track of the highest DWARF version we encounter across all units.
   Context.setMaxVersionIfGreater(getVersion());
-
-  Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
-  return Abbrevs != nullptr;
+  return true;
 }
 
 bool DWARFUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
@@ -452,3 +449,9 @@ DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
   }
   return DWARFDie();
 }
+
+const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
+  if (!Abbrevs)
+    Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
+  return Abbrevs;
+}