Make the Watchpoint IDs unique per target, not across targets as before.
Now Each newly created target has its Watchpoint IDs as 1, 2, 3 ...


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@151435 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Breakpoint/Watchpoint.cpp b/source/Breakpoint/Watchpoint.cpp
index 02ae8b8..a0b4756 100644
--- a/source/Breakpoint/Watchpoint.cpp
+++ b/source/Breakpoint/Watchpoint.cpp
@@ -24,9 +24,9 @@
 using namespace lldb_private;
 
 Watchpoint::Watchpoint (lldb::addr_t addr, size_t size, bool hardware) :
-    StoppointLocation (GetNextID(), addr, size, hardware),
+    StoppointLocation (0, addr, size, hardware),
     m_target(NULL),
-    m_enabled(0),
+    m_enabled(false),
     m_is_hardware(hardware),
     m_watch_read(0),
     m_watch_write(0),
@@ -36,6 +36,7 @@
     m_callback(NULL),
     m_callback_baton(NULL),
     m_decl_str(),
+    m_watch_spec_str(),
     m_error()
 {
 }
@@ -44,13 +45,6 @@
 {
 }
 
-break_id_t
-Watchpoint::GetNextID()
-{
-    static break_id_t g_next_ID = 0;
-    return ++g_next_ID;
-}
-
 bool
 Watchpoint::SetCallback (WatchpointHitCallback callback, void *callback_baton)
 {
@@ -66,6 +60,13 @@
     return;
 }
 
+void
+Watchpoint::SetWatchSpec (std::string &str)
+{
+    m_watch_spec_str = str;
+    return;
+}
+
 // Override default impl of StoppointLocation::IsHardware() since m_is_hardware
 // member field is more accurate.
 bool
@@ -117,13 +118,15 @@
               GetID(),
               GetLoadAddress(),
               m_byte_size,
-              m_enabled ? "enabled" : "disabled",
+              IsEnabled() ? "enabled" : "disabled",
               m_watch_read ? "r" : "",
               m_watch_write ? "w" : "");
 
     if (description_level >= lldb::eDescriptionLevelFull) {
         if (!m_decl_str.empty())
             s->Printf("\n    declare @ '%s'", m_decl_str.c_str());
+        if (!m_watch_spec_str.empty())
+            s->Printf("\n    static watchpoint spec = '%s'", m_watch_spec_str.c_str());
         if (GetConditionText())
             s->Printf("\n    condition = '%s'", GetConditionText());
     }
diff --git a/source/Breakpoint/WatchpointList.cpp b/source/Breakpoint/WatchpointList.cpp
index 9721b08..a3f2bbb 100644
--- a/source/Breakpoint/WatchpointList.cpp
+++ b/source/Breakpoint/WatchpointList.cpp
@@ -19,8 +19,9 @@
 using namespace lldb_private;
 
 WatchpointList::WatchpointList() :
-    m_address_to_watchpoint (),
-    m_mutex (Mutex::eMutexTypeRecursive)
+    m_watchpoints (),
+    m_mutex (Mutex::eMutexTypeRecursive),
+    m_next_wp_id (0)
 {
 }
 
@@ -28,21 +29,13 @@
 {
 }
 
-// Add watchpoint loc to the list.  However, if the element already exists in the
-// list, then replace it with the input one.
-
+// Add a watchpoint to the list.
 lldb::watch_id_t
 WatchpointList::Add (const WatchpointSP &wp_sp)
 {
     Mutex::Locker locker (m_mutex);
-    lldb::addr_t wp_addr = wp_sp->GetLoadAddress();
-    addr_map::iterator iter = m_address_to_watchpoint.find(wp_addr);
-
-    if (iter == m_address_to_watchpoint.end())
-        m_address_to_watchpoint.insert(iter, addr_map::value_type(wp_addr, wp_sp));
-    else
-        m_address_to_watchpoint[wp_addr] = wp_sp;
-
+    wp_sp->SetID(++m_next_wp_id);
+    m_watchpoints.push_back(wp_sp);
     return wp_sp->GetID();
 }
 
@@ -59,11 +52,11 @@
     s->Printf("%p: ", this);
     //s->Indent();
     s->Printf("WatchpointList with %zu Watchpoints:\n",
-              m_address_to_watchpoint.size());
+              m_watchpoints.size());
     s->IndentMore();
