|
|
@@ -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;
|
|
|
+}
|