Fixed the BreakpointLocationList to be able to do O(1) lookups on breakpoint

locations by ID. It used to be, worst case, O(N).

llvm-svn: 124914
This commit is contained in:
Greg Clayton 2011-02-05 00:38:04 +00:00
parent 96d07a82b2
commit c0d3446516
6 changed files with 64 additions and 188 deletions

View File

@ -232,7 +232,7 @@ public:
/// Returns a pointer to the new location.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
AddLocation (Address &addr,
AddLocation (const Address &addr,
bool *new_location = NULL);
//------------------------------------------------------------------
@ -245,7 +245,7 @@ public:
/// in the shared pointer will be NULL if there is no location at that address.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
FindLocationByAddress (Address &addr);
FindLocationByAddress (const Address &addr);
//------------------------------------------------------------------
/// Find a breakpoint location ID by Address.
@ -257,7 +257,7 @@ public:
/// there is no breakpoint location at that address.
//------------------------------------------------------------------
lldb::break_id_t
FindLocationIDByAddress (Address &addr);
FindLocationIDByAddress (const Address &addr);
//------------------------------------------------------------------
/// Find a breakpoint location for a given breakpoint location ID.

View File

@ -312,7 +312,7 @@ public:
InvokeCallback (StoppointCallbackContext *context);
protected:
friend class Breakpoint;
friend class BreakpointLocationList;
friend class CommandObjectBreakpointCommandAdd;
friend class Process;
@ -357,7 +357,7 @@ private:
BreakpointLocation (lldb::break_id_t bid,
Breakpoint &owner,
Address &addr,
const Address &addr,
lldb::tid_t tid = LLDB_INVALID_THREAD_ID,
bool hardware = false);

View File

@ -59,21 +59,7 @@ public:
/// pointer if the breakpoint doesn't exist.
//------------------------------------------------------------------
const lldb::BreakpointLocationSP
FindByAddress (Address &addr) const;
//------------------------------------------------------------------
/// Returns a shared pointer to the breakpoint location with id \a
/// breakID.
///
/// @param[in] breakID
/// The breakpoint location ID to seek for.
///
/// @result
/// A shared pointer to the breakpoint. May contain a NULL
/// pointer if the breakpoint doesn't exist.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
FindByID (lldb::break_id_t breakID);
FindByAddress (const Address &addr) const;
//------------------------------------------------------------------
/// Returns a shared pointer to the breakpoint location with id
@ -86,7 +72,7 @@ public:
/// A shared pointer to the breakpoint. May contain a NULL
/// pointer if the breakpoint doesn't exist.
//------------------------------------------------------------------
const lldb::BreakpointLocationSP
lldb::BreakpointLocationSP
FindByID (lldb::break_id_t breakID) const;
//------------------------------------------------------------------
@ -100,7 +86,7 @@ public:
/// The ID of the breakpoint location, or LLDB_INVALID_BREAK_ID.
//------------------------------------------------------------------
lldb::break_id_t
FindIDByAddress (Address &addr);
FindIDByAddress (const Address &addr);
//------------------------------------------------------------------
/// Returns a breakpoint location list of the breakpoint locations
@ -182,19 +168,6 @@ public:
uint32_t
GetHitCount () const;
//------------------------------------------------------------------
/// Removes the breakpoint location given by \b breakID from this
/// list.
///
/// @param[in] breakID
/// The breakpoint location index to remove.
///
/// @result
/// \b true if the breakpoint \a breakID was in the list.
//------------------------------------------------------------------
bool
Remove (lldb::break_id_t breakID);
//------------------------------------------------------------------
/// Enquires of the breakpoint location in this list with ID \a
/// breakID whether we should stop.
@ -262,28 +235,15 @@ protected:
/// @result
/// Returns breakpoint location id.
//------------------------------------------------------------------
virtual lldb::break_id_t
Add (lldb::BreakpointLocationSP& bp_loc_sp);
lldb::BreakpointLocationSP
Create (Breakpoint &owner, const Address &addr);
// Add (lldb::BreakpointLocationSP& bp_loc_sp);
typedef std::vector<lldb::BreakpointLocationSP> collection;
typedef std::map<lldb_private::Address,
lldb::BreakpointLocationSP,
Address::ModulePointerAndOffsetLessThanFunctionObject> addr_map;
// The breakpoint locations are stored in their Parent Breakpoint's location list by an
// index that is unique to this list, and not across all breakpoint location lists.
// This is only set in the Breakpoint's AddLocation method.
// There is another breakpoint location list, the owner's list in the BreakpointSite,
// but that should not reset the ID. Unfortunately UserID's SetID method is public.
lldb::break_id_t
GetNextID();
collection::iterator
GetIDIterator(lldb::break_id_t breakID);
collection::const_iterator
GetIDConstIterator(lldb::break_id_t breakID) const;
collection m_locations;
addr_map m_address_to_location;
mutable Mutex m_mutex;

View File

@ -81,33 +81,33 @@ Breakpoint::GetTarget () const
}
BreakpointLocationSP
Breakpoint::AddLocation (Address &addr, bool *new_location)
Breakpoint::AddLocation (const Address &addr, bool *new_location)
{
BreakpointLocationSP bp_loc_sp (m_locations.FindByAddress(addr));
if (bp_loc_sp)
{
if (new_location)
*new_location = false;
return bp_loc_sp;
}
bp_loc_sp.reset (new BreakpointLocation (m_locations.GetNextID(), *this, addr));
m_locations.Add (bp_loc_sp);
bp_loc_sp->ResolveBreakpointSite();
if (new_location)
*new_location = true;
*new_location = false;
BreakpointLocationSP bp_loc_sp (m_locations.FindByAddress(addr));
if (!bp_loc_sp)
{
bp_loc_sp = m_locations.Create (*this, addr);
if (bp_loc_sp)
{
bp_loc_sp->ResolveBreakpointSite();
if (new_location)
*new_location = true;
}
}
return bp_loc_sp;
}
BreakpointLocationSP
Breakpoint::FindLocationByAddress (Address &addr)
Breakpoint::FindLocationByAddress (const Address &addr)
{
return m_locations.FindByAddress(addr);
}
break_id_t
Breakpoint::FindLocationIDByAddress (Address &addr)
Breakpoint::FindLocationIDByAddress (const Address &addr)
{
return m_locations.FindIDByAddress(addr);
}
@ -127,7 +127,6 @@ Breakpoint::GetLocationAtIndex (uint32_t index)
BreakpointLocationSP
Breakpoint::GetLocationSP (BreakpointLocation *bp_loc_ptr)
{
assert (bp_loc_ptr->GetBreakpoint().GetID() == GetID());
return m_locations.FindByID(bp_loc_ptr->GetID());
}
@ -280,24 +279,25 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load)
// 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve
// them after the locations pass. Have to do it this way because
// resolving breakpoints will add new locations potentially.
// them after the locations pass. Have to do it this way because
// resolving breakpoints will add new locations potentially.
const size_t num_locs = m_locations.GetSize();
for (size_t i = 0; i < module_list.GetSize(); i++)
{
bool seen = false;
ModuleSP module_sp (module_list.GetModuleAtIndex (i));
Module *module = module_sp.get();
if (!m_filter_sp->ModulePasses (module_sp))
continue;
for (size_t loc_idx = 0; loc_idx < m_locations.GetSize(); loc_idx++)
for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
{
BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
if (!break_loc->IsEnabled())
continue;
const Section *section = break_loc->GetAddress().GetSection();
if (section == NULL || section->GetModule() == module)
if (section == NULL || section->GetModule() == module_sp.get())
{
if (!seen)
seen = true;

View File

@ -32,7 +32,7 @@ BreakpointLocation::BreakpointLocation
(
break_id_t loc_id,
Breakpoint &owner,
Address &addr,
const Address &addr,
lldb::tid_t tid,
bool hardware
) :

View File

@ -23,8 +23,7 @@ using namespace lldb_private;
BreakpointLocationList::BreakpointLocationList() :
m_locations(),
m_address_to_location (),
m_mutex (Mutex::eMutexTypeRecursive),
m_next_id (0)
m_mutex (Mutex::eMutexTypeRecursive)
{
}
@ -32,17 +31,16 @@ BreakpointLocationList::~BreakpointLocationList()
{
}
lldb::break_id_t
BreakpointLocationList::Add (BreakpointLocationSP &bp_loc_sp)
BreakpointLocationSP
BreakpointLocationList::Create (Breakpoint &bp, const Address &addr)
{
if (bp_loc_sp)
{
Mutex::Locker locker (m_mutex);
m_locations.push_back (bp_loc_sp);
m_address_to_location[bp_loc_sp->GetAddress()] = bp_loc_sp;
return bp_loc_sp->GetID();
}
return LLDB_INVALID_BREAK_ID;
Mutex::Locker locker (m_mutex);
// The location ID is just the size of the location list + 1
lldb::break_id_t bp_loc_id = m_locations.size() + 1;
BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, bp, addr));
m_locations.push_back (bp_loc_sp);
m_address_to_location[addr] = bp_loc_sp;
return bp_loc_sp;
}
bool
@ -62,7 +60,7 @@ BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::bre
}
lldb::break_id_t
BreakpointLocationList::FindIDByAddress (Address &addr)
BreakpointLocationList::FindIDByAddress (const Address &addr)
{
BreakpointLocationSP bp_loc_sp = FindByAddress (addr);
if (bp_loc_sp)
@ -72,95 +70,19 @@ BreakpointLocationList::FindIDByAddress (Address &addr)
return LLDB_INVALID_BREAK_ID;
}
bool
BreakpointLocationList::Remove (lldb::break_id_t break_id)
{
Mutex::Locker locker (m_mutex);
collection::iterator pos = GetIDIterator(break_id); // Predicate
if (pos != m_locations.end())
{
m_address_to_location.erase ((*pos)->GetAddress());
m_locations.erase(pos);
return true;
}
return false;
}
class BreakpointLocationIDMatches
{
public:
BreakpointLocationIDMatches (lldb::break_id_t break_id) :
m_break_id(break_id)
{
}
bool operator() (const BreakpointLocationSP &bp_loc_sp) const
{
return m_break_id == bp_loc_sp->GetID();
}
private:
const lldb::break_id_t m_break_id;
};
class BreakpointLocationAddressMatches
{
public:
BreakpointLocationAddressMatches (Address& addr) :
m_addr(addr)
{
}
bool operator() (const BreakpointLocationSP& bp_loc_sp) const
{
return Address::CompareFileAddress(m_addr, bp_loc_sp->GetAddress()) == 0;
}
private:
const Address &m_addr;
};
BreakpointLocationList::collection::iterator
BreakpointLocationList::GetIDIterator (lldb::break_id_t break_id)
{
Mutex::Locker locker (m_mutex);
return std::find_if (m_locations.begin(),
m_locations.end(),
BreakpointLocationIDMatches(break_id));
}
BreakpointLocationList::collection::const_iterator
BreakpointLocationList::GetIDConstIterator (lldb::break_id_t break_id) const
{
Mutex::Locker locker (m_mutex);
return std::find_if (m_locations.begin(),
m_locations.end(),
BreakpointLocationIDMatches(break_id));
}
BreakpointLocationSP
BreakpointLocationList::FindByID (lldb::break_id_t break_id)
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
collection::iterator pos = GetIDIterator(break_id);
if (pos != m_locations.end())
stop_sp = *pos;
return stop_sp;
}
const BreakpointLocationSP
BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
{
BreakpointLocationSP bp_loc_sp;
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
collection::const_iterator pos = GetIDConstIterator(break_id);
if (pos != m_locations.end())
stop_sp = *pos;
return stop_sp;
// We never remove a breakpoint locations, so the ID can be translated into
// the location index by subtracting 1
uint32_t idx = break_id - 1;
if (idx <= m_locations.size())
{
bp_loc_sp = m_locations[idx];
}
return bp_loc_sp;
}
size_t
@ -193,18 +115,18 @@ BreakpointLocationList::FindInModule (Module *module,
}
const BreakpointLocationSP
BreakpointLocationList::FindByAddress (Address &addr) const
BreakpointLocationList::FindByAddress (const Address &addr) const
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
BreakpointLocationSP bp_loc_sp;
if (!m_locations.empty())
{
addr_map::const_iterator pos = m_address_to_location.find (addr);
if (pos != m_address_to_location.end())
stop_sp = pos->second;
bp_loc_sp = pos->second;
}
return stop_sp;
return bp_loc_sp;
}
void
@ -226,22 +148,22 @@ BreakpointLocationSP
BreakpointLocationList::GetByIndex (uint32_t i)
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
BreakpointLocationSP bp_loc_sp;
if (i < m_locations.size())
stop_sp = m_locations[i];
bp_loc_sp = m_locations[i];
return stop_sp;
return bp_loc_sp;
}
const BreakpointLocationSP
BreakpointLocationList::GetByIndex (uint32_t i) const
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
BreakpointLocationSP bp_loc_sp;
if (i < m_locations.size())
stop_sp = m_locations[i];
bp_loc_sp = m_locations[i];
return stop_sp;
return bp_loc_sp;
}
void
@ -291,12 +213,6 @@ BreakpointLocationList::GetNumResolvedLocations() const
return resolve_count;
}
break_id_t
BreakpointLocationList::GetNextID()
{
return ++m_next_id;
}
void
BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
{