Coverage Report

Created: 2022-01-25 06:29

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/Statistics.h
Line
Count
Source
1
//===-- Statistics.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_TARGET_STATISTICS_H
10
#define LLDB_TARGET_STATISTICS_H
11
12
#include "lldb/Utility/ConstString.h"
13
#include "lldb/Utility/Stream.h"
14
#include "lldb/lldb-forward.h"
15
#include "llvm/Support/JSON.h"
16
#include <atomic>
17
#include <chrono>
18
#include <ratio>
19
#include <string>
20
#include <vector>
21
22
namespace lldb_private {
23
24
using StatsClock = std::chrono::high_resolution_clock;
25
using StatsTimepoint = std::chrono::time_point<StatsClock>;
26
27
class StatsDuration {
28
public:
29
  using Duration = std::chrono::duration<double>;
30
31
1.11k
  Duration get() const {
32
1.11k
    return Duration(InternalDuration(value.load(std::memory_order_relaxed)));
33
1.11k
  }
34
81
  operator Duration() const { return get(); }
35
36
354k
  StatsDuration &operator+=(Duration dur) {
37
354k
    value.fetch_add(std::chrono::duration_cast<InternalDuration>(dur).count(),
38
354k
                    std::memory_order_relaxed);
39
354k
    return *this;
40
354k
  }
41
42
private:
43
  using InternalDuration = std::chrono::duration<uint64_t, std::micro>;
44
  std::atomic<uint64_t> value{0};
45
};
46
47
/// A class that measures elapsed time in an exception safe way.
48
///
49
/// This is a RAII class is designed to help gather timing statistics within
50
/// LLDB where objects have optional Duration variables that get updated with
51
/// elapsed times. This helps LLDB measure statistics for many things that are
52
/// then reported in LLDB commands.
53
///
54
/// Objects that need to measure elapsed times should have a variable of type
55
/// "StatsDuration m_time_xxx;" which can then be used in the constructor of
56
/// this class inside a scope that wants to measure something:
57
///
58
///   ElapsedTime elapsed(m_time_xxx);
59
///   // Do some work
60
///
61
/// This class will increment the m_time_xxx variable with the elapsed time
62
/// when the object goes out of scope. The "m_time_xxx" variable will be
63
/// incremented when the class goes out of scope. This allows a variable to
64
/// measure something that might happen in stages at different times, like
65
/// resolving a breakpoint each time a new shared library is loaded.
66
class ElapsedTime {
67
public:
68
  /// Set to the start time when the object is created.
69
  StatsTimepoint m_start_time;
70
  /// Elapsed time in seconds to increment when this object goes out of scope.
71
  StatsDuration &m_elapsed_time;
72
73
public:
74
354k
  ElapsedTime(StatsDuration &opt_time) : m_elapsed_time(opt_time) {
75
354k
    m_start_time = StatsClock::now();
76
354k
  }
77
354k
  ~ElapsedTime() {
78
354k
    StatsClock::duration elapsed = StatsClock::now() - m_start_time;
79
354k
    m_elapsed_time += elapsed;
80
354k
  }
81
};
82
83
/// A class to count success/fail statistics.
84
struct StatsSuccessFail {
85
18.0k
  StatsSuccessFail(llvm::StringRef n) : name(n.str()) {}
86
87
14.4k
  void NotifySuccess() { ++successes; }
88
391
  void NotifyFailure() { ++failures; }
89
90
  llvm::json::Value ToJSON() const;
91
  std::string name;
92
  uint32_t successes = 0;
93
  uint32_t failures = 0;
94
};
95
96
/// A class that represents statistics for a since lldb_private::Module.
97
struct ModuleStats {
98
  llvm::json::Value ToJSON() const;
99
  intptr_t identifier;
100
  std::string path;
101
  std::string uuid;
102
  std::string triple;
103
  double symtab_parse_time = 0.0;
104
  double symtab_index_time = 0.0;
105
  double debug_parse_time = 0.0;
106
  double debug_index_time = 0.0;
107
  uint64_t debug_info_size = 0;
108
  bool symtab_loaded_from_cache = false;
109
  bool symtab_saved_to_cache = false;
110
  bool debug_info_index_loaded_from_cache = false;
111
  bool debug_info_index_saved_to_cache = false;
112
};
113
114
struct ConstStringStats {
115
  llvm::json::Value ToJSON() const;
116
  ConstString::MemoryStats stats = ConstString::GetMemoryStats();
117
};
118
119
/// A class that represents statistics for a since lldb_private::Target.
120
class TargetStats {
121
public:
122
  llvm::json::Value ToJSON(Target &target);
123
124
  void SetLaunchOrAttachTime();
125
  void SetFirstPrivateStopTime();
126
  void SetFirstPublicStopTime();
127
128
2.88k
  StatsDuration &GetCreateTime() { return m_create_time; }
129
9.26k
  StatsSuccessFail &GetExpressionStats() { return m_expr_eval; }
130
5.58k
  StatsSuccessFail &GetFrameVariableStats() { return m_frame_var; }
131
132
protected:
133
  StatsDuration m_create_time;
134
  llvm::Optional<StatsTimepoint> m_launch_or_attach_time;
135
  llvm::Optional<StatsTimepoint> m_first_private_stop_time;
136
  llvm::Optional<StatsTimepoint> m_first_public_stop_time;
137
  StatsSuccessFail m_expr_eval{"expressionEvaluation"};
138
  StatsSuccessFail m_frame_var{"frameVariable"};
139
  std::vector<intptr_t> m_module_identifiers;
140
  void CollectStats(Target &target);
141
};
142
143
class DebuggerStats {
144
public:
145
5
  static void SetCollectingStats(bool enable) { g_collecting_stats = enable; }
146
9
  static bool GetCollectingStats() { return g_collecting_stats; }
147
148
  /// Get metrics associated with one or all targets in a debugger in JSON
149
  /// format.
150
  ///
151
  /// \param debugger
152
  ///   The debugger to get the target list from if \a target is NULL.
153
  ///
154
  /// \param target
155
  ///   The single target to emit statistics for if non NULL, otherwise dump
156
  ///   statistics only for the specified target.
157
  ///
158
  /// \return
159
  ///     Returns a JSON value that contains all target metrics.
160
  static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target);
161
162
protected:
163
  // Collecting stats can be set to true to collect stats that are expensive
164
  // to collect. By default all stats that are cheap to collect are enabled.
165
  // This settings is here to maintain compatibility with "statistics enable"
166
  // and "statistics disable".
167
  static bool g_collecting_stats;
168
};
169
170
} // namespace lldb_private
171
172
#endif // LLDB_TARGET_STATISTICS_H