diff options
-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 | ||||
-rw-r--r-- | tools/qmlcachegen/qmlcachegen.cpp | 36 |
4 files changed, 60 insertions, 41 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 diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index 63be5c5ec4..7b4135e1f8 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -169,7 +169,7 @@ static bool checkArgumentsObjectUseInSignalHandlers(const QmlIR::Document &doc, return true; } -using SaveFunction = std::function<bool (const QV4::CompiledData::CompilationUnit &, QString *)>; +using SaveFunction = std::function<bool(const QV4::CompiledData::SaveableUnitPointer &, QString *)>; static bool compileQmlFile(const QString &inputFileName, SaveFunction saveFunction, Error *error) { @@ -229,11 +229,13 @@ static bool compileQmlFile(const QString &inputFileName, SaveFunction saveFuncti QmlIR::QmlUnitGenerator generator; irDocument.javaScriptCompilationUnit = v4CodeGen.generateCompilationUnit(/*generate unit*/false); generator.generate(irDocument); - QV4::CompiledData::Unit *unit = const_cast<QV4::CompiledData::Unit*>(irDocument.javaScriptCompilationUnit.data); - unit->flags |= QV4::CompiledData::Unit::StaticData; - unit->flags |= QV4::CompiledData::Unit::PendingTypeCompilation; - if (!saveFunction(irDocument.javaScriptCompilationUnit, &error->message)) + const quint32 saveFlags + = QV4::CompiledData::Unit::StaticData + | QV4::CompiledData::Unit::PendingTypeCompilation; + QV4::CompiledData::SaveableUnitPointer saveable(&irDocument.javaScriptCompilationUnit, + saveFlags); + if (!saveFunction(saveable, &error->message)) return false; } return true; @@ -321,17 +323,15 @@ static bool compileJSFile(const QString &inputFileName, const QString &inputFile irDocument.javaScriptCompilationUnit = v4CodeGen.generateCompilationUnit(/*generate unit*/false); QmlIR::QmlUnitGenerator generator; generator.generate(irDocument); - QV4::CompiledData::Unit *unitData = const_cast<QV4::CompiledData::Unit*>(irDocument.javaScriptCompilationUnit.data); - unitData->flags |= QV4::CompiledData::Unit::StaticData; unit = std::move(irDocument.javaScriptCompilationUnit); } } - return saveFunction(unit, &error->message); + return saveFunction(QV4::CompiledData::SaveableUnitPointer(&unit), &error->message); } static bool saveUnitAsCpp(const QString &inputFileName, const QString &outputFileName, - const QV4::CompiledData::CompilationUnit &unit, + const QV4::CompiledData::SaveableUnitPointer &unit, QString *errorString) { QSaveFile f(outputFileName); @@ -368,17 +368,9 @@ static bool saveUnitAsCpp(const QString &inputFileName, const QString &outputFil QByteArray hexifiedData; { - QByteArray modifiedUnit; - modifiedUnit.resize(unit.data->unitSize); - memcpy(modifiedUnit.data(), unit.data, unit.data->unitSize); - const char *dataPtr = modifiedUnit.data(); - QV4::CompiledData::Unit *unitPtr; - memcpy(&unitPtr, &dataPtr, sizeof(unitPtr)); - unitPtr->flags |= QV4::CompiledData::Unit::StaticData; - QTextStream stream(&hexifiedData); - const uchar *begin = reinterpret_cast<const uchar *>(modifiedUnit.constData()); - const uchar *end = begin + unit.data->unitSize; + const uchar *begin = unit.data<uchar>(); + const uchar *end = begin + unit.size(); stream << hex; int col = 0; for (const uchar *data = begin; data < end; ++data, ++col) { @@ -527,15 +519,15 @@ int main(int argc, char **argv) inputFileUrl = QStringLiteral("qrc://") + inputResourcePath; saveFunction = [inputResourcePath, outputFileName]( - const QV4::CompiledData::CompilationUnit &unit, + const QV4::CompiledData::SaveableUnitPointer &unit, QString *errorString) { return saveUnitAsCpp(inputResourcePath, outputFileName, unit, errorString); }; } else { - saveFunction = [outputFileName](const QV4::CompiledData::CompilationUnit &unit, + saveFunction = [outputFileName](const QV4::CompiledData::SaveableUnitPointer &unit, QString *errorString) { - return unit.saveToDisk(outputFileName, errorString); + return unit->saveToDisk(outputFileName, errorString); }; } |