15ffd83dbSDimitry Andric //===-- CommandObjectStats.cpp --------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "CommandObjectStats.h"
10349cc55cSDimitry Andric #include "lldb/Core/Debugger.h"
11349cc55cSDimitry Andric #include "lldb/Host/OptionParser.h"
12fcaf7f86SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
130b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
140b57cec5SDimitry Andric #include "lldb/Target/Target.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric using namespace lldb;
170b57cec5SDimitry Andric using namespace lldb_private;
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric class CommandObjectStatsEnable : public CommandObjectParsed {
200b57cec5SDimitry Andric public:
CommandObjectStatsEnable(CommandInterpreter & interpreter)210b57cec5SDimitry Andric   CommandObjectStatsEnable(CommandInterpreter &interpreter)
220b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "enable",
230b57cec5SDimitry Andric                             "Enable statistics collection", nullptr,
240b57cec5SDimitry Andric                             eCommandProcessMustBePaused) {}
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric   ~CommandObjectStatsEnable() override = default;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)29*c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
30349cc55cSDimitry Andric     if (DebuggerStats::GetCollectingStats()) {
310b57cec5SDimitry Andric       result.AppendError("statistics already enabled");
32*c9157d92SDimitry Andric       return;
330b57cec5SDimitry Andric     }
340b57cec5SDimitry Andric 
35349cc55cSDimitry Andric     DebuggerStats::SetCollectingStats(true);
360b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
370b57cec5SDimitry Andric   }
380b57cec5SDimitry Andric };
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric class CommandObjectStatsDisable : public CommandObjectParsed {
410b57cec5SDimitry Andric public:
CommandObjectStatsDisable(CommandInterpreter & interpreter)420b57cec5SDimitry Andric   CommandObjectStatsDisable(CommandInterpreter &interpreter)
430b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "disable",
440b57cec5SDimitry Andric                             "Disable statistics collection", nullptr,
450b57cec5SDimitry Andric                             eCommandProcessMustBePaused) {}
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric   ~CommandObjectStatsDisable() override = default;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)50*c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
51349cc55cSDimitry Andric     if (!DebuggerStats::GetCollectingStats()) {
520b57cec5SDimitry Andric       result.AppendError("need to enable statistics before disabling them");
53*c9157d92SDimitry Andric       return;
540b57cec5SDimitry Andric     }
550b57cec5SDimitry Andric 
56349cc55cSDimitry Andric     DebuggerStats::SetCollectingStats(false);
570b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
580b57cec5SDimitry Andric   }
590b57cec5SDimitry Andric };
600b57cec5SDimitry Andric 
61349cc55cSDimitry Andric #define LLDB_OPTIONS_statistics_dump
62349cc55cSDimitry Andric #include "CommandOptions.inc"
63349cc55cSDimitry Andric 
640b57cec5SDimitry Andric class CommandObjectStatsDump : public CommandObjectParsed {
65349cc55cSDimitry Andric   class CommandOptions : public Options {
66349cc55cSDimitry Andric   public:
CommandOptions()6704eeddc0SDimitry Andric     CommandOptions() { OptionParsingStarting(nullptr); }
68349cc55cSDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)69349cc55cSDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
70349cc55cSDimitry Andric                           ExecutionContext *execution_context) override {
71349cc55cSDimitry Andric       Status error;
72349cc55cSDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
73349cc55cSDimitry Andric 
74349cc55cSDimitry Andric       switch (short_option) {
75349cc55cSDimitry Andric       case 'a':
76349cc55cSDimitry Andric         m_all_targets = true;
77349cc55cSDimitry Andric         break;
78349cc55cSDimitry Andric       default:
79349cc55cSDimitry Andric         llvm_unreachable("Unimplemented option");
80349cc55cSDimitry Andric       }
81349cc55cSDimitry Andric       return error;
82349cc55cSDimitry Andric     }
83349cc55cSDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)84349cc55cSDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
85349cc55cSDimitry Andric       m_all_targets = false;
86349cc55cSDimitry Andric     }
87349cc55cSDimitry Andric 
GetDefinitions()88349cc55cSDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
89bdd1243dSDimitry Andric       return llvm::ArrayRef(g_statistics_dump_options);
90349cc55cSDimitry Andric     }
91349cc55cSDimitry Andric 
92349cc55cSDimitry Andric     bool m_all_targets = false;
93349cc55cSDimitry Andric   };
94349cc55cSDimitry Andric 
950b57cec5SDimitry Andric public:
CommandObjectStatsDump(CommandInterpreter & interpreter)960b57cec5SDimitry Andric   CommandObjectStatsDump(CommandInterpreter &interpreter)
97349cc55cSDimitry Andric       : CommandObjectParsed(
98349cc55cSDimitry Andric             interpreter, "statistics dump", "Dump metrics in JSON format",
99349cc55cSDimitry Andric             "statistics dump [<options>]", eCommandRequiresTarget) {}
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   ~CommandObjectStatsDump() override = default;
1020b57cec5SDimitry Andric 
GetOptions()103349cc55cSDimitry Andric   Options *GetOptions() override { return &m_options; }
104349cc55cSDimitry Andric 
1050b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)106*c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
107349cc55cSDimitry Andric     Target *target = nullptr;
108349cc55cSDimitry Andric     if (!m_options.m_all_targets)
109349cc55cSDimitry Andric       target = m_exe_ctx.GetTargetPtr();
1100b57cec5SDimitry Andric 
111349cc55cSDimitry Andric     result.AppendMessageWithFormatv(
112349cc55cSDimitry Andric         "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target));
1130b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
1140b57cec5SDimitry Andric   }
115349cc55cSDimitry Andric 
116349cc55cSDimitry Andric   CommandOptions m_options;
1170b57cec5SDimitry Andric };
1180b57cec5SDimitry Andric 
CommandObjectStats(CommandInterpreter & interpreter)1190b57cec5SDimitry Andric CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
1200b57cec5SDimitry Andric     : CommandObjectMultiword(interpreter, "statistics",
1210b57cec5SDimitry Andric                              "Print statistics about a debugging session",
1220b57cec5SDimitry Andric                              "statistics <subcommand> [<subcommand-options>]") {
1230b57cec5SDimitry Andric   LoadSubCommand("enable",
1240b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
1250b57cec5SDimitry Andric   LoadSubCommand("disable",
1260b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
1270b57cec5SDimitry Andric   LoadSubCommand("dump",
1280b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectStatsDump(interpreter)));
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric CommandObjectStats::~CommandObjectStats() = default;
132