1 //===-- FormatCache.cpp ------------------------------------------*- C++
2 //-*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 
11 
12 
13 #include "lldb/DataFormatters/FormatCache.h"
14 
15 using namespace lldb;
16 using namespace lldb_private;
17 
18 FormatCache::Entry::Entry()
19     : m_format_cached(false), m_summary_cached(false),
20       m_synthetic_cached(false), m_validator_cached(false) {}
21 
22 bool FormatCache::Entry::IsFormatCached() { return m_format_cached; }
23 
24 bool FormatCache::Entry::IsSummaryCached() { return m_summary_cached; }
25 
26 bool FormatCache::Entry::IsSyntheticCached() { return m_synthetic_cached; }
27 
28 bool FormatCache::Entry::IsValidatorCached() { return m_validator_cached; }
29 
30 void FormatCache::Entry::Get(lldb::TypeFormatImplSP &retval) {
31   retval = m_format_sp;
32 }
33 
34 void FormatCache::Entry::Get(lldb::TypeSummaryImplSP &retval) {
35   retval = m_summary_sp;
36 }
37 
38 void FormatCache::Entry::Get(lldb::SyntheticChildrenSP &retval) {
39   retval = m_synthetic_sp;
40 }
41 
42 void FormatCache::Entry::Get(lldb::TypeValidatorImplSP &retval) {
43   retval = m_validator_sp;
44 }
45 
46 void FormatCache::Entry::Set(lldb::TypeFormatImplSP format_sp) {
47   m_format_cached = true;
48   m_format_sp = format_sp;
49 }
50 
51 void FormatCache::Entry::Set(lldb::TypeSummaryImplSP summary_sp) {
52   m_summary_cached = true;
53   m_summary_sp = summary_sp;
54 }
55 
56 void FormatCache::Entry::Set(lldb::SyntheticChildrenSP synthetic_sp) {
57   m_synthetic_cached = true;
58   m_synthetic_sp = synthetic_sp;
59 }
60 
61 void FormatCache::Entry::Set(lldb::TypeValidatorImplSP validator_sp) {
62   m_validator_cached = true;
63   m_validator_sp = validator_sp;
64 }
65 
66 FormatCache::FormatCache()
67     : m_map(), m_mutex()
68 #ifdef LLDB_CONFIGURATION_DEBUG
69       ,
70       m_cache_hits(0), m_cache_misses(0)
71 #endif
72 {
73 }
74 
75 FormatCache::Entry &FormatCache::GetEntry(ConstString type) {
76   auto i = m_map.find(type), e = m_map.end();
77   if (i != e)
78     return i->second;
79   m_map[type] = FormatCache::Entry();
80   return m_map[type];
81 }
82 
83 template<> bool FormatCache::Entry::IsCached<lldb::TypeFormatImplSP>() {
84   return IsFormatCached();
85 }
86 template<> bool FormatCache::Entry::IsCached<lldb::TypeSummaryImplSP> () {
87   return IsSummaryCached();
88 }
89 template<> bool FormatCache::Entry::IsCached<lldb::SyntheticChildrenSP>() {
90   return IsSyntheticCached();
91 }
92 template<> bool FormatCache::Entry::IsCached<lldb::TypeValidatorImplSP>() {
93   return IsValidatorCached();
94 }
95 
96 template <typename ImplSP>
97 bool FormatCache::Get(ConstString type, ImplSP &format_impl_sp) {
98   std::lock_guard<std::recursive_mutex> guard(m_mutex);
99   auto entry = GetEntry(type);
100   if (entry.IsCached<ImplSP>()) {
101 #ifdef LLDB_CONFIGURATION_DEBUG
102     m_cache_hits++;
103 #endif
104     entry.Get(format_impl_sp);
105     return true;
106   }
107 #ifdef LLDB_CONFIGURATION_DEBUG
108   m_cache_misses++;
109 #endif
110   format_impl_sp.reset();
111   return false;
112 }
113 
114 /// Explicit instantiations for the four types.
115 /// \{
116 template bool
117 FormatCache::Get<lldb::TypeValidatorImplSP>(ConstString,
118                                             lldb::TypeValidatorImplSP &);
119 template bool
120 FormatCache::Get<lldb::TypeFormatImplSP>(ConstString, lldb::TypeFormatImplSP &);
121 template bool
122 FormatCache::Get<lldb::TypeSummaryImplSP>(ConstString,
123                                           lldb::TypeSummaryImplSP &);
124 template bool
125 FormatCache::Get<lldb::SyntheticChildrenSP>(ConstString,
126                                             lldb::SyntheticChildrenSP &);
127 /// \}
128 
129 void FormatCache::Set(ConstString type, lldb::TypeFormatImplSP &format_sp) {
130   std::lock_guard<std::recursive_mutex> guard(m_mutex);
131   GetEntry(type).Set(format_sp);
132 }
133 
134 void FormatCache::Set(ConstString type, lldb::TypeSummaryImplSP &summary_sp) {
135   std::lock_guard<std::recursive_mutex> guard(m_mutex);
136   GetEntry(type).Set(summary_sp);
137 }
138 
139 void FormatCache::Set(ConstString type,
140                       lldb::SyntheticChildrenSP &synthetic_sp) {
141   std::lock_guard<std::recursive_mutex> guard(m_mutex);
142   GetEntry(type).Set(synthetic_sp);
143 }
144 
145 void FormatCache::Set(ConstString type,
146                       lldb::TypeValidatorImplSP &validator_sp) {
147   std::lock_guard<std::recursive_mutex> guard(m_mutex);
148   GetEntry(type).Set(validator_sp);
149 }
150 
151 void FormatCache::Clear() {
152   std::lock_guard<std::recursive_mutex> guard(m_mutex);
153   m_map.clear();
154 }
155