aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-01-11 17:46:00 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-01-12 11:18:51 +0100
commit7660c30e08975011c7bd47bcb1796139b9d77196 (patch)
tree26e86cbc35560ac5bdf3327ea29f146cc1821787 /src/qml
parentccc4b52e95ac90c14c59001f675409c1a13c183b (diff)
Cache static compilation units
If we load the same file multiple times, we can re-use the old mapping. In fact we may leak memory if we don't. The fact that we have to use a mutex here is somewhat regrettable, but I haven't found a better way of serializing access. Task-number: QTBUG-89659 Pick-to: 5.15 Change-Id: Iaa44ac80faa5e95f30c05e950ab35083a8b0416b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper.cpp58
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper_p.h13
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp2
3 files changed, 61 insertions, 12 deletions
diff --git a/src/qml/jsruntime/qv4compilationunitmapper.cpp b/src/qml/jsruntime/qv4compilationunitmapper.cpp
index 74f34a284d..f3e2b445d1 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper.cpp
+++ b/src/qml/jsruntime/qv4compilationunitmapper.cpp
@@ -40,23 +40,69 @@
#include "qv4compilationunitmapper_p.h"
#include <private/qv4compileddata_p.h>
-#include <QFileInfo>
-#include <QDateTime>
-#include <QCoreApplication>
+#include <private/qv4executablecompilationunit_p.h>
+
+#include <QtCore/qdatetime.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
using namespace QV4;
-CompilationUnitMapper::CompilationUnitMapper()
- : dataPtr(nullptr)
+class StaticUnitCache
{
+public:
+ StaticUnitCache() : m_lock(&s_mutex) {}
-}
+ CompilationUnitMapper get(const QString &file)
+ {
+ const auto it = s_staticUnits.constFind(file);
+ return it == s_staticUnits.constEnd() ? CompilationUnitMapper() : *it;
+ }
+
+ void set(const QString &file, const CompilationUnitMapper &staticUnit) {
+ s_staticUnits.insert(file, staticUnit);
+ }
+
+private:
+ QMutexLocker<QMutex> m_lock;
+
+ static QMutex s_mutex;
+
+ // We can copy the mappers around because they're all static, that is the dtors are noops.
+ static QHash<QString, CompilationUnitMapper> s_staticUnits;
+};
+
+QHash<QString, CompilationUnitMapper> StaticUnitCache::s_staticUnits;
+QMutex StaticUnitCache::s_mutex;
CompilationUnitMapper::~CompilationUnitMapper()
{
close();
}
+CompiledData::Unit *CompilationUnitMapper::get(
+ const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString)
+{
+ StaticUnitCache cache;
+
+ CompilationUnitMapper mapper = cache.get(cacheFilePath);
+ if (mapper.dataPtr) {
+ auto *unit = reinterpret_cast<CompiledData::Unit *>(mapper.dataPtr);
+ if (ExecutableCompilationUnit::verifyHeader(unit, sourceTimeStamp, errorString)) {
+ *this = mapper;
+ return unit;
+ }
+
+ return nullptr;
+ }
+
+ CompiledData::Unit *data = open(cacheFilePath, sourceTimeStamp, errorString);
+ if (data && (data->flags & CompiledData::Unit::StaticData))
+ cache.set(cacheFilePath, *this);
+
+ return data;
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4compilationunitmapper_p.h b/src/qml/jsruntime/qv4compilationunitmapper_p.h
index 80f914c141..10ad0a6ede 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper_p.h
+++ b/src/qml/jsruntime/qv4compilationunitmapper_p.h
@@ -65,17 +65,20 @@ struct Unit;
class CompilationUnitMapper
{
public:
- CompilationUnitMapper();
~CompilationUnitMapper();
- CompiledData::Unit *open(const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString);
- void close();
+ CompiledData::Unit *get(
+ const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString);
private:
+ CompiledData::Unit *open(
+ const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString);
+ void close();
+
#if defined(Q_OS_UNIX)
- size_t length;
+ size_t length = 0;
#endif
- void *dataPtr;
+ void *dataPtr = nullptr;
};
}
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index 5aaec63a05..8ef8ae2221 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -764,7 +764,7 @@ bool ExecutableCompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &s
const QStringList cachePaths = { sourcePath + QLatin1Char('c'), localCacheFilePath(url) };
for (const QString &cachePath : cachePaths) {
- CompiledData::Unit *mappedUnit = cacheFile->open(cachePath, sourceTimeStamp, errorString);
+ CompiledData::Unit *mappedUnit = cacheFile->get(cachePath, sourceTimeStamp, errorString);
if (!mappedUnit)
continue;