aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-07-23 10:40:41 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-07-31 05:13:48 +0000
commite56eeee9902ffc341506040e637654b2b0451209 (patch)
treeb316f49506739e96e85dfe25bb7759703bcb95f7 /src/qml/compiler
parent4ac9cf78969436dae456c8fec4a0a706a3d65ec4 (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.cpp2
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp2
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp6
-rw-r--r--src/qml/compiler/qv4codegen.cpp5
-rw-r--r--src/qml/compiler/qv4compileddata.cpp52
-rw-r--r--src/qml/compiler/qv4compileddata_p.h7
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;