Improve DWARF parsing and accessing by 1% to 2%
authorGreg Clayton <clayborg@gmail.com>
Thu, 30 May 2019 15:21:23 +0000 (15:21 +0000)
committerGreg Clayton <clayborg@gmail.com>
Thu, 30 May 2019 15:21:23 +0000 (15:21 +0000)
When LLDB first started we didn't have our mmap of the DWARF data done correctly and if the backing file would change we would get live changes as the file changed and it would cause problems. We now mmap correctly and do not run into these issues. There was legacy code in DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(...) that would always extract the abbrev index each time the function was called to verify that DWARF data hadn't changed and a warning was emitted if it did. We no longer need this and the code was removed. The other thing this function did when it parsed the abbrev index was give us the offset of the first attribute bytes by adding the LEB128 size to the offset. This required an extra parameter to DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(...) which is now removed. I added "lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const" which calculates this when we need it and modified all sites that need the offset to call it.

Now that we aren't decoding and verifying the abbrev index, it speeds up DWARF access by 1% to 2%.

Differential Revision: https://reviews.llvm.org/D62634

llvm-svn: 362103

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h

index 76aaf52..c8684d2 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <algorithm>
 
+#include "llvm/Support/LEB128.h"
+
 #include "lldb/Core/Module.h"
 #include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -239,15 +241,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
   std::vector<DIERef> die_refs;
   bool set_frame_base_loclist_addr = false;
 
-  lldb::offset_t offset;
-  const DWARFAbbreviationDeclaration *abbrevDecl =
-      GetAbbreviationDeclarationPtr(cu, offset);
+  auto abbrevDecl = GetAbbreviationDeclarationPtr(cu);
 
   SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF();
   lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
 
   if (abbrevDecl) {
     const DWARFDataExtractor &debug_info_data = cu->GetData();
+    lldb::offset_t offset = GetFirstAttributeOffset();
 
     if (!debug_info_data.ValidOffset(offset))
       return false;
@@ -561,13 +562,10 @@ void DWARFDebugInfoEntry::DumpAttribute(
 size_t DWARFDebugInfoEntry::GetAttributes(
     const DWARFUnit *cu, DWARFAttributes &attributes,
     uint32_t curr_depth) const {
-  const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
-  lldb::offset_t offset = 0;
-  if (cu)
-    abbrevDecl = GetAbbreviationDeclarationPtr(cu, offset);
-
+  auto abbrevDecl = GetAbbreviationDeclarationPtr(cu);
   if (abbrevDecl) {
     const DWARFDataExtractor &debug_info_data = cu->GetData();
+    lldb::offset_t offset = GetFirstAttributeOffset();
 
     const uint32_t num_attributes = abbrevDecl->NumAttributes();
     for (uint32_t i = 0; i < num_attributes; ++i) {
@@ -631,15 +629,14 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
                              form_value, end_attr_offset_ptr,
                              check_specification_or_abstract_origin);
 
-  lldb::offset_t offset;
-  const DWARFAbbreviationDeclaration *abbrevDecl =
-      GetAbbreviationDeclarationPtr(cu, offset);
+  auto abbrevDecl = GetAbbreviationDeclarationPtr(cu);
 
   if (abbrevDecl) {
     uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
 
     if (attr_idx != DW_INVALID_INDEX) {
       const DWARFDataExtractor &debug_info_data = cu->GetData();
+      lldb::offset_t offset = GetFirstAttributeOffset();
 
       uint32_t idx = 0;
       while (idx < attr_idx)
@@ -1244,35 +1241,17 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
   return found_address;
 }
 
+lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
+  return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
+}
+
 const DWARFAbbreviationDeclaration *
-DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
-    const DWARFUnit *cu, lldb::offset_t &offset) const {
+DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
   if (cu) {
-    offset = GetOffset();
-
     const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
-    if (abbrev_set) {
-      const DWARFAbbreviationDeclaration *abbrev_decl =
-          abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
-      if (abbrev_decl) {
-        // Make sure the abbreviation code still matches. If it doesn't and the
-        // DWARF data was mmap'ed, the backing file might have been modified
-        // which is bad news.
-        const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset);
-
-        if (abbrev_decl->Code() == abbrev_code)
-          return abbrev_decl;
-
-        SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF();
-
-        dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
-            "0x%8.8x: the DWARF debug information has been modified (abbrev "
-            "code was %u, and is now %u)",
-            GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code);
-      }
-    }
+    if (abbrev_set)
+      return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
   }
-  offset = DW_INVALID_OFFSET;
   return nullptr;
 }
 
index 1d2eb31..77a9757 100644 (file)
@@ -118,8 +118,9 @@ public:
       lldb_private::DWARFExpression *frame_base = nullptr) const;
 
   const DWARFAbbreviationDeclaration *
-  GetAbbreviationDeclarationPtr(const DWARFUnit *cu,
-                                lldb::offset_t &offset) const;
+  GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;
+
+  lldb::offset_t GetFirstAttributeOffset() const;
 
   dw_tag_t Tag() const { return m_tag; }