Cleanup fixed form sizes.
authorGreg Clayton <clayborg@gmail.com>
Fri, 24 May 2019 22:08:50 +0000 (22:08 +0000)
committerGreg Clayton <clayborg@gmail.com>
Fri, 24 May 2019 22:08:50 +0000 (22:08 +0000)
The fix form sizes use to have two arrays: one for 4 byte addresses and in for 8 byte addresses. The table had an issue where DW_FORM_flag_present wasn't being represented as a fixed size form because its actual size _is_ zero and zero was used to indicate the form isn't fixed in size. Any code that needed to quickly access the DWARF had to get a FixedFormSizes instance using the address byte size.

This fix cleans things up by adding a DWARFFormValue::GetFixedSize() both as a static method and as a member function on DWARFFormValue. It correctly can indicate if a form size is zero. This cleanup is a precursor to a follow up patch where I hope to speed up DWARF parsing.

I verified performance doesn't regress by loading hundreds of DWARF files and setting a breakpoint by file and line and by name in files that do not have DWARF indexes. Performance remained consistent between the two approaches.

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

llvm-svn: 361675

lldb/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme
lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

index d31912e..5185237 100644 (file)
@@ -45,7 +45,7 @@
       buildConfiguration = "DebugClang"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      launchStyle = "1"
+      launchStyle = "0"
       useCustomWorkingDirectory = "NO"
       ignoresPersistentStateOnLaunch = "NO"
       debugDocumentVersioning = "YES"
             ReferencedContainer = "container:lldb.xcodeproj">
          </BuildableReference>
       </BuildableProductRunnable>
+      <CommandLineArguments>
+         <CommandLineArgument
+            argument = "~/Documents/src/args/a.out "
+            isEnabled = "YES">
+         </CommandLineArgument>
+      </CommandLineArguments>
       <AdditionalOptions>
       </AdditionalOptions>
    </LaunchAction>
index dc85b97..0722e63 100644 (file)
@@ -136,10 +136,8 @@ bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
 
 size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes,
                                uint32_t depth) const {
-  if (IsValid()) {
-    return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes,
-                                depth);
-  }
+  if (IsValid())
+    return m_die->GetAttributes(m_cu, attributes, depth);
   if (depth == 0)
     attributes.Clear();
   return 0;
