[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