1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qv4profiling_p.h"
5#include <private/qv4mm_p.h>
6#include <private/qv4string_p.h>
7
8QT_BEGIN_NAMESPACE
9
10namespace QV4 {
11namespace Profiling {
12
13FunctionLocation FunctionCall::resolveLocation() const
14{
15 return FunctionLocation(m_function->name()->toQString(),
16 m_function->executableCompilationUnit()->fileName(),
17 m_function->compiledFunction->location.line(),
18 m_function->compiledFunction->location.column());
19}
20
21FunctionCallProperties FunctionCall::properties() const
22{
23 FunctionCallProperties props = {
24 .start: m_start,
25 .end: m_end,
26 .id: reinterpret_cast<quintptr>(m_function)
27 };
28 return props;
29}
30
31Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine(engine)
32{
33 static const int metatypes[] = {
34 qRegisterMetaType<QVector<QV4::Profiling::FunctionCallProperties> >(),
35 qRegisterMetaType<QVector<QV4::Profiling::MemoryAllocationProperties> >(),
36 qRegisterMetaType<FunctionLocationHash>()
37 };
38 Q_UNUSED(metatypes);
39 m_timer.start();
40}
41
42void Profiler::stopProfiling()
43{
44 featuresEnabled = 0;
45 reportData();
46 m_sentLocations.clear();
47}
48
49bool operator<(const FunctionCall &call1, const FunctionCall &call2)
50{
51 return call1.m_start < call2.m_start ||
52 (call1.m_start == call2.m_start && (call1.m_end < call2.m_end ||
53 (call1.m_end == call2.m_end && call1.m_function < call2.m_function)));
54}
55
56void Profiler::reportData()
57{
58 std::sort(first: m_data.begin(), last: m_data.end());
59 QVector<FunctionCallProperties> properties;
60 FunctionLocationHash locations;
61 properties.reserve(size: m_data.size());
62
63 for (const FunctionCall &call : std::as_const(t&: m_data)) {
64 properties.append(t: call.properties());
65 Function *function = call.function();
66 Q_ASSERT(function);
67 SentMarker &marker = m_sentLocations[reinterpret_cast<quintptr>(function)];
68 if (!marker.isValid()) {
69 FunctionLocation &location = locations[properties.constLast().id];
70 if (!location.isValid())
71 location = call.resolveLocation();
72 marker.setFunction(function);
73 }
74 }
75
76 emit dataReady(locations, properties, m_memory_data);
77 m_data.clear();
78 m_memory_data.clear();
79}
80
81void Profiler::startProfiling(quint64 features)
82{
83 if (featuresEnabled == 0) {
84 if (features & (1 << FeatureMemoryAllocation)) {
85 qint64 timestamp = m_timer.nsecsElapsed();
86 MemoryAllocationProperties heap = {.timestamp: timestamp,
87 .size: (qint64)m_engine->memoryManager->getAllocatedMem() -
88 (qint64)m_engine->memoryManager->getLargeItemsMem(),
89 .type: HeapPage};
90 m_memory_data.append(t: heap);
91 MemoryAllocationProperties smallP = {.timestamp: timestamp,
92 .size: (qint64)m_engine->memoryManager->getUsedMem(),
93 .type: SmallItem};
94 m_memory_data.append(t: smallP);
95 MemoryAllocationProperties large = {.timestamp: timestamp,
96 .size: (qint64)m_engine->memoryManager->getLargeItemsMem(),
97 .type: LargeItem};
98 m_memory_data.append(t: large);
99 }
100
101 featuresEnabled = features;
102 }
103}
104
105} // namespace Profiling
106} // namespace QV4
107
108QT_END_NAMESPACE
109
110#include "moc_qv4profiling_p.cpp"
111

source code of qtdeclarative/src/qml/jsruntime/qv4profiling.cpp