diff options
Diffstat (limited to 'src/qml/jit/qv4assembler.cpp')
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 3da1aaa010..08e4f0a8c0 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -79,14 +79,70 @@ void CompilationUnit::linkBackendToEngine(ExecutionEngine *engine) } } -QV4::ExecutableAllocator::ChunkOfPages *CompilationUnit::chunkForFunction(int functionIndex) +void CompilationUnit::prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit) { - if (functionIndex < 0 || functionIndex >= codeRefs.count()) - return 0; - JSC::ExecutableMemoryHandle *handle = codeRefs[functionIndex].executableMemory(); - if (!handle) - return 0; - return handle->chunk(); + 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; + } + + const void *undecoratedCodePtr = codeRefs.at(i).code().dataLocation(); + written = device->write(reinterpret_cast<const char *>(undecoratedCodePtr), compiledFunction->codeSize); + if (written != qint64(compiledFunction->codeSize)) { + *errorString = device->errorString(); + return false; + } + } + return true; +} + +bool CompilationUnit::memoryMapCode(QString *errorString) +{ + Q_UNUSED(errorString); + Q_ASSERT(codeRefs.isEmpty()); + codeRefs.reserve(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); + void *codePtr = const_cast<void *>(reinterpret_cast<const void *>(basePtr + compiledFunction->codeOffset)); + JSC::MacroAssemblerCodeRef codeRef = JSC::MacroAssemblerCodeRef::createSelfManagedCodeRef(JSC::MacroAssemblerCodePtr(codePtr)); + JSC::ExecutableAllocator::makeExecutable(codePtr, compiledFunction->codeSize); + codeRefs.append(codeRef); + } + + return true; } const Assembler::VoidType Assembler::Void; |