From d8cf1a119d4c38e59ade90018a4df015dff63383 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Wed, 12 Jun 2013 00:46:38 +0000 Subject: 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 --- .../tools/debugserver/source/MacOSX/MachThread.cpp | 26 +++++----------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'lldb/tools/debugserver/source/MacOSX/MachThread.cpp') diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp index 61f5b21af14..a32161f4eb0 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp @@ -31,7 +31,6 @@ MachThread::MachThread (MachProcess *process, uint64_t unique_thread_id, thread_ m_seq_id (GetSequenceID()), m_state (eStateUnloaded), m_state_mutex (PTHREAD_MUTEX_RECURSIVE), - m_break_id (INVALID_NUB_BREAK_ID), m_suspend_count (0), m_stop_exception (), m_arch_ap (DNBArchProtocol::Create (this)), @@ -361,13 +360,12 @@ MachThread::Dump(uint32_t index) default: thread_run_state = "???"; break; } - DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", breakID: %3d, user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d", + DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d", index, m_seq_id, m_unique_id, GetPC(INVALID_NUB_ADDRESS), GetSP(INVALID_NUB_ADDRESS), - m_break_id, m_basic_info.user_time.seconds, m_basic_info.user_time.microseconds, m_basic_info.system_time.seconds, m_basic_info.system_time.microseconds, m_basic_info.cpu_usage, @@ -406,35 +404,23 @@ MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action, bool ot m_stop_exception.Clear(); } -nub_break_t +DNBBreakpoint * MachThread::CurrentBreakpoint() { - return m_process->Breakpoints().FindIDByAddress(GetPC()); + return m_process->Breakpoints().FindByAddress(GetPC()); } bool MachThread::ShouldStop(bool &step_more) { // See if this thread is at a breakpoint? - nub_break_t breakID = CurrentBreakpoint(); + DNBBreakpoint *bp = CurrentBreakpoint(); - if (NUB_BREAK_ID_IS_VALID(breakID)) + if (bp) { // This thread is sitting at a breakpoint, ask the breakpoint // if we should be stopping here. - if (Process()->Breakpoints().ShouldStop(ProcessID(), ThreadID(), breakID)) - return true; - else - { - // The breakpoint said we shouldn't stop, but we may have gotten - // a signal or the user may have requested to stop in some other - // way. Stop if we have a valid exception (this thread won't if - // another thread was the reason this process stopped) and that - // exception, is NOT a breakpoint exception (a common case would - // be a SIGINT signal). - if (GetStopException().IsValid() && !GetStopException().IsBreakpoint()) - return true; - } + return true; } else { -- cgit v1.2.3