diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-07-26 09:49:36 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-07-31 17:08:31 +0000 |
commit | c549d9c4e58ef8b6f9c8d954dc24072ce529f326 (patch) | |
tree | 025b81a2ab85b76ff7183703eeb9835db5a03e96 /src/qml | |
parent | a05d1796b88e628655afdba6063a186d3a0803bf (diff) |
Simplify loading of ahead-of-time created QML cache files
Consolidate the old "createUnitData" code that used to be a virtual
function into the one call site and avoid a malloc that way.
By the way of that, the string table gets a guard to prevent accidental
registerString() calls at a later point.
Change-Id: Ia3f8d3e874b7733822e6942e411c940ec60d95a5
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 40 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 25 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler_p.h | 3 |
5 files changed, 34 insertions, 39 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 511b953eaa..90ba0506f0 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1554,8 +1554,26 @@ bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *prope QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher) { QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = output.javaScriptCompilationUnit; - QV4::CompiledData::Unit *jsUnit = compilationUnit->createUnitData(&output); - const uint unitSize = jsUnit->unitSize; + + const QV4::CompiledData::Unit *jsUnit = nullptr; + uint jsUnitSize = 0; + + // We may already have unit data if we're loading an ahead-of-time generated cache file. + if (compilationUnit->data) { + jsUnit = const_cast<QV4::CompiledData::Unit*>(compilationUnit->data); + // Discard the old QML tables we will re-create further down anyway. + quint32 unitSizeWithoutQMLTables = jsUnit->offsetToImports; + jsUnitSize = unitSizeWithoutQMLTables; + } else { + jsUnit = output.jsGenerator.generateUnit(QV4::Compiler::JSUnitGenerator::GenerateWithoutStringTable); + jsUnitSize = jsUnit->unitSize; + } + + output.jsGenerator.stringTable.registerString(output.jsModule.fileName); + output.jsGenerator.stringTable.registerString(output.jsModule.finalUrl); + + // No more new strings after this point, we're calculating offsets. + output.jsGenerator.stringTable.freeze(); const int importSize = sizeof(QV4::CompiledData::Import) * output.imports.count(); const int objectOffsetTableSize = output.objects.count() * sizeof(quint32); @@ -1564,7 +1582,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: int objectsSize = 0; for (Object *o : qAsConst(output.objects)) { - objectOffsets.insert(o, unitSize + importSize + objectOffsetTableSize + objectsSize); + objectOffsets.insert(o, jsUnitSize + importSize + objectOffsetTableSize + objectsSize); objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count); int signalTableSize = 0; @@ -1580,12 +1598,10 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: objectsSize += enumTableSize; } - const int totalSize = unitSize + importSize + objectOffsetTableSize + objectsSize + output.jsGenerator.stringTable.sizeOfTableAndData(); + const int totalSize = jsUnitSize + importSize + objectOffsetTableSize + objectsSize + output.jsGenerator.stringTable.sizeOfTableAndData(); char *data = (char*)malloc(totalSize); - memcpy(data, jsUnit, unitSize); - memset(data + unitSize, 0, totalSize - unitSize); - if (jsUnit != compilationUnit->unitData()) - free(jsUnit); + memcpy(data, jsUnit, jsUnitSize); + memset(data + jsUnitSize, 0, totalSize - jsUnitSize); jsUnit = nullptr; QV4::CompiledData::Unit *qmlUnit = reinterpret_cast<QV4::CompiledData::Unit *>(data); @@ -1594,12 +1610,14 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: // This unit's memory was allocated with malloc on the heap, so it's // definitely not suitable for StaticData access. qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData; - qmlUnit->offsetToImports = unitSize; + qmlUnit->offsetToImports = jsUnitSize; qmlUnit->nImports = output.imports.count(); - qmlUnit->offsetToObjects = unitSize + importSize; + qmlUnit->offsetToObjects = jsUnitSize + importSize; qmlUnit->nObjects = output.objects.count(); qmlUnit->offsetToStringTable = totalSize - output.jsGenerator.stringTable.sizeOfTableAndData(); qmlUnit->stringTableSize = output.jsGenerator.stringTable.stringCount(); + qmlUnit->sourceFileIndex = output.jsGenerator.stringTable.getStringId(output.jsModule.fileName); + qmlUnit->finalUrlIndex = output.jsGenerator.stringTable.getStringId(output.jsModule.finalUrl); #ifndef V4_BOOTSTRAP if (dependencyHasher) { @@ -1762,7 +1780,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: if (showStats) { qDebug() << "Generated QML unit that is" << qmlUnit->unitSize << "bytes big contains:"; qDebug() << " " << qmlUnit->functionTableSize << "functions"; - qDebug() << " " << unitSize << "for JS unit"; + qDebug() << " " << jsUnitSize << "for JS unit"; qDebug() << " " << importSize << "for imports"; qDebug() << " " << objectsSize << "for" << qmlUnit->nObjects << "objects"; quint32 totalBindingCount = 0; diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index f9216b5c4a..af0cfedf5b 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -463,31 +463,6 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString) #endif // QT_CONFIG(temporaryfile) } -Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument) -{ - if (!irDocument->javaScriptCompilationUnit->data) - return irDocument->jsGenerator.generateUnit(QV4::Compiler::JSUnitGenerator::GenerateWithoutStringTable); - - QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = irDocument->javaScriptCompilationUnit; - QV4::CompiledData::Unit *jsUnit = const_cast<QV4::CompiledData::Unit*>(compilationUnit->data); - // Discard the old QML tables as the caller will re-create them anyway. - quint32 unitSizeWithoutQMLTables = jsUnit->offsetToImports; - char *unitCopy = (char*)malloc(unitSizeWithoutQMLTables); - memcpy(unitCopy, jsUnit, unitSizeWithoutQMLTables); - jsUnit = reinterpret_cast<QV4::CompiledData::Unit*>(unitCopy); - jsUnit->flags &= ~QV4::CompiledData::Unit::StaticData; - jsUnit->unitSize = unitSizeWithoutQMLTables; - - QV4::Compiler::StringTableGenerator &stringTable = irDocument->jsGenerator.stringTable; - - if (jsUnit->sourceFileIndex == quint32(0) || stringTable.stringForIndex(jsUnit->sourceFileIndex) != irDocument->jsModule.fileName) { - jsUnit->sourceFileIndex = stringTable.registerString(irDocument->jsModule.fileName); - jsUnit->finalUrlIndex = stringTable.registerString(irDocument->jsModule.finalUrl); - } - - return jsUnit; -} - void CompilationUnit::setUnitData(const Unit *unitData) { data = unitData; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index bf83c45384..1120567d2a 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -1018,9 +1018,6 @@ public: return refCount.load(); } - // Called only when building QML, when we build the header for JS first and append QML data - Unit *createUnitData(QmlIR::Document *irDocument); - const Unit *unitData() const { return data; } void setUnitData(const Unit *unitData); diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index bc7265ab0c..44b809899f 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -55,6 +55,7 @@ QV4::Compiler::StringTableGenerator::StringTableGenerator() int QV4::Compiler::StringTableGenerator::registerString(const QString &str) { + Q_ASSERT(!frozen); QHash<QString, int>::ConstIterator it = stringToId.constFind(str); if (it != stringToId.cend()) return *it; @@ -75,6 +76,7 @@ void QV4::Compiler::StringTableGenerator::clear() strings.clear(); stringToId.clear(); stringDataSize = 0; + frozen = false; } void QV4::Compiler::StringTableGenerator::initializeFromBackingUnit(const QV4::CompiledData::Unit *unit) diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h index bb9794358b..f2547f2d06 100644 --- a/src/qml/compiler/qv4compiler_p.h +++ b/src/qml/compiler/qv4compiler_p.h @@ -84,6 +84,8 @@ struct Q_QML_PRIVATE_EXPORT StringTableGenerator { uint sizeOfTableAndData() const { return stringDataSize + stringCount() * sizeof(uint); } + void freeze() { frozen = true; } + void clear(); void initializeFromBackingUnit(const CompiledData::Unit *unit); @@ -95,6 +97,7 @@ private: QStringList strings; uint stringDataSize; uint backingUnitTableSize = 0; + bool frozen = false; }; struct Q_QML_PRIVATE_EXPORT JSUnitGenerator { |