aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp3
-rw-r--r--src/qml/compiler/qv4compileddata.cpp19
-rw-r--r--src/qml/compiler/qv4compileddata_p.h43
3 files changed, 46 insertions, 19 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index e63aa3b66d..6f46648572 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1565,9 +1565,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
break;
}
}
- // This unit's memory was allocated with malloc on the heap, so it's
- // definitely not suitable for StaticData access.
- createdUnit->flags &= ~QV4::CompiledData::Unit::StaticData;
if (dependencyHasher) {
const QByteArray checksum = dependencyHasher();
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 091c29c8c7..71015107ad 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -82,14 +82,8 @@ CompilationUnit::~CompilationUnit()
free(const_cast<QmlUnit *>(qmlData));
qmlData = nullptr;
-#ifndef V4_BOOTSTRAP
if (!(data->flags & QV4::CompiledData::Unit::StaticData))
free(const_cast<Unit *>(data));
-#else
- // Unconditionally free the memory. In the dev tools we create units that have
- // the flag set and will be saved to disk, so intended to persist later.
- free(const_cast<Unit *>(data));
-#endif
}
data = nullptr;
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -113,16 +107,9 @@ bool CompilationUnit::saveToDisk(const QString &outputFileName, QString *errorSt
return false;
}
- QByteArray modifiedUnit;
- modifiedUnit.resize(data->unitSize);
- memcpy(modifiedUnit.data(), data, data->unitSize);
- const char *dataPtr = modifiedUnit.data();
- Unit *unitPtr;
- memcpy(&unitPtr, &dataPtr, sizeof(unitPtr));
- unitPtr->flags |= Unit::StaticData;
-
- qint64 headerWritten = cacheFile.write(modifiedUnit);
- if (headerWritten != modifiedUnit.size()) {
+ SaveableUnitPointer saveable(this);
+ qint64 headerWritten = cacheFile.write(saveable.data<char>(), saveable.size());
+ if (headerWritten != saveable.size()) {
*errorString = cacheFile.errorString();
return false;
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 9301939bff..629adf8231 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -1158,6 +1158,49 @@ public:
bool saveToDisk(const QString &outputFileName, QString *errorString) const;
};
+class SaveableUnitPointer
+{
+ Q_DISABLE_COPY_MOVE(SaveableUnitPointer)
+public:
+ SaveableUnitPointer(const CompilationUnit *unit, quint32 temporaryFlags = Unit::StaticData) :
+ unit(unit)
+ {
+ quint32_le &unitFlags = mutableFlags();
+ quint32 origFlags = unitFlags;
+ unitFlags |= temporaryFlags;
+ changedFlags = origFlags ^ unitFlags;
+ }
+
+ ~SaveableUnitPointer()
+ {
+ mutableFlags() ^= changedFlags;
+ }
+
+ const CompilationUnit *operator->() const { return unit; }
+ const CompilationUnit &operator*() const { return *unit; }
+ operator const CompilationUnit *() { return unit; }
+
+ template<typename Char>
+ const Char *data() const
+ {
+ Q_STATIC_ASSERT(sizeof(Char) == 1);
+ const Char *dataPtr;
+ memcpy(&dataPtr, &unit->data, sizeof(dataPtr));
+ return dataPtr;
+ }
+
+ quint32 size() const
+ {
+ return unit->data->unitSize;
+ }
+
+private:
+ quint32_le &mutableFlags() { return const_cast<Unit *>(unit->unitData())->flags; };
+ const CompilationUnit *unit;
+ quint32 changedFlags;
+};
+
+
} // CompiledData namespace
} // QV4 namespace