diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-07-23 10:40:41 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-07-31 05:13:48 +0000 |
commit | e56eeee9902ffc341506040e637654b2b0451209 (patch) | |
tree | b316f49506739e96e85dfe25bb7759703bcb95f7 /src/qml/compiler | |
parent | 4ac9cf78969436dae456c8fec4a0a706a3d65ec4 (diff) |
Encapsulate the unit data in CompilationUnit
This allows updating the constants table when the unit data is set /
changes and removes the tie to the engine.
Change-Id: Ice553650390589e30e18421c4e55422a55d0df89
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qqmlpropertyvalidator.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 52 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 7 |
6 files changed, 47 insertions, 27 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 04a7854d56..0461299866 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1584,7 +1584,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: char *data = (char*)malloc(totalSize); memcpy(data, jsUnit, unitSize); memset(data + unitSize, 0, totalSize - unitSize); - if (jsUnit != compilationUnit->data) + if (jsUnit != compilationUnit->unitData()) free(jsUnit); jsUnit = nullptr; diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp index 7daf2f1f2f..7ae88cf80c 100644 --- a/src/qml/compiler/qqmlpropertyvalidator.cpp +++ b/src/qml/compiler/qqmlpropertyvalidator.cpp @@ -49,7 +49,7 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, c : enginePrivate(enginePrivate) , compilationUnit(compilationUnit) , imports(imports) - , qmlUnit(compilationUnit->data) + , qmlUnit(compilationUnit->unitData()) , resolvedTypes(compilationUnit->resolvedTypes) , propertyCaches(compilationUnit->propertyCaches) , bindingPropertyDataPerObject(&compilationUnit->bindingPropertyDataPerObject) diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 0d338c8b7e..6582a9ca6b 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -161,14 +161,14 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile() Q_ASSERT(document->javaScriptCompilationUnit); // The js unit owns the data and will free the qml unit. - document->javaScriptCompilationUnit->data = qmlUnit; + document->javaScriptCompilationUnit->setUnitData(qmlUnit); QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = document->javaScriptCompilationUnit; compilationUnit = document->javaScriptCompilationUnit; compilationUnit->typeNameCache = typeNameCache; compilationUnit->resolvedTypes = resolvedTypes; compilationUnit->propertyCaches = std::move(m_propertyCaches); - Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->data->nObjects)); + Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->unitData()->nObjects)); if (errors.isEmpty()) return compilationUnit; @@ -209,7 +209,7 @@ int QQmlTypeCompiler::registerString(const QString &str) const QV4::CompiledData::Unit *QQmlTypeCompiler::qmlUnit() const { - return document->javaScriptCompilationUnit->data; + return document->javaScriptCompilationUnit->unitData(); } const QQmlImports *QQmlTypeCompiler::imports() const diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index b0e9d4ce66..c81ea09cce 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -3534,9 +3534,10 @@ QList<QQmlJS::DiagnosticMessage> Codegen::errors() const QQmlRefPointer<CompiledData::CompilationUnit> Codegen::generateCompilationUnit(bool generateUnitData) { - CompiledData::CompilationUnit *compilationUnit = new CompiledData::CompilationUnit; + CompiledData::Unit *unitData = nullptr; if (generateUnitData) - compilationUnit->data = jsUnitGenerator->generateUnit(); + unitData = jsUnitGenerator->generateUnit(); + CompiledData::CompilationUnit *compilationUnit = new CompiledData::CompilationUnit(unitData); QQmlRefPointer<CompiledData::CompilationUnit> unit; unit.adopt(compilationUnit); diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 0c81a5b3c6..a4c7c98642 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -64,6 +64,7 @@ #include <QCoreApplication> #include <QCryptographicHash> #include <QSaveFile> +#include <QScopeGuard> // generated by qmake: #include "qml_compile_hash_p.h" @@ -91,7 +92,7 @@ static_assert(sizeof(Unit::libraryVersionHash) >= QML_COMPILE_HASH_LENGTH + 1, " CompilationUnit::CompilationUnit(const Unit *unitData) { - data = unitData; + setUnitData(unitData); } #ifndef V4_BOOTSTRAP @@ -101,6 +102,10 @@ CompilationUnit::~CompilationUnit() if (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) free(const_cast<Unit *>(data)); data = nullptr; +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + delete [] constants; + constants = nullptr; +#endif } QString CompilationUnit::localCacheFilePath(const QUrl &url) @@ -175,16 +180,6 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine) } } -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - Value *bigEndianConstants = new Value[data->constantTableSize]; - const quint64_le *littleEndianConstants = data->constants(); - for (uint i = 0; i < data->constantTableSize; ++i) - bigEndianConstants[i] = Value::fromReturnedValue(littleEndianConstants[i]); - constants = bigEndianConstants; -#else - constants = reinterpret_cast<const Value*>(data->constants()); -#endif - linkBackendToEngine(engine); static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE"); @@ -240,10 +235,6 @@ void CompilationUnit::unlink() runtimeClasses = nullptr; qDeleteAll(runtimeFunctions); runtimeFunctions.clear(); -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - delete [] constants; - constants = nullptr; -#endif } void CompilationUnit::markObjects(QV4::MarkStack *markStack) @@ -369,14 +360,18 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeS continue; const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr; - QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit); + const Unit *oldData = data; + auto dataPtrRevert = qScopeGuard([this, oldData](){ + setUnitData(oldData); + }); + setUnitData(mappedUnit); if (data->sourceFileIndex != 0 && sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) { *errorString = QStringLiteral("QML source file has moved to a different location."); continue; } - dataPtrChange.commit(); + dataPtrRevert.dismiss(); free(const_cast<Unit*>(oldDataPtr)); backingFile.reset(cacheFile.take()); return true; @@ -572,6 +567,27 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument) return jsUnit; } +void CompilationUnit::setUnitData(const Unit *unitData) +{ + data = unitData; +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + delete [] constants; +#endif + constants = nullptr; + if (!data) + return; + +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + Value *bigEndianConstants = new Value[data->constantTableSize]; + const quint64_le *littleEndianConstants = data->constants(); + for (uint i = 0; i < data->constantTableSize; ++i) + bigEndianConstants[i] = Value::fromReturnedValue(littleEndianConstants[i]); + constants = bigEndianConstants; +#else + constants = reinterpret_cast<const Value*>(data->constants()); +#endif +} + QString Binding::valueAsString(const Unit *unit) const { switch (type) { @@ -697,7 +713,7 @@ bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engi hash->addData(createPropertyCache(engine)->checksum(&ok)); return ok; } - hash->addData(compilationUnit->data->md5Checksum, sizeof(compilationUnit->data->md5Checksum)); + hash->addData(compilationUnit->unitData()->md5Checksum, sizeof(compilationUnit->unitData()->md5Checksum)); return true; } diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 5103c6901e..31e83e8f76 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -982,7 +982,6 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnitBase QV4::Heap::String **runtimeStrings = nullptr; // Array const Value* constants = nullptr; QV4::Value *runtimeRegularExpressions = nullptr; - const Unit *data = nullptr; QV4::Heap::InternalClass **runtimeClasses = nullptr; }; @@ -993,6 +992,7 @@ Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeRegularExpressions) == offs struct Q_QML_PRIVATE_EXPORT CompilationUnit final : public CompilationUnitBase { + const Unit *data = nullptr; public: CompilationUnit(const Unit *unitData = nullptr); #ifdef V4_BOOTSTRAP @@ -1019,7 +1019,10 @@ public: } // Called only when building QML, when we build the header for JS first and append QML data - QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument); + Unit *createUnitData(QmlIR::Document *irDocument); + + const Unit *unitData() const { return data; } + void setUnitData(const Unit *unitData); #ifndef V4_BOOTSTRAP QIntrusiveListNode nextCompilationUnit; |