180814287SRaphael Isemann //===-- CommandObjectStats.cpp --------------------------------------------===//
210166c74SDavide Italiano //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
610166c74SDavide Italiano //
710166c74SDavide Italiano //===----------------------------------------------------------------------===//
810166c74SDavide Italiano 
910166c74SDavide Italiano #include "CommandObjectStats.h"
10*d7b33853SGreg Clayton #include "lldb/Core/Debugger.h"
11*d7b33853SGreg Clayton #include "lldb/Host/OptionParser.h"
1210166c74SDavide Italiano #include "lldb/Interpreter/CommandReturnObject.h"
1324fff242SDavide Italiano #include "lldb/Target/Target.h"
1410166c74SDavide Italiano 
1510166c74SDavide Italiano using namespace lldb;
1610166c74SDavide Italiano using namespace lldb_private;
1710166c74SDavide Italiano 
1824fff242SDavide Italiano class CommandObjectStatsEnable : public CommandObjectParsed {
1924fff242SDavide Italiano public:
2024fff242SDavide Italiano   CommandObjectStatsEnable(CommandInterpreter &interpreter)
2124fff242SDavide Italiano       : CommandObjectParsed(interpreter, "enable",
2224fff242SDavide Italiano                             "Enable statistics collection", nullptr,
2324fff242SDavide Italiano                             eCommandProcessMustBePaused) {}
2424fff242SDavide Italiano 
2524fff242SDavide Italiano   ~CommandObjectStatsEnable() override = default;
2624fff242SDavide Italiano 
2724fff242SDavide Italiano protected:
2824fff242SDavide Italiano   bool DoExecute(Args &command, CommandReturnObject &result) override {
29*d7b33853SGreg Clayton     if (DebuggerStats::GetCollectingStats()) {
3024fff242SDavide Italiano       result.AppendError("statistics already enabled");
3124fff242SDavide Italiano       return false;
3210166c74SDavide Italiano     }
3310166c74SDavide Italiano 
34*d7b33853SGreg Clayton     DebuggerStats::SetCollectingStats(true);
3524fff242SDavide Italiano     result.SetStatus(eReturnStatusSuccessFinishResult);
3610166c74SDavide Italiano     return true;
3710166c74SDavide Italiano   }
3824fff242SDavide Italiano };
3910166c74SDavide Italiano 
4024fff242SDavide Italiano class CommandObjectStatsDisable : public CommandObjectParsed {
4124fff242SDavide Italiano public:
4224fff242SDavide Italiano   CommandObjectStatsDisable(CommandInterpreter &interpreter)
4324fff242SDavide Italiano       : CommandObjectParsed(interpreter, "disable",
4424fff242SDavide Italiano                             "Disable statistics collection", nullptr,
4524fff242SDavide Italiano                             eCommandProcessMustBePaused) {}
4624fff242SDavide Italiano 
4724fff242SDavide Italiano   ~CommandObjectStatsDisable() override = default;
4824fff242SDavide Italiano 
4924fff242SDavide Italiano protected:
5024fff242SDavide Italiano   bool DoExecute(Args &command, CommandReturnObject &result) override {
51*d7b33853SGreg Clayton     if (!DebuggerStats::GetCollectingStats()) {
5224fff242SDavide Italiano       result.AppendError("need to enable statistics before disabling them");
5324fff242SDavide Italiano       return false;
5424fff242SDavide Italiano     }
5524fff242SDavide Italiano 
56*d7b33853SGreg Clayton     DebuggerStats::SetCollectingStats(false);
5724fff242SDavide Italiano     result.SetStatus(eReturnStatusSuccessFinishResult);
5824fff242SDavide Italiano     return true;
5924fff242SDavide Italiano   }
6024fff242SDavide Italiano };
6124fff242SDavide Italiano 
62*d7b33853SGreg Clayton #define LLDB_OPTIONS_statistics_dump
63*d7b33853SGreg Clayton #include "CommandOptions.inc"
64*d7b33853SGreg Clayton 
6524fff242SDavide Italiano class CommandObjectStatsDump : public CommandObjectParsed {
66*d7b33853SGreg Clayton   class CommandOptions : public Options {
67*d7b33853SGreg Clayton   public:
68*d7b33853SGreg Clayton     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
69*d7b33853SGreg Clayton 
70*d7b33853SGreg Clayton     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
71*d7b33853SGreg Clayton                           ExecutionContext *execution_context) override {
72*d7b33853SGreg Clayton       Status error;
73*d7b33853SGreg Clayton       const int short_option = m_getopt_table[option_idx].val;
74*d7b33853SGreg Clayton 
75*d7b33853SGreg Clayton       switch (short_option) {
76*d7b33853SGreg Clayton       case 'a':
77*d7b33853SGreg Clayton         m_all_targets = true;
78*d7b33853SGreg Clayton         break;
79*d7b33853SGreg Clayton       default:
80*d7b33853SGreg Clayton         llvm_unreachable("Unimplemented option");
81*d7b33853SGreg Clayton       }
82*d7b33853SGreg Clayton       return error;
83*d7b33853SGreg Clayton     }
84*d7b33853SGreg Clayton 
85*d7b33853SGreg Clayton     void OptionParsingStarting(ExecutionContext *execution_context) override {
86*d7b33853SGreg Clayton       m_all_targets = false;
87*d7b33853SGreg Clayton     }
88*d7b33853SGreg Clayton 
89*d7b33853SGreg Clayton     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
90*d7b33853SGreg Clayton       return llvm::makeArrayRef(g_statistics_dump_options);
91*d7b33853SGreg Clayton     }
92*d7b33853SGreg Clayton 
93*d7b33853SGreg Clayton     bool m_all_targets = false;
94*d7b33853SGreg Clayton   };
95*d7b33853SGreg Clayton 
9624fff242SDavide Italiano public:
9724fff242SDavide Italiano   CommandObjectStatsDump(CommandInterpreter &interpreter)
98*d7b33853SGreg Clayton       : CommandObjectParsed(
99*d7b33853SGreg Clayton             interpreter, "statistics dump", "Dump metrics in JSON format",
100*d7b33853SGreg Clayton             "statistics dump [<options>]", eCommandRequiresTarget) {}
10124fff242SDavide Italiano 
10224fff242SDavide Italiano   ~CommandObjectStatsDump() override = default;
10324fff242SDavide Italiano 
104*d7b33853SGreg Clayton   Options *GetOptions() override { return &m_options; }
105*d7b33853SGreg Clayton 
10624fff242SDavide Italiano protected:
10724fff242SDavide Italiano   bool DoExecute(Args &command, CommandReturnObject &result) override {
108*d7b33853SGreg Clayton     if (m_options.m_all_targets) {
109*d7b33853SGreg Clayton       result.AppendMessageWithFormatv(
110*d7b33853SGreg Clayton           "{0:2}", DebuggerStats::ReportStatistics(GetDebugger()));
111*d7b33853SGreg Clayton     } else {
112*d7b33853SGreg Clayton       Target &target = m_exe_ctx.GetTargetRef();
113*d7b33853SGreg Clayton       result.AppendMessageWithFormatv("{0:2}", target.ReportStatistics());
11424fff242SDavide Italiano     }
11524fff242SDavide Italiano     result.SetStatus(eReturnStatusSuccessFinishResult);
11624fff242SDavide Italiano     return true;
11724fff242SDavide Italiano   }
118*d7b33853SGreg Clayton 
119*d7b33853SGreg Clayton   CommandOptions m_options;
12024fff242SDavide Italiano };
12124fff242SDavide Italiano 
12224fff242SDavide Italiano CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
12324fff242SDavide Italiano     : CommandObjectMultiword(interpreter, "statistics",
12424fff242SDavide Italiano                              "Print statistics about a debugging session",
12524fff242SDavide Italiano                              "statistics <subcommand> [<subcommand-options>]") {
12624fff242SDavide Italiano   LoadSubCommand("enable",
12724fff242SDavide Italiano                  CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
12824fff242SDavide Italiano   LoadSubCommand("disable",
12924fff242SDavide Italiano                  CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
13024fff242SDavide Italiano   LoadSubCommand("dump",
13124fff242SDavide Italiano                  CommandObjectSP(new CommandObjectStatsDump(interpreter)));
13224fff242SDavide Italiano }
13324fff242SDavide Italiano 
13424fff242SDavide Italiano CommandObjectStats::~CommandObjectStats() = default;
135