-    addr_map::const_iterator pos, end = m_address_to_watchpoint.end();
-    for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos)
-        pos->second->DumpWithLevel(s, description_level);
+    wp_collection::const_iterator pos, end = m_watchpoints.end();
+    for (pos = m_watchpoints.begin(); pos != end; ++pos)
+        (*pos)->DumpWithLevel(s, description_level);
     s->IndentLess();
 }
 
@@ -72,11 +65,32 @@
 {
     WatchpointSP wp_sp;
     Mutex::Locker locker (m_mutex);
-    if (!m_address_to_watchpoint.empty())
+    if (!m_watchpoints.empty())
     {
-        addr_map::const_iterator pos = m_address_to_watchpoint.find (addr);
-        if (pos != m_address_to_watchpoint.end())
-            wp_sp = pos->second;
+        wp_collection::const_iterator pos, end = m_watchpoints.end();
+        for (pos = m_watchpoints.begin(); pos != end; ++pos)
+            if ((*pos)->GetLoadAddress() == addr) {
+                wp_sp = *pos;
+                break;
+            }
+    }
+
+    return wp_sp;
+}
+
+const WatchpointSP
+WatchpointList::FindBySpec (std::string spec) const
+{
+    WatchpointSP wp_sp;
+    Mutex::Locker locker (m_mutex);
+    if (!m_watchpoints.empty())
+    {
+        wp_collection::const_iterator pos, end = m_watchpoints.end();
+        for (pos = m_watchpoints.begin(); pos != end; ++pos)
+            if ((*pos)->GetWatchSpec() == spec) {
+                wp_sp = *pos;
+                break;
+            }
     }
 
     return wp_sp;
@@ -90,27 +104,27 @@
     {
     }
 
-    bool operator() (std::pair <lldb::addr_t, WatchpointSP> val_pair) const
+    bool operator() (const WatchpointSP &wp) const
     {
-        return m_watch_id == val_pair.second.get()->GetID();
+        return m_watch_id == wp->GetID();
     }
 
 private:
    const lldb::watch_id_t m_watch_id;
 };
 
-WatchpointList::addr_map::iterator
+WatchpointList::wp_collection::iterator
 WatchpointList::GetIDIterator (lldb::watch_id_t watch_id)
 {
-    return std::find_if(m_address_to_watchpoint.begin(), m_address_to_watchpoint.end(), // Search full range
-                        WatchpointIDMatches(watch_id));                                 // Predicate
+    return std::find_if(m_watchpoints.begin(), m_watchpoints.end(), // Search full range
+                        WatchpointIDMatches(watch_id));             // Predicate
 }
 
-WatchpointList::addr_map::const_iterator
+WatchpointList::wp_collection::const_iterator
 WatchpointList::GetIDConstIterator (lldb::watch_id_t watch_id) const
 {
-    return std::find_if(m_address_to_watchpoint.begin(), m_address_to_watchpoint.end(), // Search full range
-                        WatchpointIDMatches(watch_id));                                 // Predicate
+    return std::find_if(m_watchpoints.begin(), m_watchpoints.end(), // Search full range
+                        WatchpointIDMatches(watch_id));             // Predicate
 }
 
 WatchpointSP
@@ -118,9 +132,9 @@
 {
     WatchpointSP wp_sp;
     Mutex::Locker locker (m_mutex);
-    addr_map::const_iterator pos = GetIDConstIterator(watch_id);
-    if (pos != m_address_to_watchpoint.end())
-        wp_sp = pos->second;
+    wp_collection::const_iterator pos = GetIDConstIterator(watch_id);
+    if (pos != m_watchpoints.end())
+        wp_sp = *pos;
 
     return wp_sp;
 }
@@ -136,16 +150,27 @@
     return LLDB_INVALID_WATCH_ID;
 }
 
+lldb::watch_id_t
+WatchpointList::FindIDBySpec (std::string spec)
+{
+    WatchpointSP wp_sp = FindBySpec (spec);
+    if (wp_sp)
+    {
+        return wp_sp->GetID();
+    }
+    return LLDB_INVALID_WATCH_ID;
+}
+
 WatchpointSP
 WatchpointList::GetByIndex (uint32_t i)
 {
     Mutex::Locker locker (m_mutex);
     WatchpointSP wp_sp;
-    if (i < m_address_to_watchpoint.size())
+    if (i < m_watchpoints.size())
     {
-        addr_map::const_iterator pos = m_address_to_watchpoint.begin();
+        wp_collection::const_iterator pos = m_watchpoints.begin();
         std::advance(pos, i);
-        wp_sp = pos->second;
+        wp_sp = *pos;
     }
     return wp_sp;
 }
