1 //===-- FormatCache.cpp ---------------------------------------------------===//
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 
10 
11 
12 #include "lldb/DataFormatters/FormatCache.h"
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 
17 FormatCache::Entry::Entry()
18     : m_format_cached(false), m_summary_cached(false),
19       m_synthetic_cached(false) {}
20 
21 bool FormatCache::Entry::IsFormatCached() { return m_format_cached; }
22 
23 bool FormatCache::Entry::IsSummaryCached() { return m_summary_cached; }
24 
25 bool FormatCache::Entry::IsSyntheticCached() { return m_synthetic_cached; }
26 
27 void FormatCache::Entry::Get(lldb::TypeFormatImplSP &retval) {
28   retval = m_format_sp;
29 }
30 
31 void FormatCache::Entry::Get(lldb::TypeSummaryImplSP &retval) {
32   retval = m_summary_sp;
33 }
34 
35 void FormatCache::Entry::Get(lldb::SyntheticChildrenSP &retval) {
36   retval = m_synthetic_sp;
37 }
38 
39 void FormatCache::Entry::Set(lldb::TypeFormatImplSP format_sp) {
40   m_format_cached = true;
41   m_format_sp = format_sp;
42 }
43 
44 void FormatCache::Entry::Set(lldb::TypeSummaryImplSP summary_sp) {
45   m_summary_cached = true;
46   m_summary_sp = summary_sp;
47 }
48 
49 void FormatCache::Entry::Set(lldb::SyntheticChildrenSP synthetic_sp) {
50   m_synthetic_cached = true;
51   m_synthetic_sp = synthetic_sp;
52 }
53 
54 FormatCache::FormatCache()
55     : m_map(), m_mutex()
56 #ifdef LLDB_CONFIGURATION_DEBUG
57       ,
58       m_cache_hits(0), m_cache_misses(0)
59 #endif
60 {
61 }
62 
63 FormatCache::Entry &FormatCache::GetEntry(ConstString type) {
64   auto i = m_map.find(type), e = m_map.end();
65   if (i != e)
66     return i->second;
67   m_map[type] = FormatCache::Entry();
68   return m_map[type];
69 }
70 
71 namespace lldb_private {
72 
73 template<> bool FormatCache::Entry::IsCached<lldb::TypeFormatImplSP>() {
74   return IsFormatCached();
75 }
76 template<> bool FormatCache::Entry::IsCached<lldb::TypeSummaryImplSP> () {
77   return IsSummaryCached();
78 }
79 template<> bool FormatCache::Entry::IsCached<lldb::SyntheticChildrenSP>() {
80   return IsSyntheticCached();
81 }
82 
83 } // namespace lldb_private
84 
85 template <typename ImplSP>
86 bool FormatCache::Get(ConstString type, ImplSP &format_impl_sp) {
87   std::lock_guard<std::recursive_mutex> guard(m_mutex);
88   auto entry = GetEntry(type);
89   if (entry.IsCached<ImplSP>()) {
90 #ifdef LLDB_CONFIGURATION_DEBUG
91     m_cache_hits++;
92 #endif
93     entry.Get(format_impl_sp);
94     return true;
95   }
96 #ifdef LLDB_CONFIGURATION_DEBUG
97   m_cache_misses++;
98 #endif
99   format_impl_sp.reset();
100   return false;
101 }
102 
103 /// Explicit instantiations for the three types.
104 /// \{
105 template bool
106 FormatCache::Get<lldb::TypeFormatImplSP>(ConstString, lldb::TypeFormatImplSP &);
107 template bool
108 FormatCache::Get<lldb::TypeSummaryImplSP>(ConstString,
109                                           lldb::TypeSummaryImplSP &);
110 template bool
111 FormatCache::Get<lldb::SyntheticChildrenSP>(ConstString,
112                                             lldb::SyntheticChildrenSP &);
113 /// \}
114 
115 void FormatCache::Set(ConstString type, lldb::TypeFormatImplSP &format_sp) {
116   std::lock_guard<std::recursive_mutex> guard(m_mutex);
117   GetEntry(type).Set(format_sp);
118 }
119 
120 void FormatCache::Set(ConstString type, lldb::TypeSummaryImplSP &summary_sp) {
121   std::lock_guard<std::recursive_mutex> guard(m_mutex);
122   GetEntry(type).Set(summary_sp);
123 }
124 
125 void FormatCache::Set(ConstString type,
126                       lldb::SyntheticChildrenSP &synthetic_sp) {
127   std::lock_guard<std::recursive_mutex> guard(m_mutex);
128   GetEntry(type).Set(synthetic_sp);
129 }
130 
131 void FormatCache::Clear() {
132   std::lock_guard<std::recursive_mutex> guard(m_mutex);
133   m_map.clear();
134 }
135