Avoid an extra stat() on the source .qml file when loading cache
For timestamp comparison it is not necessary to create another QFileInfo() object and call exists() and lastModified(), when we can pass that information through from the type loader. Change-Id: I225cd36e672f1f390bddb4e6ebfafa3fc1269795 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
9b70716374
commit
5bd11b5a8c
|
@ -59,7 +59,7 @@ CompilationUnitMapper::~CompilationUnitMapper()
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, const QString &sourcePath, QString *errorString)
|
bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString)
|
||||||
{
|
{
|
||||||
if (strncmp(header->magic, CompiledData::magic_str, sizeof(header->magic))) {
|
if (strncmp(header->magic, CompiledData::magic_str, sizeof(header->magic))) {
|
||||||
*errorString = QStringLiteral("Magic bytes in the header do not match");
|
*errorString = QStringLiteral("Magic bytes in the header do not match");
|
||||||
|
@ -77,11 +77,6 @@ bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->sourceTimeStamp) {
|
if (header->sourceTimeStamp) {
|
||||||
QFileInfo sourceCode(sourcePath);
|
|
||||||
QDateTime sourceTimeStamp;
|
|
||||||
if (sourceCode.exists())
|
|
||||||
sourceTimeStamp = sourceCode.lastModified();
|
|
||||||
|
|
||||||
// Files from the resource system do not have any time stamps, so fall back to the application
|
// Files from the resource system do not have any time stamps, so fall back to the application
|
||||||
// executable.
|
// executable.
|
||||||
if (!sourceTimeStamp.isValid())
|
if (!sourceTimeStamp.isValid())
|
||||||
|
|
|
@ -68,11 +68,11 @@ public:
|
||||||
CompilationUnitMapper();
|
CompilationUnitMapper();
|
||||||
~CompilationUnitMapper();
|
~CompilationUnitMapper();
|
||||||
|
|
||||||
CompiledData::Unit *open(const QString &cacheFilePath, const QString &sourcePath, QString *errorString);
|
CompiledData::Unit *open(const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool verifyHeader(const QV4::CompiledData::Unit *header, const QString &sourcePath, QString *errorString);
|
static bool verifyHeader(const QV4::CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString);
|
||||||
|
|
||||||
#if defined(Q_OS_UNIX)
|
#if defined(Q_OS_UNIX)
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <private/qcore_unix_p.h>
|
#include <private/qcore_unix_p.h>
|
||||||
#include <private/qdeferredcleanup_p.h>
|
#include <private/qdeferredcleanup_p.h>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
#include "qv4compileddata_p.h"
|
#include "qv4compileddata_p.h"
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace QV4;
|
using namespace QV4;
|
||||||
|
|
||||||
CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString)
|
CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QDateTime &sourceTimeStamp, QString *errorString)
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!verifyHeader(&header, sourcePath, errorString))
|
if (!verifyHeader(&header, sourceTimeStamp, errorString))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Data structure and qt version matched, so now we can access the rest of the file safely.
|
// Data structure and qt version matched, so now we can access the rest of the file safely.
|
||||||
|
|
|
@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace QV4;
|
using namespace QV4;
|
||||||
|
|
||||||
CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString)
|
CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QDateTime &sourceTimeStamp, QString *errorString)
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!verifyHeader(&header, sourcePath, errorString))
|
if (!verifyHeader(&header, sourceTimeStamp, errorString))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const uint mappingFlags = header.flags & QV4::CompiledData::Unit::ContainsMachineCode
|
const uint mappingFlags = header.flags & QV4::CompiledData::Unit::ContainsMachineCode
|
||||||
|
|
|
@ -343,7 +343,7 @@ bool CompilationUnit::verifyChecksum(QQmlEngine *engine,
|
||||||
sizeof(data->dependencyMD5Checksum)) == 0;
|
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)) {
|
if (!QQmlFile::isLocalFile(url)) {
|
||||||
*errorString = QStringLiteral("File has to be a local file.");
|
*errorString = QStringLiteral("File has to be a local file.");
|
||||||
|
@ -353,7 +353,7 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory
|
||||||
const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url);
|
const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url);
|
||||||
QScopedPointer<CompilationUnitMapper> cacheFile(new CompilationUnitMapper());
|
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)
|
if (!mappedUnit)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -899,7 +899,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public
|
||||||
|
|
||||||
void destroy() Q_DECL_OVERRIDE;
|
void destroy() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
bool loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory, QString *errorString);
|
bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
|
virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
|
||||||
|
|
|
@ -425,7 +425,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
|
||||||
}
|
}
|
||||||
unit.indexOfRootFunction = -1;
|
unit.indexOfRootFunction = -1;
|
||||||
unit.sourceFileIndex = getStringId(irModule->fileName);
|
unit.sourceFileIndex = getStringId(irModule->fileName);
|
||||||
unit.sourceTimeStamp = irModule->sourceTimeStamp;
|
unit.sourceTimeStamp = irModule->sourceTimeStamp.isValid() ? irModule->sourceTimeStamp.toMSecsSinceEpoch() : 0;
|
||||||
unit.nImports = 0;
|
unit.nImports = 0;
|
||||||
unit.offsetToImports = 0;
|
unit.offsetToImports = 0;
|
||||||
unit.nObjects = 0;
|
unit.nObjects = 0;
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include <QtCore/QBitArray>
|
#include <QtCore/QBitArray>
|
||||||
#include <QtCore/qurl.h>
|
#include <QtCore/qurl.h>
|
||||||
#include <QtCore/QVarLengthArray>
|
#include <QtCore/QVarLengthArray>
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
#include <qglobal.h>
|
#include <qglobal.h>
|
||||||
|
|
||||||
#if defined(CONST) && defined(Q_OS_WIN)
|
#if defined(CONST) && defined(Q_OS_WIN)
|
||||||
|
@ -942,7 +943,7 @@ struct Q_QML_PRIVATE_EXPORT Module {
|
||||||
QVector<Function *> functions;
|
QVector<Function *> functions;
|
||||||
Function *rootFunction;
|
Function *rootFunction;
|
||||||
QString fileName;
|
QString fileName;
|
||||||
qint64 sourceTimeStamp;
|
QDateTime sourceTimeStamp;
|
||||||
bool isQmlModule; // implies rootFunction is always 0
|
bool isQmlModule; // implies rootFunction is always 0
|
||||||
uint unitFlags; // flags merged into CompiledData::Unit::flags
|
uint unitFlags; // flags merged into CompiledData::Unit::flags
|
||||||
#ifdef QT_NO_QML_DEBUGGER
|
#ifdef QT_NO_QML_DEBUGGER
|
||||||
|
@ -955,7 +956,6 @@ struct Q_QML_PRIVATE_EXPORT Module {
|
||||||
|
|
||||||
Module(bool debugMode)
|
Module(bool debugMode)
|
||||||
: rootFunction(0)
|
: rootFunction(0)
|
||||||
, sourceTimeStamp(0)
|
|
||||||
, isQmlModule(false)
|
, isQmlModule(false)
|
||||||
, unitFlags(0)
|
, unitFlags(0)
|
||||||
#ifndef QT_NO_QML_DEBUGGER
|
#ifndef QT_NO_QML_DEBUGGER
|
||||||
|
|
|
@ -2065,7 +2065,7 @@ bool QQmlTypeData::tryLoadFromDiskCache()
|
||||||
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
|
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
if (!unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) {
|
if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), v4->iselFactory.data(), &error)) {
|
||||||
qCDebug(DBG_DISK_CACHE) << "Error loading" << url().toString() << "from disk cache:" << error;
|
qCDebug(DBG_DISK_CACHE) << "Error loading" << url().toString() << "from disk cache:" << error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2522,7 +2522,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach
|
||||||
QString errorString;
|
QString errorString;
|
||||||
if (m_compiledData->saveToDisk(url(), &errorString)) {
|
if (m_compiledData->saveToDisk(url(), &errorString)) {
|
||||||
QString error;
|
QString error;
|
||||||
if (!m_compiledData->loadFromDisk(url(), enginePrivate->v4engine()->iselFactory.data(), &error)) {
|
if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), enginePrivate->v4engine()->iselFactory.data(), &error)) {
|
||||||
// ignore error, keep using the in-memory compilation unit.
|
// ignore error, keep using the in-memory compilation unit.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2882,7 +2882,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
|
||||||
if (!disableDiskCache() || forceDiskCache()) {
|
if (!disableDiskCache() || forceDiskCache()) {
|
||||||
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
|
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
|
||||||
QString error;
|
QString error;
|
||||||
if (unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) {
|
if (unit->loadFromDisk(url(), data.sourceTimeStamp(), v4->iselFactory.data(), &error)) {
|
||||||
initializeFromCompilationUnit(unit);
|
initializeFromCompilationUnit(unit);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3094,18 +3094,18 @@ QString QQmlDataBlob::SourceCodeData::readAll(QString *error) const
|
||||||
return QString::fromUtf8(data);
|
return QString::fromUtf8(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QQmlDataBlob::SourceCodeData::sourceTimeStamp() const
|
QDateTime QQmlDataBlob::SourceCodeData::sourceTimeStamp() const
|
||||||
{
|
{
|
||||||
if (!inlineSourceCode.isEmpty())
|
if (!inlineSourceCode.isEmpty())
|
||||||
return 0;
|
return QDateTime();
|
||||||
|
|
||||||
QDateTime timeStamp = fileInfo.lastModified();
|
QDateTime timeStamp = fileInfo.lastModified();
|
||||||
if (timeStamp.isValid())
|
if (timeStamp.isValid())
|
||||||
return timeStamp.toMSecsSinceEpoch();
|
return timeStamp;
|
||||||
|
|
||||||
static qint64 appTimeStamp = 0;
|
static QDateTime appTimeStamp;
|
||||||
if (appTimeStamp == 0)
|
if (!appTimeStamp.isValid())
|
||||||
appTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified().toMSecsSinceEpoch();
|
appTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified();
|
||||||
return appTimeStamp;
|
return appTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ public:
|
||||||
class SourceCodeData {
|
class SourceCodeData {
|
||||||
public:
|
public:
|
||||||
QString readAll(QString *error) const;
|
QString readAll(QString *error) const;
|
||||||
qint64 sourceTimeStamp() const;
|
QDateTime sourceTimeStamp() const;
|
||||||
bool exists() const;
|
bool exists() const;
|
||||||
private:
|
private:
|
||||||
friend class QQmlDataBlob;
|
friend class QQmlDataBlob;
|
||||||
|
|
|
@ -174,7 +174,7 @@ struct TestCompiler
|
||||||
{
|
{
|
||||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
||||||
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
|
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
|
||||||
return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), v4->iselFactory.data(), &lastErrorString);
|
return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), v4->iselFactory.data(), &lastErrorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeMapping()
|
void closeMapping()
|
||||||
|
|
|
@ -159,7 +159,7 @@ int main(int argc, char *argv[])
|
||||||
if (cache && QFile::exists(fn + QLatin1Char('c'))) {
|
if (cache && QFile::exists(fn + QLatin1Char('c'))) {
|
||||||
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = iSelFactory->createUnitForLoading();
|
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = iSelFactory->createUnitForLoading();
|
||||||
QString error;
|
QString error;
|
||||||
if (unit->loadFromDisk(QUrl::fromLocalFile(fn), iSelFactory, &error)) {
|
if (unit->loadFromDisk(QUrl::fromLocalFile(fn), QFileInfo(fn).lastModified(), iSelFactory, &error)) {
|
||||||
script.reset(new QV4::Script(&vm, nullptr, unit));
|
script.reset(new QV4::Script(&vm, nullptr, unit));
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl;
|
std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl;
|
||||||
|
|
Loading…
Reference in New Issue