Author: Raphael Isemann
Date: 2019-12-03T09:18:44+01:00
New Revision: 315600f480055f5143aaa245f25bd25221edfa91

URL: 
https://github.com/llvm/llvm-project/commit/315600f480055f5143aaa245f25bd25221edfa91
DIFF: 
https://github.com/llvm/llvm-project/commit/315600f480055f5143aaa245f25bd25221edfa91.diff

LOG: [lldb][NFC] Remove ThreadSafeSTLVector and ThreadSafeSTLMap and their use 
in ValueObjectSynthetic

Summary:
ThreadSafeSTLVector and ThreadSafeSTLMap are not useful for achieving any 
degree of thread safety in LLDB
and should be removed before they are used in more places. They are only used 
(unsurprisingly incorrectly) in
`ValueObjectSynthetic::GetChildAtIndex`, so this patch replaces their use there 
with a simple mutex with which
we guard the related data structures. This doesn't make 
ValueObjectSynthetic::GetChildAtIndex
any more thread-safe, but on the other hand it at least allows us to get rid of 
the ThreadSafeSTL* data structures
without changing the observable behaviour of ValueObjectSynthetic (beside that 
it is now a few bytes smaller).

Reviewers: labath, JDevlieghere, jingham

Reviewed By: labath

Subscribers: lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D70845

Added: 
    

Modified: 
    lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
    lldb/source/Core/ValueObjectSyntheticFilter.cpp

Removed: 
    lldb/include/lldb/Core/ThreadSafeSTLMap.h
    lldb/include/lldb/Core/ThreadSafeSTLVector.h