index aba8070..87d1a4b 100644 (file)
@@ -33,7 +33,6 @@ extern int g_verbose;
 
 bool DWARFDebugInfoEntry::FastExtract(
     const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu,
-    const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
     lldb::offset_t *offset_ptr) {
   m_offset = *offset_ptr;
   m_parent_idx = 0;
@@ -69,9 +68,9 @@ bool DWARFDebugInfoEntry::FastExtract(
     for (i = 0; i < numAttributes; ++i) {
       form = abbrevDecl->GetFormByIndexUnchecked(i);
 
-      const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+      llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
       if (fixed_skip_size)
-        offset += fixed_skip_size;
+        offset += *fixed_skip_size;
       else {
         bool form_is_indirect = false;
         do {
@@ -723,8 +722,8 @@ void DWARFDebugInfoEntry::DumpAttribute(
 // results. Any duplicate attributes will have the first instance take
 // precedence (this can happen for declaration attributes).
 size_t DWARFDebugInfoEntry::GetAttributes(
-    const DWARFUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
-    DWARFAttributes &attributes, uint32_t curr_depth) const {
+    const DWARFUnit *cu, DWARFAttributes &attributes,
+    uint32_t curr_depth) const {
   const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
   lldb::offset_t offset = 0;
   if (cu)
@@ -733,10 +732,6 @@ size_t DWARFDebugInfoEntry::GetAttributes(
   if (abbrevDecl) {
     const DWARFDataExtractor &debug_info_data = cu->GetData();
 
-    if (fixed_form_sizes.Empty())
-      fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
-          cu->GetAddressByteSize());
-
     const uint32_t num_attributes = abbrevDecl->NumAttributes();
     for (uint32_t i = 0; i < num_attributes; ++i) {
       DWARFFormValue form_value(cu);
@@ -769,9 +764,9 @@ size_t DWARFDebugInfoEntry::GetAttributes(
             spec_die.GetAttributes(attributes, curr_depth + 1);
         }
       } else {
-        const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+        llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
         if (fixed_skip_size)
-          offset += fixed_skip_size;
+          offset += *fixed_skip_size;
         else
           DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
       }
@@ -1120,7 +1115,7 @@ bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
 DWARFDIE
 DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
   DWARFAttributes attributes;
-  GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+  GetAttributes(cu, attributes);
   return GetParentDeclContextDIE(cu, attributes);
 }
 
@@ -1170,7 +1165,7 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE(
 const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
                                                   std::string &storage) const {
   DWARFAttributes attributes;
-  GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+  GetAttributes(cu, attributes);
   return GetQualifiedName(cu, attributes, storage);
 }
 
index caf2915..7b7459a 100644 (file)
@@ -69,7 +69,6 @@ public:
 
   bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data,
                    const DWARFUnit *cu,
-                   const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
                    lldb::offset_t *offset_ptr);
 
   bool Extract(const DWARFUnit *cu, lldb::offset_t *offset_ptr);
@@ -79,7 +78,6 @@ public:
                      DWARFDebugInfoEntry **block_die);
 
   size_t GetAttributes(const DWARFUnit *cu,
-                       DWARFFormValue::FixedFormSizes fixed_form_sizes,
                        DWARFAttributes &attrs,
                        uint32_t curr_depth = 0)
       const; // "curr_depth" for internal use only, don't set this yourself!!!
index ee4759c..b707c34 100644 (file)
@@ -21,92 +21,6 @@ class DWARFUnit;
 
 using namespace lldb_private;
 
-static uint8_t g_form_sizes_addr4[] = {
-    0, // 0x00 unused
-    4, // 0x01 DW_FORM_addr
-    0, // 0x02 unused
-    0, // 0x03 DW_FORM_block2
-    0, // 0x04 DW_FORM_block4
-    2, // 0x05 DW_FORM_data2
-    4, // 0x06 DW_FORM_data4
-    8, // 0x07 DW_FORM_data8
-    0, // 0x08 DW_FORM_string
-    0, // 0x09 DW_FORM_block
-    0, // 0x0a DW_FORM_block1
-    1, // 0x0b DW_FORM_data1
-    1, // 0x0c DW_FORM_flag
-    0, // 0x0d DW_FORM_sdata
-    4, // 0x0e DW_FORM_strp
-    0, // 0x0f DW_FORM_udata
-    0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
-       // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
-    1, // 0x11 DW_FORM_ref1
-    2, // 0x12 DW_FORM_ref2
-    4, // 0x13 DW_FORM_ref4
-    8, // 0x14 DW_FORM_ref8
-    0, // 0x15 DW_FORM_ref_udata
-    0, // 0x16 DW_FORM_indirect
-    4, // 0x17 DW_FORM_sec_offset
-    0, // 0x18 DW_FORM_exprloc
-    0, // 0x19 DW_FORM_flag_present
-    0, // 0x1a
-    0, // 0x1b
-    0, // 0x1c
-    0, // 0x1d
-    0, // 0x1e
-    0, // 0x1f
-    8, // 0x20 DW_FORM_ref_sig8
-
-};
-
-static uint8_t g_form_sizes_addr8[] = {
-    0, // 0x00 unused
-    8, // 0x01 DW_FORM_addr
-    0, // 0x02 unused
-    0, // 0x03 DW_FORM_block2
-    0, // 0x04 DW_FORM_block4
-    2, // 0x05 DW_FORM_data2
-    4, // 0x06 DW_FORM_data4
-    8, // 0x07 DW_FORM_data8
-    0, // 0x08 DW_FORM_string
-    0, // 0x09 DW_FORM_block
-    0, // 0x0a DW_FORM_block1
-    1, // 0x0b DW_FORM_data1
-    1, // 0x0c DW_FORM_flag
-    0, // 0x0d DW_FORM_sdata
-    4, // 0x0e DW_FORM_strp
-    0, // 0x0f DW_FORM_udata
-    0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
-       // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
-    1, // 0x11 DW_FORM_ref1
-    2, // 0x12 DW_FORM_ref2
-    4, // 0x13 DW_FORM_ref4
-    8, // 0x14 DW_FORM_ref8
-    0, // 0x15 DW_FORM_ref_udata
-    0, // 0x16 DW_FORM_indirect
-    4, // 0x17 DW_FORM_sec_offset
-    0, // 0x18 DW_FORM_exprloc
-    0, // 0x19 DW_FORM_flag_present
-    0, // 0x1a
-    0, // 0x1b
-    0, // 0x1c
-    0, // 0x1d
-    0, // 0x1e
-    0, // 0x1f
-    8, // 0x20 DW_FORM_ref_sig8
-};
-
-DWARFFormValue::FixedFormSizes
-DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size) {
-  switch (addr_size) {
-  case 4:
-    return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
-  case 8:
-    return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
-  }
-  return FixedFormSizes();
-}
-
 void DWARFFormValue::Clear() {
   m_unit = nullptr;
   m_form = 0;
@@ -231,6 +145,59 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
   return true;
 }
 
+struct FormSize {
+  uint8_t valid:1, size:7;
+};
+static FormSize g_form_sizes[] = {
+  {0,0}, // 0x00 unused
+  {0,0}, // 0x01 DW_FORM_addr
+  {0,0}, // 0x02 unused
+  {0,0}, // 0x03 DW_FORM_block2
+  {0,0}, // 0x04 DW_FORM_block4
+  {1,2}, // 0x05 DW_FORM_data2
+  {1,4}, // 0x06 DW_FORM_data4
+  {1,8}, // 0x07 DW_FORM_data8
+  {0,0}, // 0x08 DW_FORM_string
+  {0,0}, // 0x09 DW_FORM_block
+  {0,0}, // 0x0a DW_FORM_block1
+  {1,1}, // 0x0b DW_FORM_data1
+  {1,1}, // 0x0c DW_FORM_flag
+  {0,0}, // 0x0d DW_FORM_sdata
+  {1,4}, // 0x0e DW_FORM_strp
+  {0,0}, // 0x0f DW_FORM_udata
+  {0,0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+         // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+  {1,1}, // 0x11 DW_FORM_ref1
+  {1,2}, // 0x12 DW_FORM_ref2
+  {1,4}, // 0x13 DW_FORM_ref4
+  {1,8}, // 0x14 DW_FORM_ref8
+  {0,0}, // 0x15 DW_FORM_ref_udata
+  {0,0}, // 0x16 DW_FORM_indirect
+  {1,4}, // 0x17 DW_FORM_sec_offset
+  {0,0}, // 0x18 DW_FORM_exprloc
+  {1,0}, // 0x19 DW_FORM_flag_present
+  {0,0}, // 0x1a
+  {0,0}, // 0x1b
+  {0,0}, // 0x1c
+  {0,0}, // 0x1d
+  {0,0}, // 0x1e
+  {0,0}, // 0x1f
+  {1,8}, // 0x20 DW_FORM_ref_sig8
+};
+
+llvm::Optional<uint8_t>
+DWARFFormValue::GetFixedSize(dw_form_t form, const DWARFUnit *u) {
+  if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid)
+    return g_form_sizes[form].size;
+  if (form == DW_FORM_addr && u)
+    return u->GetAddressByteSize();
+  return llvm::None;
+}
+
+llvm::Optional<uint8_t> DWARFFormValue::GetFixedSize() const {
+  return GetFixedSize(m_form, m_unit);
+}
+
 bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
                                lldb::offset_t *offset_ptr) const {
   return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_unit);
index 2143921..848db29 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "DWARFDataExtractor.h"
 #include <stddef.h>
+#include "llvm/ADT/Optional.h"
 
 class DWARFUnit;
 class SymbolFileDWARF;
@@ -29,24 +30,6 @@ public:
     const uint8_t *data;
   } ValueType;
 
-  class FixedFormSizes {
-  public:
-    FixedFormSizes() : m_fix_sizes(nullptr), m_size(0) {}
-
-    FixedFormSizes(const uint8_t *fix_sizes, size_t size)
-        : m_fix_sizes(fix_sizes), m_size(size) {}
-
-    uint8_t GetSize(uint32_t index) const {
-      return index < m_size ? m_fix_sizes[index] : 0;
-    }
-
-    bool Empty() const { return m_size == 0; }
-
-  private:
-    const uint8_t *m_fix_sizes;
-    size_t m_size;
-  };
-
   enum {
     eValueTypeInvalid = 0,
     eValueTypeUnsigned,
@@ -71,6 +54,9 @@ public:
   bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
                     lldb::offset_t *offset_ptr);
   const uint8_t *BlockData() const;
+  static llvm::Optional<uint8_t> GetFixedSize(dw_form_t form,
+                                              const DWARFUnit *u);
+  llvm::Optional<uint8_t> GetFixedSize() const;
   DWARFDIE Reference() const;
   uint64_t Reference(dw_offset_t offset) const;
   bool Boolean() const { return m_value.value.uval != 0; }
@@ -88,7 +74,6 @@ public:
                         lldb::offset_t *offset_ptr, const DWARFUnit *unit);
   static bool IsBlockForm(const dw_form_t form);
   static bool IsDataForm(const dw_form_t form);
-  static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size);
   static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
   void Clear();
   static bool FormIsSupported(dw_form_t form);
