Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmljscompilerstats.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include <QFile>
7#include <QJsonArray>
8#include <QJsonDocument>
9#include <QJsonObject>
10#include <QTextStream>
11
13
14namespace QQmlJS {
15
16using namespace Qt::StringLiterals;
17
18std::unique_ptr<AotStats> QQmlJSAotCompilerStats::s_instance = std::make_unique<AotStats>();
19QString QQmlJSAotCompilerStats::s_moduleId;
20bool QQmlJSAotCompilerStats::s_recordAotStats = false;
21
23{
24 if (line == other.line)
25 return column < other.column;
26 return line < other.line;
27}
28
30{
31 for (const auto &[moduleUri, moduleStats] : other.m_entries.asKeyValueRange()) {
32 m_entries[moduleUri].insert(moduleStats);
33 }
34}
35
36std::optional<QList<QString>> extractAotstatsFilesList(const QString &aotstatsListPath)
37{
38 QFile aotstatsListFile(aotstatsListPath);
39 if (!aotstatsListFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
40 qDebug().noquote() << u"Could not open \"%1\" for reading"_s.arg(aotstatsListFile.fileName());
41 return std::nullopt;
42 }
43
44 QStringList aotstatsFiles;
45 QTextStream stream(&aotstatsListFile);
46 while (!stream.atEnd())
47 aotstatsFiles.append(stream.readLine());
48
49 return aotstatsFiles;
50}
51
52std::optional<AotStats> AotStats::parseAotstatsFile(const QString &aotstatsPath)
53{
54 QFile file(aotstatsPath);
56 qDebug().noquote() << u"Could not open \"%1\""_s.arg(aotstatsPath);
57 return std::nullopt;
58 }
59
61}
62
63std::optional<AotStats> AotStats::aggregateAotstatsList(const QString &aotstatsListPath)
64{
65 const auto aotstatsFiles = extractAotstatsFilesList(aotstatsListPath);
66 if (!aotstatsFiles.has_value())
67 return std::nullopt;
68
69 AotStats aggregated;
70 if (aotstatsFiles->empty())
71 return aggregated;
72
73 for (const auto &aotstatsFile : aotstatsFiles.value()) {
74 auto parsed = parseAotstatsFile(aotstatsFile);
75 if (!parsed.has_value())
76 return std::nullopt;
77 aggregated.insert(parsed.value());
78 }
79
80 return aggregated;
81}
82
84{
85 QJsonArray modulesArray = document.array();
86
88 for (const auto &modulesArrayEntry : modulesArray) {
89 const auto &moduleObject = modulesArrayEntry.toObject();
90 QString moduleId = moduleObject[u"moduleId"_s].toString();
91 const QJsonArray &filesArray = moduleObject[u"moduleFiles"_s].toArray();
92
93 QHash<QString, QList<AotStatsEntry>> files;
94 for (const auto &filesArrayEntry : filesArray) {
95 const QJsonObject &fileObject = filesArrayEntry.toObject();
96 QString filepath = fileObject[u"filepath"_s].toString();
97 const QJsonArray &statsArray = fileObject[u"entries"_s].toArray();
98
99 QList<AotStatsEntry> stats;
100 for (const auto &statsArrayEntry : statsArray) {
101 const auto &statsObject = statsArrayEntry.toObject();
103 auto micros = statsObject[u"durationMicroseconds"_s].toInteger();
104 stat.codegenDuration = std::chrono::microseconds(micros);
105 stat.functionName = statsObject[u"functionName"_s].toString();
106 stat.errorMessage = statsObject[u"errorMessage"_s].toString();
107 stat.line = statsObject[u"line"_s].toInt();
108 stat.column = statsObject[u"column"_s].toInt();
109 stat.codegenSuccessful = statsObject[u"codegenSuccessfull"_s].toBool();
110 stats.append(std::move(stat));
111 }
112
113 std::sort(stats.begin(), stats.end());
114 files[filepath] = std::move(stats);
115 }
116
117 result.m_entries[moduleId] = std::move(files);
118 }
119
120 return result;
121}
122
124{
125 QJsonArray modulesArray;
126 for (auto it1 = m_entries.begin(); it1 != m_entries.end(); ++it1) {
127 const QString moduleId = it1.key();
128 const QHash<QString, QList<AotStatsEntry>> &files = it1.value();
129
130 QJsonArray filesArray;
131 for (auto it2 = files.begin(); it2 != files.end(); ++it2) {
132 const QString &filename = it2.key();
133 const QList<AotStatsEntry> &stats = it2.value();
134
135 QJsonArray statsArray;
136 for (const auto &stat : stats) {
137 QJsonObject statObject;
138 auto micros = static_cast<qint64>(stat.codegenDuration.count());
139 statObject.insert(u"durationMicroseconds", micros);
140 statObject.insert(u"functionName", stat.functionName);
141 statObject.insert(u"errorMessage", stat.errorMessage);
142 statObject.insert(u"line", stat.line);
143 statObject.insert(u"column", stat.column);
144 statObject.insert(u"codegenSuccessfull", stat.codegenSuccessful);
145 statsArray.append(statObject);
146 }
147
149 o.insert(u"filepath"_s, filename);
150 o.insert(u"entries"_s, statsArray);
151 filesArray.append(o);
152 }
153
155 o.insert(u"moduleId"_s, moduleId);
156 o.insert(u"moduleFiles"_s, filesArray);
157 modulesArray.append(o);
158 }
159
160 return QJsonDocument(modulesArray);
161}
162
164 const QString &moduleId, const QString &filepath, const AotStatsEntry &entry)
165{
166 m_entries[moduleId][filepath].append(entry);
167}
168
169bool AotStats::saveToDisk(const QString &filepath) const
170{
171 QFile file(filepath);
173 qDebug().noquote() << u"Could not open \"%1\""_s.arg(filepath);
174 return false;
175 }
176
178 return true;
179}
180
182{
183 QQmlJSAotCompilerStats::instance()->addEntry(s_moduleId, filepath, entry);
184}
185
186} // namespace QQmlJS
187
\inmodule QtCore
Definition qfile.h:93
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:906
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
\inmodule QtCore\reentrant
Definition qjsonarray.h:18
\inmodule QtCore\reentrant
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
Parses json as a UTF-8 encoded JSON document, and creates a QJsonDocument from it.
\inmodule QtCore\reentrant
Definition qjsonobject.h:20
iterator insert(const QString &key, const QJsonValue &value)
Inserts a new item with the key key and a value of value.
bool saveToDisk(const QString &filepath) const
void addEntry(const QString &moduleId, const QString &filepath, const AotStatsEntry &entry)
void insert(const AotStats &other)
QJsonDocument toJsonDocument() const
static AotStats fromJsonDocument(const QJsonDocument &)
static std::optional< AotStats > aggregateAotstatsList(const QString &aotstatsListPath)
static std::optional< AotStats > parseAotstatsFile(const QString &aotstatsPath)
static void addEntry(const QString &filepath, const QQmlJS::AotStatsEntry &entry)
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
std::optional< QList< QString > > extractAotstatsFilesList(const QString &aotstatsListPath)
Combined button and popup list for selecting options.
EGLStreamKHR stream
#define qDebug
[1]
Definition qlogging.h:165
GLenum GLenum GLsizei void GLsizei void * column
GLuint entry
GLuint64EXT * result
[6]
long long qint64
Definition qtypes.h:60
QFile file
[0]
QSharedPointer< T > other(t)
[5]
QStringList files
[8]
bool operator<(const AotStatsEntry &) const
std::chrono::microseconds codegenDuration