99#ifndef LLDB_TARGET_STATISTICS_H
1010#define LLDB_TARGET_STATISTICS_H
1111
12+ #include " lldb/DataFormatters/TypeSummary.h"
1213#include " lldb/Utility/ConstString.h"
1314#include " lldb/Utility/RealpathPrefixes.h"
1415#include " lldb/Utility/Stream.h"
1718#include " llvm/Support/JSON.h"
1819#include < atomic>
1920#include < chrono>
21+ #include < mutex>
2022#include < optional>
2123#include < ratio>
2224#include < string>
@@ -26,6 +28,9 @@ namespace lldb_private {
2628
2729using StatsClock = std::chrono::high_resolution_clock;
2830using StatsTimepoint = std::chrono::time_point<StatsClock>;
31+ class SummaryStatistics ;
32+ // Declaring here as there is no private forward
33+ typedef std::shared_ptr<SummaryStatistics> SummaryStatisticsSP;
2934
3035class StatsDuration {
3136public:
@@ -175,6 +180,81 @@ struct StatisticsOptions {
175180 std::optional<bool > m_include_transcript;
176181};
177182
183+ // / A class that represents statistics about a TypeSummaryProviders invocations
184+ // / \note All members of this class need to be accessed in a thread safe manner
185+ class SummaryStatistics {
186+ public:
187+ explicit SummaryStatistics (std::string name, std::string impl_type)
188+ : m_total_time(), m_impl_type(std::move(impl_type)),
189+ m_name(std::move(name)), m_count(0 ) {}
190+
191+ std::string GetName () const { return m_name; };
192+ double GetTotalTime () const { return m_total_time.get ().count (); }
193+
194+ uint64_t GetSummaryCount () const {
195+ return m_count.load (std::memory_order_relaxed);
196+ }
197+
198+ StatsDuration &GetDurationReference () { return m_total_time; };
199+
200+ std::string GetSummaryKindName () const { return m_impl_type; }
201+
202+ llvm::json::Value ToJSON () const ;
203+
204+ // / Basic RAII class to increment the summary count when the call is complete.
205+ class SummaryInvocation {
206+ public:
207+ SummaryInvocation (SummaryStatisticsSP summary_stats)
208+ : m_stats(summary_stats),
209+ m_elapsed_time (summary_stats->GetDurationReference ()) {}
210+ ~SummaryInvocation () { m_stats->OnInvoked (); }
211+
212+ // / Delete the copy constructor and assignment operator to prevent
213+ // / accidental double counting.
214+ // / @{
215+ SummaryInvocation (const SummaryInvocation &) = delete;
216+ SummaryInvocation &operator =(const SummaryInvocation &) = delete;
217+ // / @}
218+
219+ private:
220+ SummaryStatisticsSP m_stats;
221+ ElapsedTime m_elapsed_time;
222+ };
223+
224+ private:
225+ void OnInvoked () noexcept { m_count.fetch_add (1 , std::memory_order_relaxed); }
226+ lldb_private::StatsDuration m_total_time;
227+ const std::string m_impl_type;
228+ const std::string m_name;
229+ std::atomic<uint64_t > m_count;
230+ };
231+
232+ // / A class that wraps a std::map of SummaryStatistics objects behind a mutex.
233+ class SummaryStatisticsCache {
234+ public:
235+ // / Get the SummaryStatistics object for a given provider name, or insert
236+ // / if statistics for that provider is not in the map.
237+ SummaryStatisticsSP
238+ GetSummaryStatisticsForProvider (lldb_private::TypeSummaryImpl &provider) {
239+ std::lock_guard<std::mutex> guard (m_map_mutex);
240+ if (auto iterator = m_summary_stats_map.find (provider.GetName ());
241+ iterator != m_summary_stats_map.end ())
242+ return iterator->second ;
243+
244+ auto it = m_summary_stats_map.try_emplace (
245+ provider.GetName (),
246+ std::make_shared<SummaryStatistics>(provider.GetName (),
247+ provider.GetSummaryKindName ()));
248+ return it.first ->second ;
249+ }
250+
251+ llvm::json::Value ToJSON ();
252+
253+ private:
254+ llvm::StringMap<SummaryStatisticsSP> m_summary_stats_map;
255+ std::mutex m_map_mutex;
256+ };
257+
178258// / A class that represents statistics for a since lldb_private::Target.
179259class TargetStats {
180260public:
0 commit comments