瀏覽代碼

Merge topic 'extended-profiling'

0fe7aae91f cmake: Add profiling events for configure and generate
3d6a8d7eac cmMakefileProfilingData: Refactor to use RAII

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !7828
Brad King 3 年之前
父節點
當前提交
3469d53b3f
共有 5 個文件被更改,包括 106 次插入21 次删除
  1. 6 7
      Source/cmMakefile.cxx
  2. 49 11
      Source/cmMakefileProfilingData.cxx
  3. 30 0
      Source/cmMakefileProfilingData.h
  4. 9 0
      Source/cmake.cxx
  5. 12 3
      Source/cmake.h

+ 6 - 7
Source/cmMakefile.cxx

@@ -375,19 +375,15 @@ public:
     ++this->Makefile->RecursionDepth;
     this->Makefile->ExecutionStatusStack.push_back(&status);
 #if !defined(CMAKE_BOOTSTRAP)
-    if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
-      this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
-                                                                          lfc);
-    }
+    this->ProfilingDataRAII =
+      this->Makefile->GetCMakeInstance()->CreateProfilingEntry(lff, lfc);
 #endif
   }
 
   ~cmMakefileCall()
   {
 #if !defined(CMAKE_BOOTSTRAP)
-    if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
-      this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
-    }
+    this->ProfilingDataRAII.reset();
 #endif
     this->Makefile->ExecutionStatusStack.pop_back();
     --this->Makefile->RecursionDepth;
@@ -399,6 +395,9 @@ public:
 
 private:
   cmMakefile* Makefile;
+#if !defined(CMAKE_BOOTSTRAP)
+  cm::optional<cmMakefileProfilingData::RAII> ProfilingDataRAII;
+#endif
 };
 
 void cmMakefile::OnExecuteCommand(std::function<void()> callback)

+ 49 - 11
Source/cmMakefileProfilingData.cxx

@@ -4,8 +4,12 @@
 
 #include <chrono>
 #include <stdexcept>
+#include <type_traits>
+#include <utility>
 #include <vector>
 
+#include <cm/utility>
+
 #include <cm3p/json/value.h>
 #include <cm3p/json/writer.h>
 
@@ -45,6 +49,23 @@ cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
 
 void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
                                          cmListFileContext const& lfc)
