[Lldb-commits] [lldb] r254762 - Cache the incremental iterators as you traverse the list, so that you don't have to keep recomputing them

Enrico Granata via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 4 12:12:46 PST 2015


Author: enrico
Date: Fri Dec  4 14:12:46 2015
New Revision: 254762

URL: http://llvm.org/viewvc/llvm-project?rev=254762&view=rev
Log:
Cache the incremental iterators as you traverse the list, so that you don't have to keep recomputing them

If memory turns out to be a problem, which I don't think it will in practice because all these ValueObjects, we'd be keeping alive anyway, I can always resort to caching the farthest-most iterator only

This gains us an order of magnitude in my benchmark, cutting the time to traverse a 1500-elements list from 22 seconds down to 2


Modified:
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxList.cpp

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxList.cpp?rev=254762&r1=254761&r2=254762&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxList.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxList.cpp Fri Dec  4 14:12:46 2015
@@ -31,9 +31,6 @@ namespace {
 
     class ListEntry
     {
-    private:
-        static const std::initializer_list<size_t> __prev_idx;
-        static const std::initializer_list<size_t> __next_idx;
     public:
         ListEntry() = default;
         ListEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
@@ -102,6 +99,64 @@ namespace {
     private:
         ValueObjectSP m_entry_sp;
     };
+    
+    class ListIterator
+    {
+    public:
+        ListIterator() = default;
+        ListIterator (ListEntry entry) : m_entry(entry) {}
+        ListIterator (ValueObjectSP entry) : m_entry(entry) {}
+        ListIterator (const ListIterator& rhs) : m_entry(rhs.m_entry) {}
+        ListIterator (ValueObject* entry) : m_entry(entry) {}
+        
+        ValueObjectSP
+        value ()
+        {
+            return m_entry.GetEntry();
+        }
+        
+        ValueObjectSP
+        advance (size_t count)
+        {
+            if (count == 0)
+                return m_entry.GetEntry();
+            if (count == 1)
+            {
+                next ();
+                return m_entry.GetEntry();
+            }
+            while (count > 0)
+            {
+                next ();
+                count--;
+                if (m_entry.null())
+                    return lldb::ValueObjectSP();
+            }
+            return m_entry.GetEntry();
+        }
+        
+        bool
+        operator == (const ListIterator& rhs) const
+        {
+            return (rhs.m_entry == m_entry);
+        }
+        
+    protected:
+        void
+        next ()
+        {
+            m_entry = m_entry.next();
+        }
+        
+        void
+        prev ()
+        {
+            m_entry = m_entry.prev();
+        }
+        
+    private:
+        ListEntry m_entry;
+    };
 
 } // end anonymous namespace
 
@@ -146,68 +201,11 @@ namespace lldb_private {
             CompilerType m_element_type;
             size_t m_count;
             std::map<size_t,lldb::ValueObjectSP> m_children;
+            std::map<size_t, ListIterator> m_iterators;
         };
     } // namespace formatters
 } // namespace lldb_private
 
-class ListIterator
-{
-public:
-    ListIterator() = default;
-    ListIterator (ListEntry entry) : m_entry(entry) {}
-    ListIterator (ValueObjectSP entry) : m_entry(entry) {}
-    ListIterator (const ListIterator& rhs) : m_entry(rhs.m_entry) {}
-    ListIterator (ValueObject* entry) : m_entry(entry) {}
-
-    ValueObjectSP
-    value ()
-    {
-        return m_entry.GetEntry();
-    }
-    
-    ValueObjectSP
-    advance (size_t count)
-    {
-        if (count == 0)
-            return m_entry.GetEntry();
-        if (count == 1)
-        {
-            next ();
-            return m_entry.GetEntry();
-        }
-        while (count > 0)
-        {
-            next ();
-            count--;
-            if (m_entry.null())
-                return lldb::ValueObjectSP();
-        }
-        return m_entry.GetEntry();
-    }
-    
-    bool
-    operator == (const ListIterator& rhs) const
-    {
-        return (rhs.m_entry == m_entry);
-    }
-    
-protected:
-    void
-    next ()
-    {
-        m_entry = m_entry.next();
-    }
-    
-    void
-    prev ()
-    {
-        m_entry = m_entry.prev();
-    }
-
-private:
-    ListEntry m_entry;
-};
-
 lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
 SyntheticChildrenFrontEnd(*valobj_sp.get()),
 m_list_capping_size(0),
@@ -217,7 +215,8 @@ m_head(NULL),
 m_tail(NULL),
 m_element_type(),
 m_count(UINT32_MAX),
-m_children()
+m_children(),
+m_iterators()
 {
     if (valobj_sp)
         Update();
@@ -319,11 +318,26 @@ lldb_private::formatters::LibcxxStdListS
     
     if (HasLoop(idx+1))
         return lldb::ValueObjectSP();
-        
+    
+    size_t actual_advance = idx;
+    
     ListIterator current(m_head);
-    ValueObjectSP current_sp(current.advance(idx));
+    if (idx > 0)
+    {
+        auto cached_iterator = m_iterators.find(idx-1);
+        if (cached_iterator != m_iterators.end())
+        {
+            current = cached_iterator->second;
+            actual_advance = 1;
+        }
+    }
+    
+    ValueObjectSP current_sp(current.advance(actual_advance));
     if (!current_sp)
         return lldb::ValueObjectSP();
+    
+    m_iterators[idx] = current;
+    
     current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child
     if (!current_sp)
         return lldb::ValueObjectSP();
@@ -343,6 +357,7 @@ bool
 lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update()
 {
     m_children.clear();
+    m_iterators.clear();
     m_head = m_tail = NULL;
     m_node_address = 0;
     m_count = UINT32_MAX;




More information about the lldb-commits mailing list