index 7049fe7..cd84923 100644 (file)
@@ -60,10 +60,8 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
   // We are in our compile unit, parse starting at the offset we were told to
   // parse
   const DWARFDataExtractor &data = GetData();
-  DWARFFormValue::FixedFormSizes fixed_form_sizes =
-      DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize());
   if (offset < GetNextUnitOffset() &&
-      m_first_die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+      m_first_die.FastExtract(data, this, &offset)) {
     AddUnitDIE(m_first_die);
     return;
   }
@@ -167,10 +165,7 @@ void DWARFUnit::ExtractDIEsRWLocked() {
   die_index_stack.reserve(32);
   die_index_stack.push_back(0);
   bool prev_die_had_children = false;
-  DWARFFormValue::FixedFormSizes fixed_form_sizes =
-      DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize());
-  while (offset < next_cu_offset &&
-         die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+  while (offset < next_cu_offset && die.FastExtract(data, this, &offset)) {
     const bool null_die = die.IsNULL();
     if (depth == 0) {
       assert(m_die_array.empty() && "Compile unit DIE already added");
@@ -415,10 +410,6 @@ TypeSystem *DWARFUnit::GetTypeSystem() {
     return nullptr;
 }
 
-DWARFFormValue::FixedFormSizes DWARFUnit::GetFixedFormSizes() {
-  return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize());
-}
-
 void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
 
 // Compare function DWARFDebugAranges::Range structures
index 165f862..da516ae 100644 (file)
@@ -157,8 +157,6 @@ public:
 
   const DWARFDebugAranges &GetFunctionAranges();
 
-  DWARFFormValue::FixedFormSizes GetFixedFormSizes();
-
   void SetBaseAddress(dw_addr_t base_addr);
 
   DWARFBaseDIE GetUnitDIEOnly() { return DWARFDIE(this, GetUnitDIEPtrOnly()); }
index a6fae61..69d3648 100644 (file)
@@ -100,20 +100,18 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) {
   }
 
   const LanguageType cu_language = unit.GetLanguageType();
-  DWARFFormValue::FixedFormSizes fixed_form_sizes = unit.GetFixedFormSizes();
 
-  IndexUnitImpl(unit, cu_language, fixed_form_sizes, unit.GetOffset(), set);
+  IndexUnitImpl(unit, cu_language, unit.GetOffset(), set);
 
   SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile();
   if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) {
     IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language,
-                  fixed_form_sizes, unit.GetOffset(), set);
+                  unit.GetOffset(), set);
   }
 }
 
 void ManualDWARFIndex::IndexUnitImpl(
     DWARFUnit &unit, const LanguageType cu_language,
-    const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
     const dw_offset_t cu_offset, IndexSet &set) {
   for (const DWARFDebugInfoEntry &die : unit.dies()) {
     const dw_tag_t tag = die.Tag();
@@ -150,8 +148,7 @@ void ManualDWARFIndex::IndexUnitImpl(
     bool is_global_or_static_variable = false;
 
     DWARFFormValue specification_die_form;
-    const size_t num_attributes =
-        die.GetAttributes(&unit, fixed_form_sizes, attributes);
+    const size_t num_attributes = die.GetAttributes(&unit, attributes);
     if (num_attributes > 0) {
       for (uint32_t i = 0; i < num_attributes; ++i) {
         dw_attr_t attr = attributes.AttributeAtIndex(i);
index 5311b0c..590d228 100644 (file)
@@ -59,7 +59,6 @@ private:
 
   static void
   IndexUnitImpl(DWARFUnit &unit, const lldb::LanguageType cu_language,
-                const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
                 const dw_offset_t cu_offset, IndexSet &set);
 
   /// Non-null value means we haven't built the index yet.
index 2871017..11a89db 100644 (file)
@@ -3166,13 +3166,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
                                         block_length);
               } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
                 // Retrieve the value as a data expression.
-                DWARFFormValue::FixedFormSizes fixed_form_sizes =
-                    DWARFFormValue::GetFixedFormSizesForAddressSize(
-                        attributes.CompileUnitAtIndex(i)->GetAddressByteSize());
                 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
-                uint32_t data_length =
-                    fixed_form_sizes.GetSize(form_value.Form());
-                if (data_length == 0) {
+                if (auto data_length = form_value.GetFixedSize())
+                  location.CopyOpcodeData(module, debug_info_data, data_offset,
+                                          *data_length);
+                else {
                   const uint8_t *data_pointer = form_value.BlockData();
                   if (data_pointer) {
                     form_value.Unsigned();
@@ -3181,21 +3179,14 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
                     // create the variable
                     const_value = form_value;
                   }
-                } else
-                  location.CopyOpcodeData(module, debug_info_data, data_offset,
-                                          data_length);
+                }
               } else {
                 // Retrieve the value as a string expression.
                 if (form_value.Form() == DW_FORM_strp) {
-                  DWARFFormValue::FixedFormSizes fixed_form_sizes =
-                      DWARFFormValue::GetFixedFormSizesForAddressSize(
-                          attributes.CompileUnitAtIndex(i)
-                              ->GetAddressByteSize());
                   uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
-                  uint32_t data_length =
-                      fixed_form_sizes.GetSize(form_value.Form());
-                  location.CopyOpcodeData(module, debug_info_data, data_offset,
-                                          data_length);
+                  if (auto data_length = form_value.GetFixedSize())
+                    location.CopyOpcodeData(module, debug_info_data,
+                                            data_offset, *data_length);
                 } else {
                   const char *str = form_value.AsCString();
                   uint32_t string_offset =