Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
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
// Qt-Security score:significant
4
5
#
include
"qqmljscompilerstats_p.h"
6
7
#
include
<
QFile
>
8
#
include
<
QJsonArray
>
9
#
include
<
QJsonDocument
>
10
#
include
<
QJsonObject
>
11
#
include
<
QTextStream
>
12
13
QT_BEGIN_NAMESPACE
14
15
namespace
QQmlJS
{
16
17
using
namespace
Qt
::
StringLiterals
;
18
19
std
::
unique_ptr
<
AotStats
>
QQmlJSAotCompilerStats
::
s_instance
=
std
::
make_unique
<
AotStats
>();
20
QString
QQmlJSAotCompilerStats
::
s_moduleId
;
21
bool
QQmlJSAotCompilerStats
::
s_recordAotStats
=
false
;
22
23
bool
QQmlJS
::
AotStatsEntry
::
operator
<(
const
AotStatsEntry
&
other
)
const
24
{
25
if
(
line
==
other
.
line
)
26
return
column
<
other
.
column
;
27
return
line
<
other
.
line
;
28
}
29
30
void
AotStats
::
insert
(
const
AotStats
&
other
)
31
{
32
for
(
const
auto
&[
moduleUri
,
moduleStats
] :
other
.
m_entries
.
asKeyValueRange
()) {
33
m_entries
[
moduleUri
].
insert
(
moduleStats
);
34
}
35
}
36
37
std
::
optional
<
QList
<
QString
>>
AotStats
::
readAllLines
(
const
QString
&
path
)
38
{
39
QFile
aotstatsListFile
(
path
);
40
if
(!
aotstatsListFile
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
)) {
41
qDebug
().
noquote
() << u"Could not open \"%1\" for reading"_s.
arg
(
aotstatsListFile
.
fileName
());
42
return
std
::
nullopt
;
43
}
44
45
QStringList
aotstatsFiles
;
46
QTextStream
stream
(&
aotstatsListFile
);
47
while
(!
stream
.
atEnd
())
48
aotstatsFiles
.
append
(
stream
.
readLine
());
49
50
return
aotstatsFiles
;
51
}
52
53
std
::
optional
<
AotStats
>
AotStats
::
parseAotstatsFile
(
const
QString
&
aotstatsPath
)
54
{
55
QFile
file
(
aotstatsPath
);
56
if
(!
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
)) {
57
qDebug
().
noquote
() << u"Could not open \"%1\""_s.
arg
(
aotstatsPath
);
58
return
std
::
nullopt
;
59
}
60
61
return
AotStats
::
fromJsonDocument
(
QJsonDocument
::
fromJson
(
file
.
readAll
()));
62
}
63
64
std
::
optional
<
AotStats
>
AotStats
::
aggregateAotstatsList
(
const
QString
&
aotstatsListPath
)
65
{
66
const
auto
aotstatsFiles
=
readAllLines
(
aotstatsListPath
);
67
if
(!
aotstatsFiles
.
has_value
())
68
return
std
::
nullopt
;
69
70
AotStats
aggregated
;
71
if
(
aotstatsFiles
->
empty
())
72
return
aggregated
;
73
74
for
(
const
auto
&
aotstatsFile
:
aotstatsFiles
.
value
()) {
75
auto
parsed
=
parseAotstatsFile
(
aotstatsFile
);
76
if
(!
parsed
.
has_value
())
77
return
std
::
nullopt
;
78
aggregated
.
insert
(
parsed
.
value
());
79
}
80
81
return
aggregated
;
82
}
83
84
static
constexpr
int
S_AOTSTATS_FORMAT_REVISION
= 1;
// Added support for skipping
85
86
static
constexpr
QLatin1StringView
S_CODEGEN_RESULT
{
"codegenResult"
};
87
static
constexpr
QLatin1StringView
S_COLUMN
{
"column"
};
88
static
constexpr
QLatin1StringView
S_DURATION_MICROSECONDS
{
"durationMicroseconds"
};
89
static
constexpr
QLatin1StringView
S_ENTRIES
{
"entries"
};
90
static
constexpr
QLatin1StringView
S_FILE_PATH
{
"filePath"
};
91
static
constexpr
QLatin1StringView
S_FORMAT_REVISION
{
"formatRevision"
};
92
static
constexpr
QLatin1StringView
S_FUNCTION_NAME
{
"functionName"
};
93
static
constexpr
QLatin1StringView
S_LINE
{
"line"
};
94
static
constexpr
QLatin1StringView
S_MESSAGE
{
"message"
};
95
static
constexpr
QLatin1StringView
S_MODULES
{
"modules"
};
96
static
constexpr
QLatin1StringView
S_MODULE_FILES
{
"moduleFiles"
};
97
static
constexpr
QLatin1StringView
S_MODULE_ID
{
"moduleId"
};
98
99
std
::
optional
<
AotStats
>
AotStats
::
fromJsonDocument
(
const
QJsonDocument
&
document
)
100
{
101
QJsonObject
root
=
document
.
object
();
102
const
QJsonValue
revision
=
root
[
S_FORMAT_REVISION
];
103
if
(
revision
.
isUndefined
() ||
revision
.
toInt
() !=
S_AOTSTATS_FORMAT_REVISION
) {
104
qDebug
() <<
"AotStats format revision missmatch. Please try again with a clean build."
;
105
return
std
::
nullopt
;
106
}
107
108
const
QJsonArray
modulesArray
=
root
[
S_MODULES
].
toArray
();
109
QQmlJS
::
AotStats
result
;
110
for
(
const
auto
&
modulesArrayEntry
:
std
::
as_const
(
modulesArray
)) {
111
const
auto
&
moduleObject
=
modulesArrayEntry
.
toObject
();
112
QString
moduleId
=
moduleObject
[
S_MODULE_ID
].
toString
();
113
const
QJsonArray
&
filesArray
=
moduleObject
[
S_MODULE_FILES
].
toArray
();
114
115
QHash
<
QString
,
QList
<
AotStatsEntry
>>
files
;
116
for
(
const
auto
&
filesArrayEntry
:
filesArray
) {
117
const
QJsonObject
&
fileObject
=
filesArrayEntry
.
toObject
();
118
QString
filepath
=
fileObject
[
S_FILE_PATH
].
toString
();
119
const
QJsonArray
&
statsArray
=
fileObject
[
S_ENTRIES
].
toArray
();
120
121
QList
<
AotStatsEntry
>
stats
;
122
for
(
const
auto
&
statsArrayEntry
:
statsArray
) {
123
const
auto
&
statsObject
=
statsArrayEntry
.
toObject
();
124
QQmlJS
::
AotStatsEntry
stat
;
125
auto
micros
=
statsObject
[
S_DURATION_MICROSECONDS
].
toInteger
();
126
stat
.
codegenDuration
=
std
::
chrono
::
microseconds
(
micros
);
127
stat
.
functionName
=
statsObject
[
S_FUNCTION_NAME
].
toString
();
128
stat
.
message
=
statsObject
[
S_MESSAGE
].
toString
();
129
stat
.
line
=
statsObject
[
S_LINE
].
toInt
();
130
stat
.
column
=
statsObject
[
S_COLUMN
].
toInt
();
131
stat
.
codegenResult
=
QQmlJS
::
CodegenResult
(
statsObject
[
S_CODEGEN_RESULT
].
toInt
());
132
stats
.
append
(
std
::
move
(
stat
));
133
}
134
135
std
::
sort
(
stats
.
begin
(),
stats
.
end
());
136
files
[
filepath
] =
std
::
move
(
stats
);
137
}
138
139
result
.
m_entries
[
moduleId
] =
std
::
move
(
files
);
140
}
141
142
return
result
;
143
}
144
145
QJsonDocument
AotStats
::
toJsonDocument
()
const
146
{
147
QJsonArray
modulesArray
;
148
for
(
auto
it1
=
m_entries
.
begin
();
it1
!=
m_entries
.
end
(); ++
it1
) {
149
const
QString
moduleId
=
it1
.
key
();
150
const
QHash
<
QString
,
QList
<
AotStatsEntry
>> &
files
=
it1
.
value
();
151
152
QJsonArray
filesArray
;
153
for
(
auto
it2
=
files
.
begin
();
it2
!=
files
.
end
(); ++
it2
) {
154
const
QString
&
filename
=
it2
.
key
();
155
const
QList
<
AotStatsEntry
> &
stats
=
it2
.
value
();
156
157
QJsonArray
statsArray
;
158
for
(
const
auto
&
stat
:
stats
) {
159
QJsonObject
statObject
;
160
auto
micros
=
static_cast
<
qint64
>(
stat
.
codegenDuration
.
count
());
161
statObject
.
insert
(
S_DURATION_MICROSECONDS
,
micros
);
162
statObject
.
insert
(
S_FUNCTION_NAME
,
stat
.
functionName
);
163
statObject
.
insert
(
S_MESSAGE
,
stat
.
message
);
164
statObject
.
insert
(
S_LINE
,
stat
.
line
);
165
statObject
.
insert
(
S_COLUMN
,
stat
.
column
);
166
using
CodegenResType
=
std
::
underlying_type_t
<
QQmlJS
::
CodegenResult
>;
167
statObject
.
insert
(
S_CODEGEN_RESULT
,
168
static_cast
<
CodegenResType
>(
stat
.
codegenResult
));
169
statsArray
.
append
(
statObject
);
170
}
171
172
QJsonObject
o
;
173
o
.
insert
(
S_FILE_PATH
,
filename
);
174
o
.
insert
(
S_ENTRIES
,
statsArray
);
175
filesArray
.
append
(
o
);
176
}
177
178
QJsonObject
o
;
179
o
.
insert
(
S_MODULE_ID
,
moduleId
);
180
o
.
insert
(
S_MODULE_FILES
,
filesArray
);
181
modulesArray
.
append
(
o
);
182
}
183
184
QJsonObject
root
;
185
root
.
insert
(
S_FORMAT_REVISION
,
S_AOTSTATS_FORMAT_REVISION
);
186
root
.
insert
(
S_MODULES
,
modulesArray
);
187
return
QJsonDocument
(
root
);
188
}
189
190
void
AotStats
::
registerFile
(
const
QString
&
moduleId
,
const
QString
&
filepath
)
191
{
192
m_entries
[
moduleId
][
filepath
] = {};
193
}
194
195
void
AotStats
::
addEntry
(
196
const
QString
&
moduleId
,
const
QString
&
filepath
,
const
AotStatsEntry
&
entry
)
197
{
198
m_entries
[
moduleId
][
filepath
].
append
(
entry
);
199
}
200
201
bool
AotStats
::
saveToDisk
(
const
QString
&
filepath
)
const
202
{
203
QFile
file
(
filepath
);
204
if
(!
file
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
|
QIODevice
::
Truncate
)) {
205
qDebug
().
noquote
() << u"Could not open \"%1\""_s.
arg
(
filepath
);
206
return
false
;
207
}
208
209
file
.
write
(
this
->
toJsonDocument
().
toJson
(
QJsonDocument
::
Indented
));
210
return
true
;
211
}
212
213
void
QQmlJSAotCompilerStats
::
registerFile
(
const
QString
&
filepath
)
214
{
215
QQmlJSAotCompilerStats
::
instance
()->
registerFile
(
s_moduleId
,
filepath
);
216
}
217
218
void
QQmlJSAotCompilerStats
::
addEntry
(
const
QString
&
filepath
,
const
QQmlJS
::
AotStatsEntry
&
entry
)
219
{
220
QQmlJSAotCompilerStats
::
instance
()->
addEntry
(
s_moduleId
,
filepath
,
entry
);
221
}
222
223
}
// namespace QQmlJS
224
225
QT_END_NAMESPACE
QQmlJS
Definition
qv4bytecodegenerator_p.h:27
QQmlJS::S_LINE
static constexpr QLatin1StringView S_LINE
Definition
qqmljscompilerstats.cpp:93
QQmlJS::S_FORMAT_REVISION
static constexpr QLatin1StringView S_FORMAT_REVISION
Definition
qqmljscompilerstats.cpp:91
QQmlJS::S_ENTRIES
static constexpr QLatin1StringView S_ENTRIES
Definition
qqmljscompilerstats.cpp:89
QQmlJS::S_COLUMN
static constexpr QLatin1StringView S_COLUMN
Definition
qqmljscompilerstats.cpp:87
QQmlJS::S_MESSAGE
static constexpr QLatin1StringView S_MESSAGE
Definition
qqmljscompilerstats.cpp:94
QQmlJS::S_CODEGEN_RESULT
static constexpr QLatin1StringView S_CODEGEN_RESULT
Definition
qqmljscompilerstats.cpp:86
QQmlJS::S_AOTSTATS_FORMAT_REVISION
static constexpr int S_AOTSTATS_FORMAT_REVISION
Definition
qqmljscompilerstats.cpp:84
QQmlJS::S_MODULES
static constexpr QLatin1StringView S_MODULES
Definition
qqmljscompilerstats.cpp:95
QQmlJS::S_FILE_PATH
static constexpr QLatin1StringView S_FILE_PATH
Definition
qqmljscompilerstats.cpp:90
QQmlJS::S_DURATION_MICROSECONDS
static constexpr QLatin1StringView S_DURATION_MICROSECONDS
Definition
qqmljscompilerstats.cpp:88
QQmlJS::S_MODULE_FILES
static constexpr QLatin1StringView S_MODULE_FILES
Definition
qqmljscompilerstats.cpp:96
QQmlJS::S_MODULE_ID
static constexpr QLatin1StringView S_MODULE_ID
Definition
qqmljscompilerstats.cpp:97
QQmlJS::S_FUNCTION_NAME
static constexpr QLatin1StringView S_FUNCTION_NAME
Definition
qqmljscompilerstats.cpp:92
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtdeclarative
src
qmlcompiler
qqmljscompilerstats.cpp
Generated on
for Qt by
1.18.0