diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 19 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 43 |
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 |