+{
+  cm::optional<Json::Value> argsValue(cm::in_place, Json::objectValue);
+  if (!lff.Arguments().empty()) {
+    std::string args;
+    for (auto const& a : lff.Arguments()) {
+      args = cmStrCat(args, args.empty() ? "" : " ", a.Value);
+    }
+    (*argsValue)["functionArgs"] = args;
+  }
+  (*argsValue)["location"] =
+    cmStrCat(lfc.FilePath, ':', std::to_string(lfc.Line));
+  this->StartEntry("script", lff.LowerCaseName(), std::move(argsValue));
+}
+
+void cmMakefileProfilingData::StartEntry(const std::string& category,
+                                         const std::string& name,
+                                         cm::optional<Json::Value> args)
 {
   /* Do not try again if we previously failed to write to output. */
   if (!this->ProfileStream.good()) {
@@ -58,24 +79,17 @@ void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
     cmsys::SystemInformation info;
     Json::Value v;
     v["ph"] = "B";
-    v["name"] = lff.LowerCaseName();
-    v["cat"] = "cmake";
+    v["name"] = name;
+    v["cat"] = category;
     v["ts"] = static_cast<Json::Value::UInt64>(
       std::chrono::duration_cast<std::chrono::microseconds>(
         std::chrono::steady_clock::now().time_since_epoch())
         .count());
     v["pid"] = static_cast<int>(info.GetProcessId());
     v["tid"] = 0;
-    Json::Value argsValue;
-    if (!lff.Arguments().empty()) {
-      std::string args;
-      for (auto const& a : lff.Arguments()) {
-        args += (args.empty() ? "" : " ") + a.Value;
-      }
-      argsValue["functionArgs"] = args;
+    if (args) {
+      v["args"] = *std::move(args);
     }
-    argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
-    v["args"] = argsValue;
 
     this->JsonWriter->write(v, &this->ProfileStream);
   } catch (std::ios_base::failure& fail) {
@@ -112,3 +126,27 @@ void cmMakefileProfilingData::StopEntry()
     cmSystemTools::Error("Error writing profiling output!");
   }
 }
+
+cmMakefileProfilingData::RAII::RAII(RAII&& other) noexcept
+  : Data(other.Data)
+{
+  other.Data = nullptr;
+}
+
+cmMakefileProfilingData::RAII::~RAII()
+{
+  if (this->Data) {
+    this->Data->StopEntry();
+  }
+}
+
+cmMakefileProfilingData::RAII& cmMakefileProfilingData::RAII::operator=(
+  RAII&& other) noexcept
+{
+  if (this->Data) {
+    this->Data->StopEntry();
+  }
+  this->Data = other.Data;
+  other.Data = nullptr;
+  return *this;
+}

+ 30 - 0
Source/cmMakefileProfilingData.h

@@ -3,6 +3,11 @@
 #pragma once
 #include <memory>
 #include <string>
+#include <utility>
+
+#include <cm/optional>
+
+#include <cm3p/json/value.h> // IWYU pragma: keep
 
 #include "cmsys/FStream.hxx"
 
@@ -19,8 +24,33 @@ public:
   cmMakefileProfilingData(const std::string&);
   ~cmMakefileProfilingData() noexcept;
   void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
+  void StartEntry(const std::string& category, const std::string& name,
+                  cm::optional<Json::Value> args = cm::nullopt);
   void StopEntry();
 
+  class RAII
+  {
+  public:
+    RAII() = delete;
+    RAII(const RAII&) = delete;
+    RAII(RAII&&) noexcept;
+
+    template <typename... Args>
+    RAII(cmMakefileProfilingData& data, Args&&... args)
+      : Data(&data)
+    {
+      this->Data->StartEntry(std::forward<Args>(args)...);
+    }
+
+    ~RAII();
+
+    RAII& operator=(const RAII&) = delete;
+    RAII& operator=(RAII&&) noexcept;
+
+  private:
+    cmMakefileProfilingData* Data = nullptr;
+  };
+
 private:
   cmsys::ofstream ProfileStream;
   std::unique_ptr<Json::StreamWriter> JsonWriter;

+ 9 - 0
Source/cmake.cxx

@@ -2070,6 +2070,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
 
 int cmake::Configure()
 {
+#if !defined(CMAKE_BOOTSTRAP)
+  auto profilingRAII = this->CreateProfilingEntry("project", "configure");
+#endif
+
   DiagLevel diagLevel;
 
   if (this->DiagLevels.count("deprecated") == 1) {
@@ -2582,6 +2586,11 @@ int cmake::Generate()
   if (!this->GlobalGenerator) {
     return -1;
   }
+
+#if !defined(CMAKE_BOOTSTRAP)
+  auto profilingRAII = this->CreateProfilingEntry("project", "generate");
+#endif
+
   if (!this->GlobalGenerator->Compute()) {
     return -1;
   }

+ 12 - 3
Source/cmake.h

@@ -33,6 +33,7 @@
 #  include <cm3p/json/value.h>
 
 #  include "cmCMakePresetsGraph.h"
+#  include "cmMakefileProfilingData.h"
 #endif
 
 class cmExternalMakefileProjectGeneratorFactory;
@@ -41,9 +42,6 @@ class cmFileTimeCache;
 class cmGlobalGenerator;
 class cmGlobalGeneratorFactory;
 class cmMakefile;
-#if !defined(CMAKE_BOOTSTRAP)
-class cmMakefileProfilingData;
-#endif
 class cmMessenger;
 class cmVariableWatch;
 struct cmBuildOptions;
@@ -639,6 +637,17 @@ public:
 #if !defined(CMAKE_BOOTSTRAP)
   cmMakefileProfilingData& GetProfilingOutput();
   bool IsProfilingEnabled() const;
+
+  template <typename... Args>
+  cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
+    Args&&... args)
+  {
+    if (this->IsProfilingEnabled()) {
+      return cm::make_optional<cmMakefileProfilingData::RAII>(
+        this->GetProfilingOutput(), std::forward<Args>(args)...);
+    }
+    return cm::nullopt;
+  }
 #endif
 
 protected: