From 40e8109ceff8519920245a01d82357dc57639f46 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 22 Jun 2017 09:44:55 +0200 Subject: Don't use the ISel's anymore Move the code that generates the CompilationUnit over to Codegen, and don't use the ISel's at all anymore when compiling JS/QML. Change-Id: Iba89082c386c3d3fd58ac25a4651c5d39178cc5c Reviewed-by: Erik Verbruggen --- src/qml/compiler/qqmltypecompiler.cpp | 7 ++---- src/qml/compiler/qv4codegen.cpp | 25 ++++++++++++++++++++++ src/qml/compiler/qv4codegen_p.h | 13 ++++++++--- src/qml/compiler/qv4compileddata.cpp | 4 ++-- src/qml/compiler/qv4compileddata_p.h | 2 +- src/qml/compiler/qv4compiler.cpp | 1 - src/qml/jsruntime/qv4engine.cpp | 38 +-------------------------------- src/qml/jsruntime/qv4engine_p.h | 4 +--- src/qml/jsruntime/qv4functionobject.cpp | 5 +---- src/qml/jsruntime/qv4global_p.h | 9 ++++++++ src/qml/jsruntime/qv4object.cpp | 2 -- src/qml/jsruntime/qv4object_p.h | 1 + src/qml/jsruntime/qv4regexpobject.cpp | 2 -- src/qml/jsruntime/qv4regexpobject_p.h | 1 - src/qml/jsruntime/qv4script.cpp | 13 +++++------ src/qml/jsruntime/qv4script_p.h | 2 +- src/qml/qml/qqmltypeloader.cpp | 15 ++++++------- src/qml/qml/qqmltypewrapper_p.h | 1 + src/qml/qml/qqmlvaluetypewrapper_p.h | 1 + 19 files changed, 68 insertions(+), 78 deletions(-) (limited to 'src/qml') diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 18a1cbdc93..63a240e575 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -142,6 +142,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() QmlIR::JSCodeGen v4CodeGenerator(typeData->finalUrlString(), document->code, &document->jsGenerator, &document->jsModule, &document->jsParserEngine, document->program, typeNameCache, &document->jsGenerator.stringTable); v4CodeGenerator.setUseFastLookups(false); + // ### v4CodeGenerator.setUseTypeInference(true); QQmlJSCodeGenerator jsCodeGen(this, &v4CodeGenerator); if (!jsCodeGen.generateCodeForComponents()) return nullptr; @@ -149,11 +150,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() QQmlJavaScriptBindingExpressionSimplificationPass pass(document->objects, &document->jsModule, &document->jsGenerator); pass.reduceTranslationBindings(); - QV4::ExecutionEngine *v4 = engine->v4engine(); - QScopedPointer isel(v4->iselFactory->create(engine, v4->executableAllocator, &document->jsModule, &document->jsGenerator)); - isel->setUseFastLookups(false); - isel->setUseTypeInference(true); - document->javaScriptCompilationUnit = isel->compile(/*generated unit data*/false); + document->javaScriptCompilationUnit = v4CodeGenerator.generateCompilationUnit(/*generated unit data*/false); } // Generate QML compiled type data structures diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 76ff7b7b4a..8b08e926ad 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #ifndef V4_BOOTSTRAP #include @@ -3205,6 +3206,30 @@ QList Codegen::errors() const return _errors; } +QQmlRefPointer Codegen::generateCompilationUnit(bool generateUnitData) +{ + Moth::CompilationUnit *compilationUnit = new Moth::CompilationUnit; + compilationUnit->codeRefs.resize(_module->functions.size()); + int i = 0; + for (IR::Function *irFunction : qAsConst(_module->functions)) + compilationUnit->codeRefs[i++] = irFunction->code; + + if (generateUnitData) + compilationUnit->data = jsUnitGenerator->generateUnit(); + + QQmlRefPointer unit; + unit.adopt(compilationUnit); + return unit; +} + +QQmlRefPointer Codegen::createUnitForLoading() +{ + QQmlRefPointer result; + result.adopt(new Moth::CompilationUnit); + return result; +} + + #ifndef V4_BOOTSTRAP QList Codegen::qmlErrors() const diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index 9fd2ed637b..9f13bee4cf 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -56,6 +56,8 @@ #include #include #include +#include +#include #include #include #ifndef V4_BOOTSTRAP @@ -71,12 +73,13 @@ struct ControlFlow; struct ControlFlowCatch; struct ControlFlowFinally; -namespace Compiler { -struct JSUnitGenerator; -} namespace Moth { struct Instruction; } + +namespace CompiledData { +struct CompilationUnit; +} } namespace QQmlJS { @@ -629,6 +632,10 @@ public: void handleTryCatch(AST::TryStatement *ast); void handleTryFinally(AST::TryStatement *ast); + + QQmlRefPointer generateCompilationUnit(bool generateUnitData = true); + static QQmlRefPointer createUnitForLoading(); + protected: friend struct QV4::ControlFlow; friend struct QV4::ControlFlowCatch; diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 68063c2f71..b8e2ba6377 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -341,7 +341,7 @@ bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHashe sizeof(data->dependencyMD5Checksum)) == 0; } -bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString) +bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString) { if (!QQmlFile::isLocalFile(url)) { *errorString = QStringLiteral("File has to be a local file."); @@ -374,7 +374,7 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeS { const QString foundCodeGenerator = stringAt(data->codeGeneratorIndex); - const QString expectedCodeGenerator = iselFactory->codeGeneratorName; + const QString expectedCodeGenerator = QStringLiteral("moth"); // ### if (foundCodeGenerator != expectedCodeGenerator) { *errorString = QString::fromUtf8("Code generator mismatch. Found code generated by %1 but expected %2").arg(foundCodeGenerator).arg(expectedCodeGenerator); return false; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index f4ba257cf5..8d2f113d63 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -901,7 +901,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public void destroy() Q_DECL_OVERRIDE; - bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString); + bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString); protected: virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0; diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 19f3d5b2ce..619993b874 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -39,7 +39,6 @@ #include #include -#include #include #include #include diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 019936767a..568413bc57 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -81,14 +81,6 @@ #include #include -#ifdef V4_ENABLE_JIT -#include "qv4isel_masm_p.h" -#endif // V4_ENABLE_JIT - -#if QT_CONFIG(qml_interpreter) -#include "qv4isel_moth_p.h" -#endif - #if USE(PTHREADS) # include #if !defined(Q_OS_INTEGRITY) @@ -129,7 +121,7 @@ QQmlEngine *ExecutionEngine::qmlEngine() const qint32 ExecutionEngine::maxCallDepth = -1; -ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) +ExecutionEngine::ExecutionEngine() : executableAllocator(new QV4::ExecutableAllocator) , regExpAllocator(new QV4::ExecutableAllocator) , bumperPointerAllocator(new WTF::BumpPointerAllocator) @@ -158,34 +150,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) } Q_ASSERT(maxCallDepth > 0); - if (!factory) { -#if QT_CONFIG(qml_interpreter) - bool jitDisabled = true; - -#ifdef V4_ENABLE_JIT - static const bool forceMoth = !qEnvironmentVariableIsEmpty("QV4_FORCE_INTERPRETER") || - !OSAllocator::canAllocateExecutableMemory(); - if (forceMoth) { - factory = new Moth::ISelFactory; - } else { - factory = new JIT::ISelFactory<>; - jitDisabled = false; - } -#else // !V4_ENABLE_JIT - factory = new Moth::ISelFactory; -#endif // V4_ENABLE_JIT - - if (jitDisabled) { - qWarning("JIT is disabled for QML. Property bindings and animations will be " - "very slow. Visit https://wiki.qt.io/V4 to learn about possible " - "solutions for your platform."); - } -#else - factory = new JIT::ISelFactory<>; -#endif - } - iselFactory.reset(factory); - // reserve space for the JS stack // we allow it to grow to a bit more than JSStackLimit, as we can overshoot due to ScopedValues // allocated outside of JIT'ed methods. diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 16a043dda5..5929d3df11 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -51,7 +51,6 @@ // #include "qv4global_p.h" -#include "private/qv4isel_p.h" #include "qv4managed_p.h" #include "qv4context_p.h" #include @@ -99,7 +98,6 @@ private: public: ExecutableAllocator *executableAllocator; ExecutableAllocator *regExpAllocator; - QScopedPointer iselFactory; WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine. @@ -339,7 +337,7 @@ public: // bookkeeping. MultiplyWrappedQObjectMap *m_multiplyWrappedQObjects; - ExecutionEngine(EvalISelFactory *iselFactory = 0); + ExecutionEngine(); ~ExecutionEngine(); #ifdef QT_NO_QML_DEBUGGER diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 2ca4584fc1..17f92f5f7c 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -38,8 +38,6 @@ ****************************************************************************/ #include "qv4object_p.h" -#include "qv4jsir_p.h" -#include "qv4isel_p.h" #include "qv4objectproto_p.h" #include "qv4stringobject_p.h" #include "qv4function_p.h" @@ -225,8 +223,7 @@ void FunctionCtor::construct(const Managed *that, Scope &scope, CallData *callDa QQmlJS::RuntimeCodegen cg(scope.engine, &jsGenerator, f->strictMode()); cg.generateFromFunctionExpression(QString(), function, fe, &module); - QScopedPointer isel(scope.engine->iselFactory->create(QQmlEnginePrivate::get(scope.engine), scope.engine->executableAllocator, &module, &jsGenerator)); - QQmlRefPointer compilationUnit = isel->compile(); + QQmlRefPointer compilationUnit = cg.generateCompilationUnit(); Function *vmf = compilationUnit->linkToEngine(scope.engine); ExecutionContext *global = scope.engine->rootContext(); diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 15148f6bc7..b5b077124d 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -184,7 +184,16 @@ namespace Heap { template struct Pointer; } +namespace IR { +struct Function; +struct Module; +} +namespace Compiler { +struct JSUnitGenerator; +} + class MemoryManager; +class ExecutableAllocator; struct String; struct Object; struct ObjectPrototype; diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 94d5a74fe5..963a3fe454 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -38,8 +38,6 @@ ****************************************************************************/ #include "qv4object_p.h" -#include "qv4jsir_p.h" -#include "qv4isel_p.h" #include "qv4objectproto_p.h" #include "qv4stringobject_p.h" #include "qv4argumentsobject_p.h" diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 066a93cc61..f05b84d598 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -57,6 +57,7 @@ #include "qv4scopedvalue_p.h" #include "qv4value_p.h" #include "qv4internalclass_p.h" +#include "qv4string_p.h" QT_BEGIN_NAMESPACE diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 735951e085..3b1e680831 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -38,8 +38,6 @@ ****************************************************************************/ #include "qv4regexpobject_p.h" -#include "qv4jsir_p.h" -#include "qv4isel_p.h" #include "qv4objectproto_p.h" #include "qv4regexp_p.h" #include "qv4stringobject_p.h" diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index 6f54a4ab92..6356ad45f3 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -56,7 +56,6 @@ #include "qv4functionobject_p.h" #include "qv4string_p.h" #include "qv4codegen_p.h" -#include "qv4isel_p.h" #include "qv4managed_p.h" #include "qv4property_p.h" #include "qv4objectiterator_p.h" diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index cc8dfb30c2..53adb09273 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -134,10 +134,7 @@ void Script::parse() if (v4->hasException) return; - QScopedPointer isel(v4->iselFactory->create(QQmlEnginePrivate::get(v4), v4->executableAllocator, &module, &jsGenerator)); - if (inheritContext) - isel->setUseFastLookups(false); - compilationUnit = isel->compile(); + compilationUnit = cg.generateCompilationUnit(); vmFunction = compilationUnit->linkToEngine(v4); } @@ -188,7 +185,9 @@ Function *Script::function() return vmFunction; } -QQmlRefPointer Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList *reportedErrors, QQmlJS::Directives *directivesCollector) +QQmlRefPointer Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, + const QUrl &url, const QString &source, QList *reportedErrors, + QQmlJS::Directives *directivesCollector) { using namespace QQmlJS; using namespace QQmlJS::AST; @@ -242,9 +241,7 @@ QQmlRefPointer Script::precompile(IR::Module return 0; } - QScopedPointer isel(engine->iselFactory->create(QQmlEnginePrivate::get(engine), engine->executableAllocator, module, unitGenerator)); - isel->setUseFastLookups(false); - return isel->compile(/*generate unit data*/false); + return cg.generateCompilationUnit(/*generate unit data*/false); } QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext) diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index 4ebe2dd609..25a9dbe3a1 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -139,7 +139,7 @@ struct Q_QML_EXPORT Script { Function *function(); - static QQmlRefPointer precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, + static QQmlRefPointer precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, const QUrl &url, const QString &source, QList *reportedErrors = 0, QQmlJS::Directives *directivesCollector = 0); static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext); diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index e4293596d8..5917d96293 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -2074,10 +2075,10 @@ bool QQmlTypeData::tryLoadFromDiskCache() if (!v4) return false; - QQmlRefPointer unit = v4->iselFactory->createUnitForLoading(); + QQmlRefPointer unit = QQmlJS::Codegen::createUnitForLoading(); { QString error; - if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), v4->iselFactory.data(), &error)) { + if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) { qCDebug(DBG_DISK_CACHE) << "Error loading" << url().toString() << "from disk cache:" << error; return false; } @@ -2558,7 +2559,7 @@ void QQmlTypeData::compile(const QQmlRefPointer &typeNameCach QString errorString; if (m_compiledData->saveToDisk(url(), &errorString)) { QString error; - if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), enginePrivate->v4engine()->iselFactory.data(), &error)) { + if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) { // ignore error, keep using the in-memory compilation unit. } } else { @@ -2917,12 +2918,10 @@ struct EmptyCompilationUnit : public QV4::CompiledData::CompilationUnit void QQmlScriptBlob::dataReceived(const SourceCodeData &data) { - QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine()); - if (!disableDiskCache() || forceDiskCache()) { - QQmlRefPointer unit = v4->iselFactory->createUnitForLoading(); + QQmlRefPointer unit = QQmlJS::Codegen::createUnitForLoading(); QString error; - if (unit->loadFromDisk(url(), data.sourceTimeStamp(), v4->iselFactory.data(), &error)) { + if (unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) { initializeFromCompilationUnit(unit); return; } else { @@ -2944,7 +2943,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) QmlIR::ScriptDirectivesCollector collector(&irUnit.jsParserEngine, &irUnit.jsGenerator); QList errors; - QQmlRefPointer unit = QV4::Script::precompile(&irUnit.jsModule, &irUnit.jsGenerator, v4, finalUrl(), source, &errors, &collector); + QQmlRefPointer unit = QV4::Script::precompile(&irUnit.jsModule, &irUnit.jsGenerator, finalUrl(), source, &errors, &collector); // No need to addref on unit, it's initial refcount is 1 source.clear(); if (!errors.isEmpty()) { diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 730bfd6d12..d28751d10a 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE class QQmlTypeNameCache; +class QQmlType; namespace QV4 { diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index c8aac719ab..630b405c84 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -56,6 +56,7 @@ #include #include +#include QT_BEGIN_NAMESPACE -- cgit v1.2.3