1 //===-- Statistics.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 #include "lldb/Target/Statistics.h"
10 
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Symbol/SymbolFile.h"
14 #include "lldb/Target/Target.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 using namespace llvm;
19 
20 json::Value StatsSuccessFail::ToJSON() const {
21   return json::Object{{"successes", successes}, {"failures", failures}};
22 }
23 
24 static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end) {
25   StatsDuration elapsed = end.time_since_epoch() - start.time_since_epoch();
26   return elapsed.count();
27 }
28 
29 json::Value TargetStats::ToJSON() {
30   json::Object target_metrics_json{{m_expr_eval.name, m_expr_eval.ToJSON()},
31                                    {m_frame_var.name, m_frame_var.ToJSON()}};
32   if (m_launch_or_attach_time && m_first_private_stop_time) {
33     double elapsed_time =
34         elapsed(*m_launch_or_attach_time, *m_first_private_stop_time);
35     target_metrics_json.try_emplace("launchOrAttachTime", elapsed_time);
36   }
37   if (m_launch_or_attach_time && m_first_public_stop_time) {
38     double elapsed_time =
39         elapsed(*m_launch_or_attach_time, *m_first_public_stop_time);
40     target_metrics_json.try_emplace("firstStopTime", elapsed_time);
41   }
42   target_metrics_json.try_emplace("targetCreateTime", m_create_time.count());
43 
44   return target_metrics_json;
45 }
46 
47 void TargetStats::SetLaunchOrAttachTime() {
48   m_launch_or_attach_time = StatsClock::now();
49   m_first_private_stop_time = llvm::None;
50 }
51 
52 void TargetStats::SetFirstPrivateStopTime() {
53   // Launching and attaching has many paths depending on if synchronous mode
54   // was used or if we are stopping at the entry point or not. Only set the
55   // first stop time if it hasn't already been set.
56   if (!m_first_private_stop_time)
57     m_first_private_stop_time = StatsClock::now();
58 }
59 
60 void TargetStats::SetFirstPublicStopTime() {
61   // Launching and attaching has many paths depending on if synchronous mode
62   // was used or if we are stopping at the entry point or not. Only set the
63   // first stop time if it hasn't already been set.
64   if (!m_first_public_stop_time)
65     m_first_public_stop_time = StatsClock::now();
66 }
67 
68 bool DebuggerStats::g_collecting_stats = false;
69 
70 llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger) {
71   json::Array targets;
72   for (const auto &target : debugger.GetTargetList().Targets()) {
73     targets.emplace_back(target->ReportStatistics());
74   }
75   json::Object global_stats{
76       {"targets", std::move(targets)},
77   };
78   return std::move(global_stats);
79 }
80