@@ -155,23 +180,33 @@
 {
     Mutex::Locker locker (m_mutex);
     WatchpointSP wp_sp;
-    if (i < m_address_to_watchpoint.size())
+    if (i < m_watchpoints.size())
     {
-        addr_map::const_iterator pos = m_address_to_watchpoint.begin();
+        wp_collection::const_iterator pos = m_watchpoints.begin();
         std::advance(pos, i);
-        wp_sp = pos->second;
+        wp_sp = *pos;
     }
     return wp_sp;
 }
 
+std::vector<lldb::watch_id_t>
+WatchpointList::GetWatchpointIDs() const
+{
+    std::vector<lldb::watch_id_t> IDs;
+    wp_collection::const_iterator pos, end = m_watchpoints.end();
+    for (pos = m_watchpoints.begin(); pos != end; ++pos)
+        IDs.push_back((*pos)->GetID());
+    return IDs;
+}
+
 bool
 WatchpointList::Remove (lldb::watch_id_t watch_id)
 {
     Mutex::Locker locker (m_mutex);
-    addr_map::iterator pos = GetIDIterator(watch_id);
-    if (pos != m_address_to_watchpoint.end())
+    wp_collection::iterator pos = GetIDIterator(watch_id);
+    if (pos != m_watchpoints.end())
     {
-        m_address_to_watchpoint.erase(pos);
+        m_watchpoints.erase(pos);
         return true;
     }
     return false;
@@ -182,9 +217,9 @@
 {
     uint32_t hit_count = 0;
     Mutex::Locker locker (m_mutex);
-    addr_map::const_iterator pos, end = m_address_to_watchpoint.end();
-    for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos)
-        hit_count += pos->second->GetHitCount();
+    wp_collection::const_iterator pos, end = m_watchpoints.end();
+    for (pos = m_watchpoints.begin(); pos != end; ++pos)
+        hit_count += (*pos)->GetHitCount();
     return hit_count;
 }
 
@@ -209,12 +244,12 @@
 WatchpointList::GetDescription (Stream *s, lldb::DescriptionLevel level)
 {
     Mutex::Locker locker (m_mutex);
-    addr_map::iterator pos, end = m_address_to_watchpoint.end();
+    wp_collection::iterator pos, end = m_watchpoints.end();
 
-    for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos)
+    for (pos = m_watchpoints.begin(); pos != end; ++pos)
     {
         s->Printf(" ");
-        pos->second->Dump(s);
+        (*pos)->Dump(s);
     }
 }
 
@@ -223,16 +258,16 @@
 {
     Mutex::Locker locker(m_mutex);
 
-    addr_map::iterator pos, end = m_address_to_watchpoint.end();
-    for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos)
-        pos->second->SetEnabled (enabled);
+    wp_collection::iterator pos, end = m_watchpoints.end();
+    for (pos = m_watchpoints.begin(); pos != end; ++pos)
+        (*pos)->SetEnabled (enabled);
 }
 
 void
 WatchpointList::RemoveAll ()
 {
     Mutex::Locker locker(m_mutex);
-    m_address_to_watchpoint.clear();
+    m_watchpoints.clear();
 }
 
 void
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 88976ef..3a26b77 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -138,7 +138,10 @@
         m_breakpoint_list.ClearAllBreakpointSites();
         m_internal_breakpoint_list.ClearAllBreakpointSites();
         // Disable watchpoints just on the debugger side.
+        Mutex::Locker locker;
+        this->GetWatchpointList().GetListMutex(locker);
         DisableAllWatchpoints(false);
+        ClearAllWatchpointHitCounts();
         m_process_sp.reset();
     }
 }
@@ -672,6 +675,26 @@
     return true; // Success!
 }
 
+// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
+bool
+Target::ClearAllWatchpointHitCounts ()
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    if (log)
+        log->Printf ("Target::%s\n", __FUNCTION__);
+
+    size_t num_watchpoints = m_watchpoint_list.GetSize();
+    for (size_t i = 0; i < num_watchpoints; ++i)
+    {
+        WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+        if (!wp_sp)
+            return false;
+
+        wp_sp->ResetHitCount();
+    }
+    return true; // Success!
+}
+
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list
 // during these operations.
 bool