diff options
Diffstat (limited to 'src/qml/compiler/qv4compileddata_p.h')
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 126 |
1 files changed, 76 insertions, 50 deletions
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index a83dea1a0a..55c5f1f29f 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE // Bump this whenever the compiler data structures change in an incompatible way. -#define QV4_DATA_STRUCTURE_VERSION 0x13 +#define QV4_DATA_STRUCTURE_VERSION 0x15 class QIODevice; class QQmlPropertyCache; @@ -87,9 +87,6 @@ struct Document; } namespace QV4 { -namespace IR { -struct Function; -} struct Function; class EvalISelFactory; @@ -155,9 +152,7 @@ struct Lookup enum Type : unsigned int { Type_Getter = 0x0, Type_Setter = 0x1, - Type_GlobalGetter = 2, - Type_IndexedGetter = 3, - Type_IndexedSetter = 4 + Type_GlobalGetter = 2 }; union { @@ -202,6 +197,11 @@ struct String }; static_assert(sizeof(String) == 4, "String structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); +struct CodeOffsetToLine { + quint32_le codeOffset; + quint32_le line; +}; + // Function is aligned on an 8-byte boundary to make sure there are no bus errors or penalties // for unaligned access. The ordering of the fields is also from largest to smallest. struct Function @@ -210,22 +210,23 @@ struct Function IsStrict = 0x1, HasDirectEval = 0x2, UsesArgumentsObject = 0x4, - IsNamedExpression = 0x8, - HasCatchOrWith = 0x10, - CanUseSimpleCall = 0x20 +// Unused = 0x8, + HasCatchOrWith = 0x10 }; - // 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; quint32_le formalsOffset; quint32_le nLocals; quint32_le localsOffset; + quint32_le nLineNumbers; + quint32_le lineNumberOffset; quint32_le nInnerFunctions; + quint32_le nRegisters; Location location; // Qml Extensions Begin @@ -249,6 +250,7 @@ struct Function const quint32_le *formalsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + formalsOffset); } const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); } + const CodeOffsetToLine *lineNumberTable() const { return reinterpret_cast<const CodeOffsetToLine *>(reinterpret_cast<const char *>(this) + lineNumberOffset); } const quint32_le *qmlIdObjectDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingIdObjectsOffset); } const quint32_le *qmlContextPropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingContextPropertiesOffset); } const quint32_le *qmlScopePropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingScopePropertiesOffset); } @@ -258,13 +260,23 @@ 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 nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies) { - return (sizeof(Function) + (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies + 2 * nPropertyDependencies) * sizeof(quint32) + 7) & ~0x7; + 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); + size_t size = align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize); + Q_ASSERT(size < INT_MAX); + return int(size); + } + + static size_t align(size_t a) { + return (a + 7) & ~size_t(7); } }; -static_assert(sizeof(Function) == 72, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); +static_assert(sizeof(Function) == 76, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); // Qml data structures @@ -860,40 +872,59 @@ 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 QIntrusiveListNode nextCompilationUnit; - 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; @@ -913,23 +944,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; @@ -960,25 +988,23 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public void markObjects(MarkStack *markStack); - void destroy() 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; - virtual bool memoryMapCode(QString *errorString); + 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); #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 |