diff options
| author | Greg Clayton <gclayton@apple.com> | 2013-06-12 00:46:38 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2013-06-12 00:46:38 +0000 |
| commit | d8cf1a119d4c38e59ade90018a4df015dff63383 (patch) | |
| tree | 606b745e59a29f527781d29bd8709ff5e8a814f1 /lldb/source/Symbol/SymbolContext.cpp | |
| parent | ec36f9a73429dda07049473625d3354b209cc5b7 (diff) | |
| download | bcm5719-llvm-d8cf1a119d4c38e59ade90018a4df015dff63383.tar.gz bcm5719-llvm-d8cf1a119d4c38e59ade90018a4df015dff63383.zip | |
Huge performance improvements when one breakpoint contains many locations.
325,000 breakpoints for running "breakpoint set --func-regex ." on lldb itself (after hitting a breakpoint at main so that LLDB.framework is loaded) used to take up to an hour to set, now we are down under a minute. With warm file caches, we are at 40 seconds, and that is with setting 325,000 breakpoint through the GDB remote API. Linux and the native debuggers might be faster. I haven't timed what how much is debug info parsing and how much is the protocol traffic to/from GDB remote.
That there were many performance issues. Most of them were due to storing breakpoints in the wrong data structures, or using the wrong iterators to traverse the lists, traversing the lists in inefficient ways, and not optimizing certain function name lookups/symbol merges correctly.
Debugging after that is also now very efficient. There were issues with replacing the breakpoint opcodes in memory that was read, and those routines were also fixed.
llvm-svn: 183820
Diffstat (limited to 'lldb/source/Symbol/SymbolContext.cpp')
| -rw-r--r-- | lldb/source/Symbol/SymbolContext.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index b2beb912f43..ac91161f7d6 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -1023,6 +1023,10 @@ SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_in { for (pos = m_symbol_contexts.begin(); pos != end; ++pos) { + // Don't merge symbols into inlined function symbol contexts + if (pos->block && pos->block->GetContainingInlinedBlock()) + continue; + if (pos->function) { if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress()) @@ -1044,6 +1048,49 @@ SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_in return true; } +bool +SymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc, + uint32_t start_idx, + uint32_t stop_idx) +{ + if (symbol_sc.symbol != NULL + && symbol_sc.comp_unit == NULL + && symbol_sc.function == NULL + && symbol_sc.block == NULL + && symbol_sc.line_entry.IsValid() == false) + { + if (symbol_sc.symbol->ValueIsAddress()) + { + const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx); + for (size_t i=start_idx; i<end; ++i) + { + const SymbolContext &function_sc = m_symbol_contexts[i]; + // Don't merge symbols into inlined function symbol contexts + if (function_sc.block && function_sc.block->GetContainingInlinedBlock()) + continue; + + if (function_sc.function) + { + if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress()) + { + // Do we already have a function with this symbol? + if (function_sc.symbol == symbol_sc.symbol) + return true; // Already have a symbol context with this symbol, return true + + if (function_sc.symbol == NULL) + { + // We successfully merged this symbol into an existing symbol context + m_symbol_contexts[i].symbol = symbol_sc.symbol; + return true; + } + } + } + } + } + } + return false; +} + void SymbolContextList::Clear() { |

