summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/ThreadSafeSTLMap.h128
-rw-r--r--lldb/include/lldb/Core/ThreadSafeSTLVector.h72
-rw-r--r--lldb/include/lldb/Core/ValueObjectSyntheticFilter.h15
-rw-r--r--lldb/source/Core/ValueObjectSyntheticFilter.cpp49
4 files changed, 47 insertions, 217 deletions
diff --git a/lldb/include/lldb/Core/ThreadSafeSTLMap.h b/lldb/include/lldb/Core/ThreadSafeSTLMap.h
deleted file mode 100644
index df0208cd49b..00000000000
--- 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 e1666a69ef7..00000000000
--- 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 3b14a3e9f38..ec395095351 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 @@ protected:
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 a6bf35eac70..a30be1b0833 100644
--- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
@@ -48,8 +48,9 @@ public:
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;
OpenPOWER on IntegriCloud