################################################################################
diff  --git a/lldb/include/lldb/Core/ThreadSafeSTLMap.h 
b/lldb/include/lldb/Core/ThreadSafeSTLMap.h
deleted file mode 100644
index df0208cd49b3..000000000000
--- a/lldb/include/lldb/Core/ThreadSafeSTLMap.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//===-- ThreadSafeSTLMap.h --------------------------------------*- C++ 
-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ThreadSafeSTLMap_h_
-#define liblldb_ThreadSafeSTLMap_h_
-
-#include <map>
-#include <mutex>
-
-#include "lldb/lldb-defines.h"
-
-namespace lldb_private {
-
-template <typename _Key, typename _Tp> class ThreadSafeSTLMap {
-public:
-  typedef std::map<_Key, _Tp> collection;
-  typedef typename collection::iterator iterator;
-  typedef typename collection::const_iterator const_iterator;
-  // Constructors and Destructors
-  ThreadSafeSTLMap() : m_collection(), m_mutex() {}
-
-  ~ThreadSafeSTLMap() {}
-
-  bool IsEmpty() const {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return m_collection.empty();
-  }
-
-  void Clear() {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return m_collection.clear();
-  }
-
-  size_t Erase(const _Key &key) {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return EraseNoLock(key);
-  }
-
-  size_t EraseNoLock(const _Key &key) { return m_collection.erase(key); }
-
-  bool GetValueForKey(const _Key &key, _Tp &value) const {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return GetValueForKeyNoLock(key, value);
-  }
-
-  // Call this if you have already manually locked the mutex using the
-  // GetMutex() accessor
-  bool GetValueForKeyNoLock(const _Key &key, _Tp &value) const {
-    const_iterator pos = m_collection.find(key);
-    if (pos != m_collection.end()) {
-      value = pos->second;
-      return true;
-    }
-    return false;
-  }
-
-  bool GetFirstKeyForValue(const _Tp &value, _Key &key) const {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return GetFirstKeyForValueNoLock(value, key);
-  }
-
-  bool GetFirstKeyForValueNoLock(const _Tp &value, _Key &key) const {
-    const_iterator pos, end = m_collection.end();
-    for (pos = m_collection.begin(); pos != end; ++pos) {
-      if (pos->second == value) {
-        key = pos->first;
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool LowerBound(const _Key &key, _Key &match_key, _Tp &match_value,
-                  bool decrement_if_not_equal) const {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return LowerBoundNoLock(key, match_key, match_value,
-                            decrement_if_not_equal);
-  }
-
-  bool LowerBoundNoLock(const _Key &key, _Key &match_key, _Tp &match_value,
-                        bool decrement_if_not_equal) const {
-    const_iterator pos = m_collection.lower_bound(key);
-    if (pos != m_collection.end()) {
-      match_key = pos->first;
-      if (decrement_if_not_equal && key != match_key &&
-          pos != m_collection.begin()) {
-        --pos;
-        match_key = pos->first;
-      }
-      match_value = pos->second;
-      return true;
-    }
-    return false;
-  }
-
-  iterator lower_bound_unsafe(const _Key &key) {
-    return m_collection.lower_bound(key);
-  }
-
-  void SetValueForKey(const _Key &key, const _Tp &value) {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    SetValueForKeyNoLock(key, value);
-  }
-
-  // Call this if you have already manually locked the mutex using the
-  // GetMutex() accessor
-  void SetValueForKeyNoLock(const _Key &key, const _Tp &value) {
-    m_collection[key] = value;
-  }
-
-  std::recursive_mutex &GetMutex() { return m_mutex; }
-
-private:
-  collection m_collection;
-  mutable std::recursive_mutex m_mutex;
-
-  // For ThreadSafeSTLMap only
-  DISALLOW_COPY_AND_ASSIGN(ThreadSafeSTLMap);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_ThreadSafeSTLMap_h_

diff  --git a/lldb/include/lldb/Core/ThreadSafeSTLVector.h 
b/lldb/include/lldb/Core/ThreadSafeSTLVector.h
deleted file mode 100644
index e1666a69ef7e..000000000000
--- a/lldb/include/lldb/Core/ThreadSafeSTLVector.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===-- ThreadSafeSTLVector.h ------------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ThreadSafeSTLVector_h_
-#define liblldb_ThreadSafeSTLVector_h_
-
-#include <mutex>
-#include <vector>
-
-#include "lldb/lldb-defines.h"
-
-namespace lldb_private {
-
-template <typename _Object> class ThreadSafeSTLVector {
-public:
-  typedef std::vector<_Object> collection;
-  typedef typename collection::iterator iterator;
-  typedef typename collection::const_iterator const_iterator;
-  // Constructors and Destructors
-  ThreadSafeSTLVector() : m_collection(), m_mutex() {}
-
-  ~ThreadSafeSTLVector() = default;
-
-  bool IsEmpty() const {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return m_collection.empty();
-  }
-
-  void Clear() {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return m_collection.clear();
-  }
-
-  size_t GetCount() {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return m_collection.size();
-  }
-
-  void AppendObject(_Object &object) {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    m_collection.push_back(object);
-  }
-
-  _Object GetObject(size_t index) {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    return m_collection.at(index);
-  }
-
-  void SetObject(size_t index, const _Object &object) {
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    m_collection.at(index) = object;
-  }
-
-  std::recursive_mutex &GetMutex() { return m_mutex; }
-
-private:
-  collection m_collection;
-  mutable std::recursive_mutex m_mutex;
-
-  // For ThreadSafeSTLVector only
-  DISALLOW_COPY_AND_ASSIGN(ThreadSafeSTLVector);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_ThreadSafeSTLVector_h_

diff  --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h 
b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
index 3b14a3e9f388..ec395095351d 100644
--- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
+++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -9,8 +9,6 @@
 #ifndef liblldb_ValueObjectSyntheticFilter_h_
 #define liblldb_ValueObjectSyntheticFilter_h_
 
-#include "lldb/Core/ThreadSafeSTLMap.h"
-#include "lldb/Core/ThreadSafeSTLVector.h"
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Utility/ConstString.h"
@@ -135,19 +133,24 @@ class ValueObjectSynthetic : public ValueObject {
   lldb::SyntheticChildrenSP m_synth_sp;
   std::unique_ptr<SyntheticChildrenFrontEnd> m_synth_filter_up;
 
-  typedef ThreadSafeSTLMap<uint32_t, ValueObject *> ByIndexMap;
-  typedef ThreadSafeSTLMap<const char *, uint32_t> NameToIndexMap;
-  typedef ThreadSafeSTLVector<lldb::ValueObjectSP> SyntheticChildrenCache;
+  typedef std::map<uint32_t, ValueObject *> ByIndexMap;
+  typedef std::map<const char *, uint32_t> NameToIndexMap;
+  typedef std::vector<lldb::ValueObjectSP> SyntheticChildrenCache;
 
   typedef ByIndexMap::iterator ByIndexIterator;
   typedef NameToIndexMap::iterator NameToIndexIterator;
 
+  std::mutex m_child_mutex;
+  /// Guarded by m_child_mutex;
   ByIndexMap m_children_byindex;
+  /// Guarded by m_child_mutex;
   NameToIndexMap m_name_toindex;
+  /// Guarded by m_child_mutex;
+  SyntheticChildrenCache m_synthetic_children_cache;
+
   uint32_t m_synthetic_children_count; // FIXME use the ValueObject's
                                        // ChildrenManager instead of a special
                                        // purpose solution
-  SyntheticChildrenCache m_synthetic_children_cache;
 
   ConstString m_parent_type_name;
 

diff  --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp 
b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
index a6bf35eac70a..a30be1b08338 100644
--- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
@@ -48,8 +48,9 @@ class DummySyntheticFrontEnd : public 
SyntheticChildrenFrontEnd {
 ValueObjectSynthetic::ValueObjectSynthetic(ValueObject &parent,
                                            lldb::SyntheticChildrenSP filter)
     : ValueObject(parent), m_synth_sp(filter), m_children_byindex(),
-      m_name_toindex(), m_synthetic_children_count(UINT32_MAX),
-      m_synthetic_children_cache(), m_parent_type_name(parent.GetTypeName()),
+      m_name_toindex(), m_synthetic_children_cache(),
+      m_synthetic_children_count(UINT32_MAX),
+      m_parent_type_name(parent.GetTypeName()),
       m_might_have_children(eLazyBoolCalculate),
       m_provides_value(eLazyBoolCalculate) {
   SetName(parent.GetName());
@@ -177,14 +178,20 @@ bool ValueObjectSynthetic::UpdateValue() {
               "filter said caches are stale - clearing",
               GetName().AsCString());
     // filter said that cached values are stale
-    m_children_byindex.Clear();
-    m_name_toindex.Clear();
+    {
+      std::lock_guard<std::mutex> guard(m_child_mutex);
+      m_children_byindex.clear();
+      m_name_toindex.clear();
+    }
     // usually, an object's value can change but this does not alter its
     // children count for a synthetic VO that might indeed happen, so we need
     // to tell the upper echelons that they need to come back to us asking for
     // children
     m_children_count_valid = false;
-    m_synthetic_children_cache.Clear();
+    {
+      std::lock_guard<std::mutex> guard(m_child_mutex);
+      m_synthetic_children_cache.clear();
+    }
     m_synthetic_children_count = UINT32_MAX;
     m_might_have_children = eLazyBoolCalculate;
   } else {
@@ -232,7 +239,16 @@ lldb::ValueObjectSP 
ValueObjectSynthetic::GetChildAtIndex(size_t idx,
   UpdateValueIfNeeded();
 
   ValueObject *valobj;
-  if (!m_children_byindex.GetValueForKey(idx, valobj)) {
+  bool child_is_cached;
+  {
+    std::lock_guard<std::mutex> guard(m_child_mutex);
+    auto cached_child_it = m_children_byindex.find(idx);
+    child_is_cached = cached_child_it != m_children_byindex.end();
+    if (child_is_cached)
+      valobj = cached_child_it->second;
+  }
+
+  if (!child_is_cached) {
     if (can_create && m_synth_filter_up != nullptr) {
       LLDB_LOGF(log,
                 "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
@@ -254,9 +270,12 @@ lldb::ValueObjectSP 
ValueObjectSynthetic::GetChildAtIndex(size_t idx,
       if (!synth_guy)
         return synth_guy;
 
-      if (synth_guy->IsSyntheticChildrenGenerated())
-        m_synthetic_children_cache.AppendObject(synth_guy);
-      m_children_byindex.SetValueForKey(idx, synth_guy.get());
+      {
+        std::lock_guard<std::mutex> guard(m_child_mutex);
+        if (synth_guy->IsSyntheticChildrenGenerated())
+          m_synthetic_children_cache.push_back(synth_guy);
+        m_children_byindex[idx] = synth_guy.get();
+      }
       synth_guy->SetPreferredDisplayLanguageIfNeeded(
           GetPreferredDisplayLanguage());
       return synth_guy;
@@ -297,13 +316,21 @@ size_t 
ValueObjectSynthetic::GetIndexOfChildWithName(ConstString name) {
   UpdateValueIfNeeded();
 
   uint32_t found_index = UINT32_MAX;
-  bool did_find = m_name_toindex.GetValueForKey(name.GetCString(), 
found_index);
+  bool did_find;
+  {
+    std::lock_guard<std::mutex> guard(m_child_mutex);
+    auto name_to_index = m_name_toindex.find(name.GetCString());
+    did_find = name_to_index != m_name_toindex.end();
+    if (did_find)
+      found_index = name_to_index->second;
+  }
 
   if (!did_find && m_synth_filter_up != nullptr) {
     uint32_t index = m_synth_filter_up->GetIndexOfChildWithName(name);
     if (index == UINT32_MAX)
       return index;
-    m_name_toindex.SetValueForKey(name.GetCString(), index);
+    std::lock_guard<std::mutex> guard(m_child_mutex);
+    m_name_toindex[name.GetCString()] = index;
     return index;
   } else if (!did_find && m_synth_filter_up == nullptr)
     return UINT32_MAX;


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to