aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compileddata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler/qv4compileddata.cpp')
-rw-r--r--src/qml/compiler/qv4compileddata.cpp66
1 files changed, 42 insertions, 24 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 8f8d374e24..c56f08c2f0 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -77,13 +77,7 @@ namespace QV4 {
namespace CompiledData {
-#ifdef V4_BOOTSTRAP
-static QString cacheFilePath(const QString &localSourcePath)
-{
- const QString localCachePath = localSourcePath + QLatin1Char('c');
- return localCachePath;
-}
-#else
+#if !defined(V4_BOOTSTRAP)
static QString cacheFilePath(const QUrl &url)
{
const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url);
@@ -102,7 +96,6 @@ static QString cacheFilePath(const QUrl &url)
CompilationUnit::CompilationUnit()
: data(0)
, engine(0)
- , runtimeStrings(0)
, runtimeLookups(0)
, runtimeRegularExpressions(0)
, runtimeClasses(0)
@@ -132,8 +125,10 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
runtimeStrings = (QV4::Heap::String **)malloc(data->stringTableSize * sizeof(QV4::Heap::String*));
// memset the strings to 0 in case a GC run happens while we're within the loop below
memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::Heap::String*));
- for (uint i = 0; i < data->stringTableSize; ++i)
+ for (uint i = 0; i < data->stringTableSize; ++i) {
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
+ runtimeStrings[i]->setMarkBit();
+ }
runtimeRegularExpressions = new QV4::Value[data->regexpTableSize];
// memset the regexps to 0 in case a GC run happens while we're within the loop below
@@ -147,7 +142,14 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
flags |= IR::RegExp::RegExp_IgnoreCase;
if (re->flags & CompiledData::RegExp::RegExp_Multiline)
flags |= IR::RegExp::RegExp_Multiline;
- runtimeRegularExpressions[i] = engine->newRegExpObject(data->stringAt(re->stringIndex), flags);
+ QV4::Heap::RegExpObject *ro = engine->newRegExpObject(data->stringAt(re->stringIndex), flags);
+ runtimeRegularExpressions[i] = ro;
+#if WRITEBARRIER(steele)
+ if (engine->memoryManager->nextGCIsIncremental) {
+ ro->setMarkBit();
+ ro->setGrayBit();
+ }
+#endif
}
if (data->lookupTableSize) {
@@ -174,8 +176,6 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
l->level = -1;
l->index = UINT_MAX;
l->nameIndex = compiledLookups[i].nameIndex;
- if (type == CompiledData::Lookup::Type_IndexedGetter || type == CompiledData::Lookup::Type_IndexedSetter)
- l->engine = engine;
}
}
@@ -331,10 +331,9 @@ void CompilationUnit::finalize(QQmlEnginePrivate *engine)
totalObjectCount = objectCount;
}
-bool CompilationUnit::verifyChecksum(QQmlEngine *engine,
- const ResolvedTypeReferenceMap &dependentTypes) const
+bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHasher) const
{
- if (dependentTypes.isEmpty()) {
+ if (!dependencyHasher) {
for (size_t i = 0; i < sizeof(data->dependencyMD5Checksum); ++i) {
if (data->dependencyMD5Checksum[i] != 0)
return false;
@@ -342,7 +341,7 @@ bool CompilationUnit::verifyChecksum(QQmlEngine *engine,
return true;
}
QCryptographicHash hash(QCryptographicHash::Md5);
- if (!dependentTypes.addToHash(&hash, engine))
+ if (!dependencyHasher(&hash))
return false;
QByteArray checksum = hash.result();
Q_ASSERT(checksum.size() == sizeof(data->dependencyMD5Checksum));
@@ -350,7 +349,7 @@ bool CompilationUnit::verifyChecksum(QQmlEngine *engine,
sizeof(data->dependencyMD5Checksum)) == 0;
}
-bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory, QString *errorString)
+bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString)
{
if (!QQmlFile::isLocalFile(url)) {
*errorString = QStringLiteral("File has to be a local file.");
@@ -360,14 +359,14 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory
const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url);
QScopedPointer<CompilationUnitMapper> cacheFile(new CompilationUnitMapper());
- CompiledData::Unit *mappedUnit = cacheFile->open(cacheFilePath(url), sourcePath, errorString);
+ CompiledData::Unit *mappedUnit = cacheFile->open(cacheFilePath(url), sourceTimeStamp, errorString);
if (!mappedUnit)
return false;
const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr;
QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit);
- if (sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
+ if (data->sourceFileIndex != 0 && sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
*errorString = QStringLiteral("QML source file has moved to a different location.");
return false;
}
@@ -408,27 +407,29 @@ bool CompilationUnit::memoryMapCode(QString *errorString)
#endif // V4_BOOTSTRAP
#if defined(V4_BOOTSTRAP)
-bool CompilationUnit::saveToDisk(const QString &unitUrl, QString *errorString)
+bool CompilationUnit::saveToDisk(const QString &outputFileName, QString *errorString)
#else
bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
#endif
{
errorString->clear();
+#if !defined(V4_BOOTSTRAP)
if (data->sourceTimeStamp == 0) {
*errorString = QStringLiteral("Missing time stamp for source file");
return false;
}
-#if !defined(V4_BOOTSTRAP)
if (!QQmlFile::isLocalFile(unitUrl)) {
*errorString = QStringLiteral("File has to be a local file.");
return false;
}
+ const QString outputFileName = cacheFilePath(unitUrl);
#endif
+#if QT_CONFIG(temporaryfile)
// Foo.qml -> Foo.qmlc
- QSaveFile cacheFile(cacheFilePath(unitUrl));
+ QSaveFile cacheFile(outputFileName);
if (!cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
*errorString = cacheFile.errorString();
return false;
@@ -459,6 +460,10 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
}
return true;
+#else
+ *errorString = QStringLiteral("features.temporaryfile is disabled.");
+ return false;
+#endif // QT_CONFIG(temporaryfile)
}
void CompilationUnit::prepareCodeOffsetsForDiskStorage(Unit *unit)
@@ -480,10 +485,22 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument)
return irDocument->jsGenerator.generateUnit(QV4::Compiler::JSUnitGenerator::GenerateWithoutStringTable);
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = irDocument->javaScriptCompilationUnit;
- QV4::CompiledData::Unit *jsUnit = const_cast<QV4::CompiledData::Unit*>(irDocument->javaScriptCompilationUnit->data);
+ QV4::CompiledData::Unit *jsUnit = const_cast<QV4::CompiledData::Unit*>(compilationUnit->data);
+ auto ensureWritableUnit = [&jsUnit, &compilationUnit]() {
+ if (jsUnit == compilationUnit->data) {
+ char *unitCopy = (char*)malloc(jsUnit->unitSize);
+ memcpy(unitCopy, jsUnit, jsUnit->unitSize);
+ jsUnit = reinterpret_cast<QV4::CompiledData::Unit*>(unitCopy);
+ }
+ };
QV4::Compiler::StringTableGenerator &stringTable = irDocument->jsGenerator.stringTable;
+ if (jsUnit->sourceFileIndex == quint32(0) || jsUnit->stringAt(jsUnit->sourceFileIndex) != irDocument->jsModule.fileName) {
+ ensureWritableUnit();
+ jsUnit->sourceFileIndex = stringTable.registerString(irDocument->jsModule.fileName);
+ }
+
// Collect signals that have had a change in signature (from onClicked to onClicked(mouse) for example)
// and now need fixing in the QV4::CompiledData. Also register strings at the same time, to finalize
// the string table.
@@ -546,6 +563,7 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument)
}
if (!signalParameterNameTable.isEmpty()) {
+ ensureWritableUnit();
Q_ASSERT(jsUnit != compilationUnit->data);
const uint signalParameterTableSize = signalParameterNameTable.count() * sizeof(quint32);
uint newSize = jsUnit->unitSize + signalParameterTableSize;
@@ -764,7 +782,7 @@ void Unit::generateChecksum()
#ifndef V4_BOOTSTRAP
QCryptographicHash hash(QCryptographicHash::Md5);
- const int checksummableDataOffset = qOffsetOf(QV4::CompiledData::Unit, md5Checksum) + sizeof(md5Checksum);
+ const int checksummableDataOffset = offsetof(QV4::CompiledData::Unit, md5Checksum) + sizeof(md5Checksum);
const char *dataPtr = reinterpret_cast<const char *>(this) + checksummableDataOffset;
hash.addData(dataPtr, unitSize - checksummableDataOffset);