File indexing completed on 2026-05-10 08:42:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_TARGET_STATISTICS_H
0010 #define LLDB_TARGET_STATISTICS_H
0011
0012 #include "lldb/DataFormatters/TypeSummary.h"
0013 #include "lldb/Utility/ConstString.h"
0014 #include "lldb/Utility/RealpathPrefixes.h"
0015 #include "lldb/Utility/Stream.h"
0016 #include "lldb/lldb-forward.h"
0017 #include "llvm/ADT/StringMap.h"
0018 #include "llvm/Support/JSON.h"
0019 #include <atomic>
0020 #include <chrono>
0021 #include <mutex>
0022 #include <optional>
0023 #include <ratio>
0024 #include <string>
0025 #include <vector>
0026
0027 namespace lldb_private {
0028
0029 using StatsClock = std::chrono::high_resolution_clock;
0030 using StatsTimepoint = std::chrono::time_point<StatsClock>;
0031 class SummaryStatistics;
0032
0033 typedef std::shared_ptr<SummaryStatistics> SummaryStatisticsSP;
0034
0035 class StatsDuration {
0036 public:
0037 using Duration = std::chrono::duration<double>;
0038
0039 Duration get() const {
0040 return Duration(InternalDuration(value.load(std::memory_order_relaxed)));
0041 }
0042 operator Duration() const { return get(); }
0043
0044 void reset() { value.store(0, std::memory_order_relaxed); }
0045
0046 StatsDuration &operator+=(Duration dur) {
0047 value.fetch_add(std::chrono::duration_cast<InternalDuration>(dur).count(),
0048 std::memory_order_relaxed);
0049 return *this;
0050 }
0051
0052 private:
0053 using InternalDuration = std::chrono::duration<uint64_t, std::micro>;
0054 std::atomic<uint64_t> value{0};
0055 };
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 class ElapsedTime {
0077 public:
0078
0079 StatsTimepoint m_start_time;
0080
0081 StatsDuration &m_elapsed_time;
0082
0083 public:
0084 ElapsedTime(StatsDuration &opt_time) : m_elapsed_time(opt_time) {
0085 m_start_time = StatsClock::now();
0086 }
0087 ~ElapsedTime() {
0088 StatsClock::duration elapsed = StatsClock::now() - m_start_time;
0089 m_elapsed_time += elapsed;
0090 }
0091 };
0092
0093
0094 struct StatsSuccessFail {
0095 StatsSuccessFail(llvm::StringRef n) : name(n.str()) {}
0096
0097 void NotifySuccess() { ++successes; }
0098 void NotifyFailure() { ++failures; }
0099
0100 llvm::json::Value ToJSON() const;
0101 std::string name;
0102 uint32_t successes = 0;
0103 uint32_t failures = 0;
0104 };
0105
0106
0107 struct ModuleStats {
0108 llvm::json::Value ToJSON() const;
0109 intptr_t identifier;
0110 std::string path;
0111 std::string uuid;
0112 std::string triple;
0113
0114 std::string symfile_path;
0115
0116
0117
0118
0119 std::vector<intptr_t> symfile_modules;
0120 llvm::StringMap<llvm::json::Value> type_system_stats;
0121 double symtab_parse_time = 0.0;
0122 double symtab_index_time = 0.0;
0123 double debug_parse_time = 0.0;
0124 double debug_index_time = 0.0;
0125 uint64_t debug_info_size = 0;
0126 bool symtab_loaded_from_cache = false;
0127 bool symtab_saved_to_cache = false;
0128 bool debug_info_index_loaded_from_cache = false;
0129 bool debug_info_index_saved_to_cache = false;
0130 bool debug_info_enabled = true;
0131 bool symtab_stripped = false;
0132 bool debug_info_had_variable_errors = false;
0133 bool debug_info_had_incomplete_types = false;
0134 };
0135
0136 struct ConstStringStats {
0137 llvm::json::Value ToJSON() const;
0138 ConstString::MemoryStats stats = ConstString::GetMemoryStats();
0139 };
0140
0141 struct StatisticsOptions {
0142 public:
0143 void SetSummaryOnly(bool value) { m_summary_only = value; }
0144 bool GetSummaryOnly() const { return m_summary_only.value_or(false); }
0145
0146 void SetLoadAllDebugInfo(bool value) { m_load_all_debug_info = value; }
0147 bool GetLoadAllDebugInfo() const {
0148 return m_load_all_debug_info.value_or(false);
0149 }
0150
0151 void SetIncludeTargets(bool value) { m_include_targets = value; }
0152 bool GetIncludeTargets() const {
0153 if (m_include_targets.has_value())
0154 return m_include_targets.value();
0155
0156 return true;
0157 }
0158
0159 void SetIncludeModules(bool value) { m_include_modules = value; }
0160 bool GetIncludeModules() const {
0161 if (m_include_modules.has_value())
0162 return m_include_modules.value();
0163
0164
0165 return !GetSummaryOnly();
0166 }
0167
0168 void SetIncludeTranscript(bool value) { m_include_transcript = value; }
0169 bool GetIncludeTranscript() const {
0170 if (m_include_transcript.has_value())
0171 return m_include_transcript.value();
0172
0173
0174 return !GetSummaryOnly();
0175 }
0176
0177 private:
0178 std::optional<bool> m_summary_only;
0179 std::optional<bool> m_load_all_debug_info;
0180 std::optional<bool> m_include_targets;
0181 std::optional<bool> m_include_modules;
0182 std::optional<bool> m_include_transcript;
0183 };
0184
0185
0186
0187 class SummaryStatistics {
0188 public:
0189 explicit SummaryStatistics(std::string name, std::string impl_type)
0190 : m_total_time(), m_impl_type(std::move(impl_type)),
0191 m_name(std::move(name)), m_count(0) {}
0192
0193 std::string GetName() const { return m_name; };
0194 double GetTotalTime() const { return m_total_time.get().count(); }
0195
0196 uint64_t GetSummaryCount() const {
0197 return m_count.load(std::memory_order_relaxed);
0198 }
0199
0200 StatsDuration &GetDurationReference() { return m_total_time; };
0201
0202 std::string GetSummaryKindName() const { return m_impl_type; }
0203
0204 llvm::json::Value ToJSON() const;
0205
0206 void Reset() { m_total_time.reset(); }
0207
0208
0209 class SummaryInvocation {
0210 public:
0211 SummaryInvocation(SummaryStatisticsSP summary_stats)
0212 : m_stats(summary_stats),
0213 m_elapsed_time(summary_stats->GetDurationReference()) {}
0214 ~SummaryInvocation() { m_stats->OnInvoked(); }
0215
0216
0217
0218
0219 SummaryInvocation(const SummaryInvocation &) = delete;
0220 SummaryInvocation &operator=(const SummaryInvocation &) = delete;
0221
0222
0223 private:
0224 SummaryStatisticsSP m_stats;
0225 ElapsedTime m_elapsed_time;
0226 };
0227
0228 private:
0229 void OnInvoked() noexcept { m_count.fetch_add(1, std::memory_order_relaxed); }
0230 lldb_private::StatsDuration m_total_time;
0231 const std::string m_impl_type;
0232 const std::string m_name;
0233 std::atomic<uint64_t> m_count;
0234 };
0235
0236
0237 class SummaryStatisticsCache {
0238 public:
0239
0240
0241 SummaryStatisticsSP
0242 GetSummaryStatisticsForProvider(lldb_private::TypeSummaryImpl &provider) {
0243 std::lock_guard<std::mutex> guard(m_map_mutex);
0244 if (auto iterator = m_summary_stats_map.find(provider.GetName());
0245 iterator != m_summary_stats_map.end())
0246 return iterator->second;
0247
0248 auto it = m_summary_stats_map.try_emplace(
0249 provider.GetName(),
0250 std::make_shared<SummaryStatistics>(provider.GetName(),
0251 provider.GetSummaryKindName()));
0252 return it.first->second;
0253 }
0254
0255 llvm::json::Value ToJSON();
0256
0257 void Reset();
0258
0259 private:
0260 llvm::StringMap<SummaryStatisticsSP> m_summary_stats_map;
0261 std::mutex m_map_mutex;
0262 };
0263
0264
0265 class TargetStats {
0266 public:
0267 llvm::json::Value ToJSON(Target &target,
0268 const lldb_private::StatisticsOptions &options);
0269
0270 void SetLaunchOrAttachTime();
0271 void SetFirstPrivateStopTime();
0272 void SetFirstPublicStopTime();
0273 void IncreaseSourceMapDeduceCount();
0274 void IncreaseSourceRealpathAttemptCount(uint32_t count);
0275 void IncreaseSourceRealpathCompatibleCount(uint32_t count);
0276
0277 StatsDuration &GetCreateTime() { return m_create_time; }
0278 StatsSuccessFail &GetExpressionStats() { return m_expr_eval; }
0279 StatsSuccessFail &GetFrameVariableStats() { return m_frame_var; }
0280 void Reset(Target &target);
0281
0282 protected:
0283 StatsDuration m_create_time;
0284 std::optional<StatsTimepoint> m_launch_or_attach_time;
0285 std::optional<StatsTimepoint> m_first_private_stop_time;
0286 std::optional<StatsTimepoint> m_first_public_stop_time;
0287 StatsSuccessFail m_expr_eval{"expressionEvaluation"};
0288 StatsSuccessFail m_frame_var{"frameVariable"};
0289 std::vector<intptr_t> m_module_identifiers;
0290 uint32_t m_source_map_deduce_count = 0;
0291 uint32_t m_source_realpath_attempt_count = 0;
0292 uint32_t m_source_realpath_compatible_count = 0;
0293 void CollectStats(Target &target);
0294 };
0295
0296 class DebuggerStats {
0297 public:
0298 static void SetCollectingStats(bool enable) { g_collecting_stats = enable; }
0299 static bool GetCollectingStats() { return g_collecting_stats; }
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 static llvm::json::Value
0318 ReportStatistics(Debugger &debugger, Target *target,
0319 const lldb_private::StatisticsOptions &options);
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 static void ResetStatistics(Debugger &debugger, Target *target);
0330
0331 protected:
0332
0333
0334
0335
0336 static bool g_collecting_stats;
0337 };
0338
0339 }
0340
0341 #endif