diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-29 13:12:17 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-30 08:09:13 +0000 |
commit | 260a24800dcdf3fa6ad4a8d0abaa0c8b23aae511 (patch) | |
tree | 7382fd5a6f00ffd05ae45a86e803d7454d070ad3 /src | |
parent | e931b123e90ca0162e112148de5cd35f149e4841 (diff) |
Remove the codeRefs in the Moth::CompilationUnit
There's no point in allocating that vector of byte arrays,
if we can directly embed those int the CompiledData and
reference it from there.
Change-Id: I8fc92b1efaca5a9646f40fc84a2ac4191c8f3444
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilationunit_moth.cpp | 72 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilationunit_moth_p.h | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 27 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 20 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 2 |
7 files changed, 17 insertions, 125 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 7643212ea1..ea3f194852 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2731,11 +2731,6 @@ QList<QQmlJS::DiagnosticMessage> Codegen::errors() const QQmlRefPointer<CompiledData::CompilationUnit> Codegen::generateCompilationUnit(bool generateUnitData) { Moth::CompilationUnit *compilationUnit = new Moth::CompilationUnit; - compilationUnit->codeRefs.resize(_module->functions.size()); - int i = 0; - for (Context *irFunction : qAsConst(_module->functions)) - compilationUnit->codeRefs[i++] = irFunction->code; - if (generateUnitData) compilationUnit->data = jsUnitGenerator->generateUnit(); diff --git a/src/qml/compiler/qv4compilationunit_moth.cpp b/src/qml/compiler/qv4compilationunit_moth.cpp index c53dcc91b0..fa9a3f82fc 100644 --- a/src/qml/compiler/qv4compilationunit_moth.cpp +++ b/src/qml/compiler/qv4compilationunit_moth.cpp @@ -55,79 +55,9 @@ CompilationUnit::~CompilationUnit() void CompilationUnit::linkBackendToEngine(QV4::ExecutionEngine *engine) { runtimeFunctions.resize(data->functionTableSize); - runtimeFunctions.fill(0); for (int i = 0 ;i < runtimeFunctions.size(); ++i) { const QV4::CompiledData::Function *compiledFunction = data->functionAt(i); - - QV4::Function *runtimeFunction = new QV4::Function(engine, this, compiledFunction, &VME::exec); - runtimeFunction->codeData = reinterpret_cast<const uchar *>(codeRefs.at(i).constData()); - runtimeFunctions[i] = runtimeFunction; - } -} - -bool CompilationUnit::memoryMapCode(QString *errorString) -{ - Q_UNUSED(errorString); - codeRefs.resize(data->functionTableSize); - - const char *basePtr = reinterpret_cast<const char *>(data); - - for (uint i = 0; i < data->functionTableSize; ++i) { - const CompiledData::Function *compiledFunction = data->functionAt(i); - const char *codePtr = const_cast<const char *>(reinterpret_cast<const char *>(basePtr + compiledFunction->codeOffset)); - QByteArray code = QByteArray::fromRawData(codePtr, compiledFunction->codeSize); - codeRefs[i] = code; + runtimeFunctions[i] = new QV4::Function(engine, this, compiledFunction, &VME::exec); } - - return true; } - #endif // V4_BOOTSTRAP - -void CompilationUnit::prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit) -{ - const int codeAlignment = 16; - quint64 offset = WTF::roundUpToMultipleOf(codeAlignment, unit->unitSize); - Q_ASSERT(int(unit->functionTableSize) == codeRefs.size()); - for (int i = 0; i < codeRefs.size(); ++i) { - CompiledData::Function *compiledFunction = const_cast<CompiledData::Function *>(unit->functionAt(i)); - compiledFunction->codeOffset = offset; - compiledFunction->codeSize = codeRefs.at(i).size(); - offset = WTF::roundUpToMultipleOf(codeAlignment, offset + compiledFunction->codeSize); - } -} - -bool CompilationUnit::saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString) -{ - Q_ASSERT(device->pos() == unit->unitSize); - Q_ASSERT(device->atEnd()); - Q_ASSERT(int(unit->functionTableSize) == codeRefs.size()); - - QByteArray padding; - - for (int i = 0; i < codeRefs.size(); ++i) { - const CompiledData::Function *compiledFunction = unit->functionAt(i); - - if (device->pos() > qint64(compiledFunction->codeOffset)) { - *errorString = QStringLiteral("Invalid state of cache file to write."); - return false; - } - - const quint64 paddingSize = compiledFunction->codeOffset - device->pos(); - padding.fill(0, paddingSize); - qint64 written = device->write(padding); - if (written != padding.size()) { - *errorString = device->errorString(); - return false; - } - - QByteArray code = codeRefs.at(i); - - written = device->write(code.constData(), compiledFunction->codeSize); - if (written != qint64(compiledFunction->codeSize)) { - *errorString = device->errorString(); - return false; - } - } - return true; -} diff --git a/src/qml/compiler/qv4compilationunit_moth_p.h b/src/qml/compiler/qv4compilationunit_moth_p.h index a0d1b7ca17..80e97e0d74 100644 --- a/src/qml/compiler/qv4compilationunit_moth_p.h +++ b/src/qml/compiler/qv4compilationunit_moth_p.h @@ -68,13 +68,7 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit virtual ~CompilationUnit(); #if !defined(V4_BOOTSTRAP) void linkBackendToEngine(QV4::ExecutionEngine *engine) Q_DECL_OVERRIDE; - bool memoryMapCode(QString *errorString) Q_DECL_OVERRIDE; #endif - void prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit) Q_DECL_OVERRIDE; - bool saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString) Q_DECL_OVERRIDE; - - QVector<QByteArray> codeRefs; - }; } diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index fa0c222397..3f6f9f12b6 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -387,21 +387,12 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeS } } - if (!memoryMapCode(errorString)) - return false; - dataPtrChange.commit(); free(const_cast<Unit*>(oldDataPtr)); backingFile.reset(cacheFile.take()); return true; } -bool CompilationUnit::memoryMapCode(QString *errorString) -{ - *errorString = QStringLiteral("Missing code mapping backend"); - return false; -} - #endif // V4_BOOTSTRAP #if defined(V4_BOOTSTRAP) @@ -441,17 +432,12 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString) memcpy(&unitPtr, &dataPtr, sizeof(unitPtr)); unitPtr->flags |= Unit::StaticData; - prepareCodeOffsetsForDiskStorage(unitPtr); - qint64 headerWritten = cacheFile.write(modifiedUnit); if (headerWritten != modifiedUnit.size()) { *errorString = cacheFile.errorString(); return false; } - if (!saveCodeToDisk(&cacheFile, unitPtr, errorString)) - return false; - if (!cacheFile.commit()) { *errorString = cacheFile.errorString(); return false; @@ -465,19 +451,6 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString) #endif // QT_CONFIG(temporaryfile) } -void CompilationUnit::prepareCodeOffsetsForDiskStorage(Unit *unit) -{ - Q_UNUSED(unit); -} - -bool CompilationUnit::saveCodeToDisk(QIODevice *device, const Unit *unit, QString *errorString) -{ - Q_UNUSED(device); - Q_UNUSED(unit); - *errorString = QStringLiteral("Saving code to disk is not supported in this configuration"); - return false; -} - Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument) { if (!irDocument->javaScriptCompilationUnit->data) diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 6c8e2bc121..d1567611dc 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE // Bump this whenever the compiler data structures change in an incompatible way. -#define QV4_DATA_STRUCTURE_VERSION 0x14 +#define QV4_DATA_STRUCTURE_VERSION 0x15 class QIODevice; class QQmlPropertyCache; @@ -212,10 +212,9 @@ struct Function CanUseSimpleCall = 0x20 }; - // Absolute offset into file where the code for this function is located. Only used when the function - // is serialized. - quint64_le codeOffset; - quint64_le codeSize; + // Absolute offset into file where the code for this function is located. + quint32_le codeOffset; + quint32_le codeSize; quint32_le nameIndex; quint32_le nFormals; @@ -257,12 +256,14 @@ struct Function const quint32_le *formalsEnd() const { return formalsTable() + nFormals; } // --- + const uchar *code() const { return reinterpret_cast<const uchar *>(this) + codeOffset; } + inline bool hasQmlDependencies() const { return nDependingIdObjects > 0 || nDependingContextProperties > 0 || nDependingScopeProperties > 0; } - static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies) { + static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies, int codeSize) { int trailingData = (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies + 2 * nPropertyDependencies)*sizeof (quint32) + nLines*sizeof(CodeOffsetToLine); - return align(align(sizeof(Function)) + size_t(trailingData)); + return align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize); } static size_t align(size_t a) { @@ -958,7 +959,6 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public protected: virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0; - virtual bool memoryMapCode(QString *errorString); #endif // V4_BOOTSTRAP public: @@ -967,10 +967,6 @@ public: #else bool saveToDisk(const QUrl &unitUrl, QString *errorString); #endif - -protected: - virtual void prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit); - virtual bool saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString); }; #ifndef V4_BOOTSTRAP diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index aaa06efa8c..b726d75c8d 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -349,8 +349,8 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte function->location.line = irFunction->line; function->location.column = irFunction->column; - function->codeOffset = 0; - function->codeSize = 0; + function->codeOffset = currentOffset; + function->codeSize = irFunction->code.size(); // write formals quint32_le *formals = (quint32_le *)(f + function->formalsOffset); @@ -383,6 +383,9 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte *writtenDeps++ = property.key(); // property index *writtenDeps++ = property.value(); // notify index } + + // write byte code + memcpy(f + function->codeOffset, irFunction->code.constData(), irFunction->code.size()); } QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Compiler::JSUnitGenerator::GeneratorOption option, quint32_le *functionOffsets, uint *jsClassDataOffset) @@ -435,7 +438,8 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp const int qmlIdDepsCount = f->idObjectDependencies.count(); const int qmlPropertyDepsCount = f->scopeObjectPropertyDependencies.count() + f->contextObjectPropertyDependencies.count(); - nextOffset += QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->lineNumberMapping.size(), f->nestedContexts.size(), qmlIdDepsCount, qmlPropertyDepsCount); + nextOffset += QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->lineNumberMapping.size(), f->nestedContexts.size(), + qmlIdDepsCount, qmlPropertyDepsCount, f->code.size()); } if (option == GenerateWithStringTable) { diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 681a5ba1cf..594810e498 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -55,7 +55,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, : compiledFunction(function) , compilationUnit(unit) , code(codePtr) - , codeData(0) + , codeData(function->code()) , hasQmlDependencies(function->hasQmlDependencies()) { Q_UNUSED(engine); |