Skip to content

Commit ffcb6d7

Browse files
Merge pull request #11066 from augusto2112/cache-failure-find-types
[lldb] Fix caching, add lookup failures to TSSTyperef's LookupClangType
2 parents d185373 + b60b9ef commit ffcb6d7

File tree

3 files changed

+81
-11
lines changed

3 files changed

+81
-11
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===-- ThreadSafeStringMap.h ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_UTILITY_THREADSAFESTRINGMAP_H
10+
#define LLDB_UTILITY_THREADSAFESTRINGMAP_H
11+
12+
#include <mutex>
13+
14+
#include "llvm/ADT/StringMap.h"
15+
16+
namespace lldb_private {
17+
18+
template <typename _ValueType> class ThreadSafeStringMap {
19+
public:
20+
typedef llvm::StringMap<_ValueType> LLVMMapType;
21+
22+
ThreadSafeStringMap(unsigned map_initial_capacity = 0)
23+
: m_map(map_initial_capacity), m_mutex() {}
24+
25+
void Insert(llvm::StringRef k, _ValueType v) {
26+
std::lock_guard<std::mutex> guard(m_mutex);
27+
m_map.insert(std::make_pair(k, v));
28+
}
29+
30+
void Erase(llvm::StringRef k) {
31+
std::lock_guard<std::mutex> guard(m_mutex);
32+
m_map.erase(k);
33+
}
34+
35+
_ValueType Lookup(llvm::StringRef k) {
36+
std::lock_guard<std::mutex> guard(m_mutex);
37+
return m_map.lookup(k);
38+
}
39+
40+
bool Lookup(llvm::StringRef k, _ValueType &v) {
41+
std::lock_guard<std::mutex> guard(m_mutex);
42+
auto iter = m_map.find(k), end = m_map.end();
43+
if (iter == end)
44+
return false;
45+
v = iter->second;
46+
return true;
47+
}
48+
49+
void Clear() {
50+
std::lock_guard<std::mutex> guard(m_mutex);
51+
m_map.clear();
52+
}
53+
54+
protected:
55+
LLVMMapType m_map;
56+
std::mutex m_mutex;
57+
};
58+
59+
} // namespace lldb_private
60+
61+
#endif // LLDB_UTILITY_THREADSAFESTRINGMAP_H

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -422,35 +422,42 @@ TypeSP TypeSystemSwiftTypeRef::LookupClangType(
422422
TypeSP TypeSystemSwiftTypeRefForExpressions::LookupClangType(
423423
StringRef name_ref, llvm::ArrayRef<CompilerContext> decl_context,
424424
SymbolContext sc) {
425-
// Check the cache first. Negative results are also cached.
425+
// Build up the cache key (the concatenation of the name and the stringified
426+
// decl context).
427+
StreamString stream;
428+
stream << name_ref;
429+
for (auto &context : decl_context)
430+
context.Dump(stream);
431+
426432
TypeSP result;
427-
ConstString name(name_ref);
428-
if (m_clang_type_cache.Lookup(name.AsCString(), result))
433+
// Check the cache first. Negative results are also cached.
434+
auto key = stream.GetString();
435+
if (m_clang_type_cache.Lookup(key, result))
429436
return result;
430437

431-
ModuleSP cur_module = sc.module_sp;
432438
auto lookup = [&](const ModuleSP &m) -> bool {
433-
// Already visited this.
434-
if (m == cur_module)
435-
return true;
436-
437439
// Don't recursively call into LookupClangTypes() to avoid filling
438440
// hundreds of image caches with negative results.
439441
result = ::LookupClangType(const_cast<Module &>(*m), decl_context);
440442
// Cache it in the expression context.
441443
if (result)
442-
m_clang_type_cache.Insert(name.AsCString(), result);
444+
m_clang_type_cache.Insert(key, result);
443445
return !result;
444446
};
445447

446448
// Visit the current module first as a performance optimization heuristic.
449+
ModuleSP cur_module = sc.module_sp;
447450
if (cur_module)
448451
if (!lookup(cur_module))
449452
return result;
450453

451454
if (TargetSP target_sp = GetTargetWP().lock())
452455
target_sp->GetImages().ForEach(lookup);
453456

457+
/// Cache the negative result. This is safe to do because ModulesDidLoad will
458+
/// clear the cache.
459+
if (!result)
460+
m_clang_type_cache.Insert(key, result);
454461
return result;
455462
}
456463

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "lldb/Symbol/SymbolContext.h"
1919
#include "lldb/Target/ExecutionContext.h"
2020
#include "lldb/Utility/ThreadSafeDenseMap.h"
21+
#include "lldb/Utility/ThreadSafeStringMap.h"
2122
#include "swift/Demangling/ManglingFlavor.h"
2223

2324
// FIXME: needed only for the DenseMap.
@@ -686,8 +687,9 @@ class TypeSystemSwiftTypeRefForExpressions : public TypeSystemSwiftTypeRef {
686687
/// Perform all the implicit imports for the current frame.
687688
mutable std::unique_ptr<SymbolContext> m_initial_symbol_context_up;
688689
std::unique_ptr<SwiftPersistentExpressionState> m_persistent_state_up;
689-
/// Map ConstString Clang type identifiers to Clang types.
690-
ThreadSafeDenseMap<const char *, lldb::TypeSP> m_clang_type_cache;
690+
/// Map ConstString Clang type identifiers and the concatenation of the
691+
/// compiler context used to find them to Clang types.
692+
ThreadSafeStringMap<lldb::TypeSP> m_clang_type_cache;
691693
};
692694

693695
} // namespace lldb_private

0 commit comments

Comments
 (0)