diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-10-17 13:02:17 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-11-07 07:24:09 +0000 |
commit | 1c3e1df2536712c7c2aef4ec5f68316a7e32e4ff (patch) | |
tree | 503616ae443ed0e4386e92d67f94454efcc69fab /src | |
parent | 573ad68f8295e5b8e578bb6bad9d1ca932cccaf6 (diff) |
Move a couple of data members required for new JIT
Mark CompilationUnit final and get rid of it's vtable.
Fix initializations with 0 instead of nullptr.
Change-Id: Ieec260bd45d8f08cf5d8964becd312b221cbb2a9
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 34 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 71 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofiler_p.h | 157 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4enginebase_p.h | 17 |
5 files changed, 171 insertions, 110 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index ab47bf66f2..79a6018734 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -94,23 +94,10 @@ static QString cacheFilePath(const QUrl &url) } #endif -#ifndef V4_BOOTSTRAP CompilationUnit::CompilationUnit() - : data(0) - , engine(0) - , qmlEngine(0) - , runtimeLookups(0) - , runtimeRegularExpressions(0) - , runtimeClasses(0) - , constants(nullptr) - , totalBindingsCount(0) - , totalParserStatusCount(0) - , totalObjectCount(0) - , metaTypeId(-1) - , listMetaTypeId(-1) - , isRegisteredWithEngine(false) {} +#ifndef V4_BOOTSTRAP CompilationUnit::~CompilationUnit() { unlink(); @@ -269,14 +256,6 @@ void CompilationUnit::markObjects(QV4::MarkStack *markStack) } } -void CompilationUnit::destroy() -{ - if (qmlEngine) - QQmlEnginePrivate::deleteInEngineThread(qmlEngine, this); - else - delete this; -} - IdentifierHash<int> CompilationUnit::namedObjectsPerComponent(int componentObjectIndex) { auto it = namedObjectsPerComponentCache.find(componentObjectIndex); @@ -765,6 +744,17 @@ bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *e #endif +void CompilationUnit::destroy() +{ +#if !defined(V4_BOOTSTRAP) + if (qmlEngine) + QQmlEnginePrivate::deleteInEngineThread(qmlEngine, this); + else +#endif + delete this; +} + + void Unit::generateChecksum() { #ifndef V4_BOOTSTRAP diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 8825ce7b98..8d6f3b3393 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -869,39 +869,58 @@ typedef QVector<QQmlPropertyData*> BindingPropertyData; struct Q_QML_PRIVATE_EXPORT CompilationUnitBase { - QV4::Heap::String **runtimeStrings = 0; // Array + // pointers either to data->constants() or little-endian memory copy. + QV4::Heap::String **runtimeStrings = nullptr; // Array + const Value* constants = nullptr; + QV4::Value *runtimeRegularExpressions = nullptr; }; Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value); Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeStrings) == 0); +Q_STATIC_ASSERT(offsetof(CompilationUnitBase, constants) == sizeof(QV4::Heap::String **)); +Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeRegularExpressions) == offsetof(CompilationUnitBase, constants) + sizeof(const Value *)); -struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public QQmlRefCount +struct Q_QML_PRIVATE_EXPORT CompilationUnit final : public CompilationUnitBase { +public: + CompilationUnit(); #ifdef V4_BOOTSTRAP - CompilationUnit() - : data(0) - {} - virtual ~CompilationUnit() {} + ~CompilationUnit() {} #else - CompilationUnit(); - virtual ~CompilationUnit(); + ~CompilationUnit(); #endif - const Unit *data; + void addref() + { + Q_ASSERT(refCount.load() > 0); + refCount.ref(); + } + + void release() + { + Q_ASSERT(refCount.load() > 0); + if (!refCount.deref()) + destroy(); + } + int count() const + { + return refCount.load(); + } + + const Unit *data = nullptr; // Called only when building QML, when we build the header for JS first and append QML data - virtual QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument); + QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument); #ifndef V4_BOOTSTRAP - ExecutionEngine *engine; - QQmlEnginePrivate *qmlEngine; // only used in QML environment for composite types, not in plain QJSEngine case. + ExecutionEngine *engine = nullptr; + QQmlEnginePrivate *qmlEngine = nullptr; // only used in QML environment for composite types, not in plain QJSEngine case. QString fileName() const { return data->stringAt(data->sourceFileIndex); } QUrl url() const { if (m_url.isNull) m_url = QUrl(fileName()); return m_url; } - QV4::Lookup *runtimeLookups; - QV4::Value *runtimeRegularExpressions; - QV4::InternalClass **runtimeClasses; + QV4::Lookup *runtimeLookups = nullptr; + QV4::InternalClass **runtimeClasses = nullptr; QVector<QV4::Function *> runtimeFunctions; mutable QQmlNullableValue<QUrl> m_url; @@ -921,23 +940,20 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public QHash<int, IdentifierHash<int>> namedObjectsPerComponentCache; IdentifierHash<int> namedObjectsPerComponent(int componentObjectIndex); - // pointers either to data->constants() or little-endian memory copy. - const Value* constants; - void finalizeCompositeType(QQmlEnginePrivate *qmlEngine); - int totalBindingsCount; // Number of bindings used in this type - int totalParserStatusCount; // Number of instantiated types that are QQmlParserStatus subclasses - int totalObjectCount; // Number of objects explicitly instantiated + int totalBindingsCount = 0; // Number of bindings used in this type + int totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses + int totalObjectCount = 0; // Number of objects explicitly instantiated QVector<QQmlScriptData *> dependentScripts; ResolvedTypeReferenceMap resolvedTypes; bool verifyChecksum(const DependentTypesHasher &dependencyHasher) const; - int metaTypeId; - int listMetaTypeId; - bool isRegisteredWithEngine; + int metaTypeId = -1; + int listMetaTypeId = -1; + bool isRegisteredWithEngine = false; QScopedPointer<CompilationUnitMapper> backingFile; @@ -968,14 +984,17 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public void markObjects(MarkStack *markStack); - void destroy() override; - bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString); protected: void linkBackendToEngine(QV4::ExecutionEngine *engine); #endif // V4_BOOTSTRAP +private: + void destroy(); + + QAtomicInt refCount = 1; + public: #if defined(V4_BOOTSTRAP) bool saveToDisk(const QString &outputFileName, QString *errorString); diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 88f8e94f25..9b51b5ab46 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -149,74 +149,120 @@ class Q_QML_PRIVATE_EXPORT QQmlProfiler : public QObject, public QQmlProfilerDef Q_OBJECT public: - class FunctionRefCount : public QQmlRefCount { - public: - FunctionRefCount(QV4::Function *function): - m_function(function) + struct Location { + Location(const QQmlSourceLocation &location = QQmlSourceLocation(), + const QUrl &url = QUrl()) : + location(location), url(url) {} + QQmlSourceLocation location; + QUrl url; + }; + + // Unfortunately we have to resolve the locations right away because the QML context might not + // be available anymore when we send the data. + struct RefLocation : public Location { + RefLocation() + : Location(), locationType(MaximumRangeType), sent(false) { - m_function->compilationUnit->addref(); + function = nullptr; } - FunctionRefCount(const FunctionRefCount &other) : - QQmlRefCount(other), m_function(other.m_function) + RefLocation(QV4::Function *ref) + : Location(ref->sourceLocation()), locationType(Binding), sent(false) { - m_function->compilationUnit->addref(); + function = ref; + function->compilationUnit->addref(); } - FunctionRefCount &operator=(const FunctionRefCount &other) + RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj, const QString &type) + : Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url), + locationType(Creating), sent(false) + { + unit = ref; + unit->addref(); + } + + RefLocation(QQmlBoundSignalExpression *ref) + : Location(ref->sourceLocation()), locationType(HandlingSignal), sent(false) + { + boundSignal = ref; + boundSignal->addref(); + } + + RefLocation(QQmlDataBlob *ref) + : Location(QQmlSourceLocation()), locationType(Compiling), sent(false) + { + blob = ref; + blob->addref(); + } + + RefLocation(const RefLocation &other) + : Location(other), + locationType(other.locationType), + function(other.function), + sent(other.sent) + { + addref(); + } + + RefLocation &operator=(const RefLocation &other) { if (this != &other) { - QQmlRefCount::operator=(other); - other.m_function->compilationUnit->addref(); - m_function->compilationUnit->release(); - m_function = other.m_function; + release(); + Location::operator=(other); + locationType = other.locationType; + function = other.function; + sent = other.sent; + addref(); } return *this; } - ~FunctionRefCount() + ~RefLocation() { - m_function->compilationUnit->release(); + release(); } - private: - QV4::Function *m_function; - }; - - struct Location { - Location(const QQmlSourceLocation &location = QQmlSourceLocation(), - const QUrl &url = QUrl()) : - location(location), url(url) {} - QQmlSourceLocation location; - QUrl url; - }; + void addref() + { + switch (locationType) { + case Binding: + function->compilationUnit->addref(); + break; + case Creating: + unit->addref(); + break; + case HandlingSignal: + boundSignal->addref(); + break; + case Compiling: + blob->addref(); + break; + default: + Q_ASSERT(locationType == MaximumRangeType); + break; + } + } - // Unfortunately we have to resolve the locations right away because the QML context might not - // be available anymore when we send the data. - struct RefLocation : public Location { - RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr), sent(false) - {} - - RefLocation(QV4::Function *function) : - Location(function->sourceLocation()), locationType(Binding), - ref(new FunctionRefCount(function), - QQmlRefPointer<QQmlRefCount>::Adopt), sent(false) - {} - - RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj, - const QString &type) : - Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url), - locationType(Creating), ref(ref), sent(false) - {} - - RefLocation(QQmlBoundSignalExpression *ref) : - Location(ref->sourceLocation()), locationType(HandlingSignal), ref(ref), sent(false) - {} - - RefLocation(QQmlDataBlob *ref) : - Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), ref(ref), - sent(false) - {} + void release() + { + switch (locationType) { + case Binding: + function->compilationUnit->release(); + break; + case Creating: + unit->release(); + break; + case HandlingSignal: + boundSignal->release(); + break; + case Compiling: + blob->release(); + break; + default: + Q_ASSERT(locationType == MaximumRangeType); + break; + } + } bool isValid() const { @@ -224,7 +270,12 @@ public: } RangeType locationType; - QQmlRefPointer<QQmlRefCount> ref; + union { + QV4::Function *function; + QV4::CompiledData::CompilationUnit *unit; + QQmlBoundSignalExpression *boundSignal; + QQmlDataBlob *blob; + }; bool sent; }; diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 0f9027ea5f..6d5b93bcc8 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -441,8 +441,6 @@ public: InternalClass *newClass(const InternalClass &other); - // Exception handling - Value *exceptionValue; StackTrace exceptionStackTrace; ReturnedValue throwError(const Value &value); diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h index 00049392af..e0f5f3ffb1 100644 --- a/src/qml/jsruntime/qv4enginebase_p.h +++ b/src/qml/jsruntime/qv4enginebase_p.h @@ -66,24 +66,27 @@ struct CppStackFrame; #endif struct Q_QML_EXPORT EngineBase { - CppStackFrame *currentStackFrame = 0; + CppStackFrame *currentStackFrame = nullptr; - Value *jsStackTop = 0; + Value *jsStackTop = nullptr; quint8 hasException = false; quint8 writeBarrierActive = false; quint16 unused = 0; #if QT_POINTER_SIZE == 8 quint8 padding[4]; #endif - MemoryManager *memoryManager = 0; + MemoryManager *memoryManager = nullptr; Runtime runtime; qint32 callDepth = 0; - Value *jsStackLimit = 0; - Value *jsStackBase = 0; + Value *jsStackLimit = nullptr; + Value *jsStackBase = nullptr; - IdentifierTable *identifierTable = 0; - Object *globalObject = 0; + IdentifierTable *identifierTable = nullptr; + Object *globalObject = nullptr; + + // Exception handling + Value *exceptionValue = nullptr; enum { Class_Empty, |