[Lldb-commits] [lldb] r177585 - Change DWARFCallFrameInfo from using a vector of AddressRanges to

Jason Molenda jmolenda at apple.com
Wed Mar 20 14:57:42 PDT 2013


Author: jmolenda
Date: Wed Mar 20 16:57:42 2013
New Revision: 177585

URL: http://llvm.org/viewvc/llvm-project?rev=177585&view=rev
Log:
Change DWARFCallFrameInfo from using a vector of AddressRanges to
track the EH FDEs for the functions in a module to using a
RangeDataVector, a more light-weight data structure that only refers
to File addresses.  Makes the initial FDE scan about 3x faster, uses
less memory.
<rdar://problem/13465650> 

Modified:
    lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
    lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp

Modified: lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h?rev=177585&r1=177584&r2=177585&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h (original)
+++ lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h Wed Mar 20 16:57:42 2013
@@ -12,15 +12,16 @@
 
 #include <map>
 
-#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Flags.h"
-#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/RangeMap.h"
 #include "lldb/Core/VMRange.h"
 #include "lldb/Core/dwarf.h"
 #include "lldb/Host/Mutex.h"
-#include "lldb/Symbol/UnwindPlan.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/lldb-private.h"
 
 namespace lldb_private {
 
@@ -53,7 +54,6 @@ public:
     bool
     GetUnwindPlan (Address addr, UnwindPlan& unwind_plan);
 
-
 private:
     enum
     {
@@ -81,22 +81,10 @@ private:
 
     typedef STD_SHARED_PTR(CIE) CIESP;
 
-    struct FDEEntry
-    {
-        AddressRange bounds;   // function bounds
-        dw_offset_t offset;    // offset to this FDE within the Section
-
-        FDEEntry () : bounds (), offset (0) { }
-
-        inline bool
-        operator<(const DWARFCallFrameInfo::FDEEntry& b) const
-        {
-            if (bounds.GetBaseAddress().GetOffset() < b.bounds.GetBaseAddress().GetOffset())
-                return true;
-            else
-                return false;
-        }
-    };
+    // Start address, size, offset of FDE location
+    // used for finding an FDE for a given File address; the start address field is
+    // an offset into an individual Module.
+    typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap;
 
     typedef std::map<off_t, CIESP> cie_map_t;
 
@@ -104,7 +92,7 @@ private:
     IsEHFrame() const;
 
     bool
-    GetFDEEntryByAddress (Address addr, FDEEntry& fde_entry);
+    GetFDEEntryByFileAddress (lldb::addr_t file_offset, FDEEntryMap::Entry& fde_entry);
 
     void
     GetFDEIndex ();
@@ -127,7 +115,7 @@ private:
     DataExtractor               m_cfi_data;
     bool                        m_cfi_data_initialized;   // only copy the section into the DE once
 
-    std::vector<FDEEntry>       m_fde_index;
+    FDEEntryMap                 m_fde_index;
     bool                        m_fde_index_initialized;  // only scan the section for FDEs once
     Mutex                       m_fde_index_mutex;        // and isolate the thread that does it
 

Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=177585&r1=177584&r2=177585&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Wed Mar 20 16:57:42 2013
@@ -17,6 +17,7 @@
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
+#include "lldb/Core/Timer.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Symbol/DWARFCallFrameInfo.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -47,54 +48,60 @@ DWARFCallFrameInfo::~DWARFCallFrameInfo(
 
 
 bool
-DWARFCallFrameInfo::GetAddressRange (Address addr, AddressRange &range)
+DWARFCallFrameInfo::GetUnwindPlan (Address addr, UnwindPlan& unwind_plan)
 {
-    FDEEntry fde_entry;
-    if (GetFDEEntryByAddress (addr, fde_entry) == false)
+    FDEEntryMap::Entry fde_entry;
+
+    // Make sure that the Address we're searching for is the same object file
+    // as this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
+    ModuleSP module_sp = addr.GetModule();
+    if (module_sp.get() == NULL || module_sp->GetObjectFile() == NULL || module_sp->GetObjectFile() != &m_objfile)
         return false;
-    range = fde_entry.bounds;
-    return true;
+
+    if (GetFDEEntryByFileAddress (addr.GetFileAddress(), fde_entry) == false)
+        return false;
+    return FDEToUnwindPlan (fde_entry.data, addr, unwind_plan);
 }
 
 bool
-DWARFCallFrameInfo::GetUnwindPlan (Address addr, UnwindPlan& unwind_plan)
+DWARFCallFrameInfo::GetAddressRange (Address addr, AddressRange &range)
 {
-    FDEEntry fde_entry;
-    if (GetFDEEntryByAddress (addr, fde_entry) == false)
+
+    // Make sure that the Address we're searching for is the same object file
+    // as this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
+    ModuleSP module_sp = addr.GetModule();
+    if (module_sp.get() == NULL || module_sp->GetObjectFile() == NULL || module_sp->GetObjectFile() != &m_objfile)
+        return false;
+
+    if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
+        return false;
+    GetFDEIndex();
+    FDEEntryMap::Entry *fde_entry = m_fde_index.FindEntryThatContains (addr.GetFileAddress());
+    if (!fde_entry)
         return false;
-    return FDEToUnwindPlan (fde_entry.offset, addr, unwind_plan);
+
+    range = AddressRange(fde_entry->base, fde_entry->size, m_objfile.GetSectionList());
+    return true;
 }
 
 bool
-DWARFCallFrameInfo::GetFDEEntryByAddress (Address addr, FDEEntry& fde_entry)
+DWARFCallFrameInfo::GetFDEEntryByFileAddress (addr_t file_addr, FDEEntryMap::Entry &fde_entry)
 {
     if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
         return false;
-    GetFDEIndex();
 
-    struct FDEEntry searchfde;
-    searchfde.bounds = AddressRange (addr, 1);
+    GetFDEIndex();
 
-    std::vector<FDEEntry>::const_iterator idx;
-    if (m_fde_index.size() == 0)
+    if (m_fde_index.IsEmpty())
         return false;
 
-    idx = std::lower_bound (m_fde_index.begin(), m_fde_index.end(), searchfde);
-    if (idx == m_fde_index.end())
-    {
-        --idx;
-    }
-    if (idx != m_fde_index.begin() && idx->bounds.GetBaseAddress().GetOffset() != addr.GetOffset())
-    {
-       --idx;
-    }
-    if (idx->bounds.ContainsFileAddress (addr))
-    {
-        fde_entry = *idx;
-        return true;
-    }
+    FDEEntryMap::Entry *fde = m_fde_index.FindEntryThatContains (file_addr);
 
-    return false;
+    if (fde == NULL)
+        return false;
+
+    fde_entry = *fde;
+    return true;
 }
 
 const DWARFCallFrameInfo::CIE*
@@ -302,6 +309,8 @@ DWARFCallFrameInfo::GetFDEIndex ()
     if (m_fde_index_initialized) // if two threads hit the locker
         return;
 
+    Timer scoped_timer (__PRETTY_FUNCTION__, "%s - %s", __PRETTY_FUNCTION__, m_objfile.GetFileSpec().GetFilename().AsCString(""));
+
     lldb::offset_t offset = 0;
     if (m_cfi_data_initialized == false)
         GetCFIData();
@@ -329,10 +338,8 @@ DWARFCallFrameInfo::GetFDEIndex ()
 
             lldb::addr_t addr = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr);
             lldb::addr_t length = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr, text_addr, data_addr);
-            FDEEntry fde;
-            fde.bounds = AddressRange (addr, length, m_objfile.GetSectionList());
-            fde.offset = current_entry;
-            m_fde_index.push_back(fde);
+            FDEEntryMap::Entry fde (addr, length, current_entry);
+            m_fde_index.Append(fde);
         }
         else
         {
@@ -344,7 +351,7 @@ DWARFCallFrameInfo::GetFDEIndex ()
         }
         offset = next_entry;
     }
-    std::sort (m_fde_index.begin(), m_fde_index.end());
+    m_fde_index.Sort();
     m_fde_index_initialized = true;
 }
 





More information about the lldb-commits mailing list