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 "qv4compilationunitmapper_p.h" |
5 | |
6 | #include <private/qv4compileddata_p.h> |
7 | #include <private/qv4executablecompilationunit_p.h> |
8 | |
9 | #include <QtCore/qdatetime.h> |
10 | #include <QtCore/qmutex.h> |
11 | #include <QtCore/qhash.h> |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | using namespace QV4; |
16 | |
17 | class StaticUnitCache |
18 | { |
19 | public: |
20 | StaticUnitCache() : m_lock(&s_mutex) {} |
21 | |
22 | CompilationUnitMapper get(const QString &file) |
23 | { |
24 | const auto it = s_staticUnits.constFind(key: file); |
25 | return it == s_staticUnits.constEnd() ? CompilationUnitMapper() : *it; |
26 | } |
27 | |
28 | void set(const QString &file, const CompilationUnitMapper &staticUnit) { |
29 | s_staticUnits.insert(key: file, value: staticUnit); |
30 | } |
31 | |
32 | void remove(const QString &file) |
33 | { |
34 | s_staticUnits.remove(key: file); |
35 | } |
36 | |
37 | private: |
38 | QMutexLocker<QMutex> m_lock; |
39 | |
40 | static QMutex s_mutex; |
41 | |
42 | // We can copy the mappers around because they're all static. |
43 | // We never unmap the files. |
44 | static QHash<QString, CompilationUnitMapper> s_staticUnits; |
45 | }; |
46 | |
47 | QHash<QString, CompilationUnitMapper> StaticUnitCache::s_staticUnits; |
48 | QMutex StaticUnitCache::s_mutex; |
49 | |
50 | CompiledData::Unit *CompilationUnitMapper::get( |
51 | const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString) |
52 | { |
53 | StaticUnitCache cache; |
54 | |
55 | CompilationUnitMapper mapper = cache.get(file: cacheFilePath); |
56 | if (mapper.dataPtr) { |
57 | auto *unit = reinterpret_cast<CompiledData::Unit *>(mapper.dataPtr); |
58 | if (ExecutableCompilationUnit::verifyHeader(unit, expectedSourceTimeStamp: sourceTimeStamp, errorString)) { |
59 | *this = mapper; |
60 | return unit; |
61 | } |
62 | |
63 | return nullptr; |
64 | } |
65 | |
66 | CompiledData::Unit *data = open(cacheFilePath, sourceTimeStamp, errorString); |
67 | if (data && (data->flags & CompiledData::Unit::StaticData)) { |
68 | cache.set(file: cacheFilePath, staticUnit: *this); |
69 | return data; |
70 | } else { |
71 | close(); |
72 | return nullptr; |
73 | } |
74 | } |
75 | |
76 | void CompilationUnitMapper::invalidate(const QString &cacheFilePath) |
77 | { |
78 | StaticUnitCache cache; |
79 | cache.remove(file: cacheFilePath); |
80 | } |
81 | |
82 | QT_END_NAMESPACE |
83 | |