diff options
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index b689272006..0b6f088bd3 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -53,8 +53,8 @@ #include "qv4global_p.h" #include <QHash> -#include <private/qqmljsmemorypool_p.h> #include <private/qv4identifier_p.h> +#include <private/qv4heap_p.h> QT_BEGIN_NAMESPACE @@ -79,12 +79,12 @@ struct PropertyHash inline PropertyHash(); inline PropertyHash(const PropertyHash &other); inline ~PropertyHash(); + PropertyHash &operator=(const PropertyHash &other); void addEntry(const Entry &entry, int classSize); uint lookup(const Identifier *identifier) const; - -private: - PropertyHash &operator=(const PropertyHash &other); + int removeIdentifier(Identifier *identifier, int classSize); + void detach(bool grow, int classSize); }; struct PropertyHashData @@ -118,6 +118,17 @@ inline PropertyHash::~PropertyHash() delete d; } +inline PropertyHash &PropertyHash::operator=(const PropertyHash &other) +{ + ++other.d->refCount; + if (!--d->refCount) + delete d; + d = other.d; + return *this; +} + + + inline uint PropertyHash::lookup(const Identifier *identifier) const { Q_ASSERT(d->entries); @@ -163,6 +174,13 @@ struct SharedInternalClassData { if (!--d->refcount) delete d; } + SharedInternalClassData &operator=(const SharedInternalClassData &other) { + ++other.d->refcount; + if (!--d->refcount) + delete d; + d = other.d; + return *this; + } void add(uint pos, T value) { if (pos < d->size) { @@ -214,9 +232,6 @@ struct SharedInternalClassData { Q_ASSERT(i < d->size); return d->data[i]; } - -private: - SharedInternalClassData &operator=(const SharedInternalClassData &other); }; struct InternalClassTransition @@ -226,14 +241,17 @@ struct InternalClassTransition const VTable *vtable; Heap::Object *prototype; }; - InternalClass *lookup; + Heap::InternalClass *lookup; int flags; enum { // range 0-0xff is reserved for attribute changes NotExtensible = 0x100, VTableChange = 0x200, PrototypeChange = 0x201, - ProtoClass = 0x202 + ProtoClass = 0x202, + Sealed = 0x203, + Frozen = 0x204, + RemoveMember = -1 }; bool operator==(const InternalClassTransition &other) const @@ -243,11 +261,14 @@ struct InternalClassTransition { return id < other.id || (id == other.id && flags < other.flags); } }; -struct InternalClass : public QQmlJS::Managed { - int id = 0; // unique across the engine, gets changed also when proto chain changes +namespace Heap { + +struct InternalClass : Base { ExecutionEngine *engine; const VTable *vtable; + quintptr protoId; // unique across the engine, gets changed whenever the proto chain changes Heap::Object *prototype; + InternalClass *parent; PropertyHash propertyTable; // id to valueIndex SharedInternalClassData<Identifier *> nameMap; @@ -257,32 +278,25 @@ struct InternalClass : public QQmlJS::Managed { std::vector<Transition> transitions; InternalClassTransition &lookupOrInsertTransition(const InternalClassTransition &t); - InternalClass *m_sealed; - InternalClass *m_frozen; - uint size; bool extensible; - bool isUsedAsProto = false; + bool isSealed; + bool isFrozen; + bool isUsedAsProto; + + void init(ExecutionEngine *engine); + void init(InternalClass *other); + void destroy(); Q_REQUIRED_RESULT InternalClass *nonExtensible(); - Q_REQUIRED_RESULT InternalClass *changeVTable(const VTable *vt) { - if (vtable == vt) - return this; - return changeVTableImpl(vt); - } - Q_REQUIRED_RESULT InternalClass *changePrototype(Heap::Object *proto) { - if (prototype == proto) - return this; - return changePrototypeImpl(proto); - } - static void addMember(Object *object, String *string, PropertyAttributes data, uint *index); - Q_REQUIRED_RESULT InternalClass *addMember(String *string, PropertyAttributes data, uint *index = nullptr); + static void addMember(QV4::Object *object, QV4::String *string, PropertyAttributes data, uint *index); + Q_REQUIRED_RESULT InternalClass *addMember(QV4::String *string, PropertyAttributes data, uint *index = nullptr); Q_REQUIRED_RESULT InternalClass *addMember(Identifier *identifier, PropertyAttributes data, uint *index = nullptr); Q_REQUIRED_RESULT InternalClass *changeMember(Identifier *identifier, PropertyAttributes data, uint *index = nullptr); - static void changeMember(Object *object, String *string, PropertyAttributes data, uint *index = nullptr); - static void removeMember(Object *object, Identifier *id); - uint find(const String *string); + static void changeMember(QV4::Object *object, QV4::String *string, PropertyAttributes data, uint *index = nullptr); + static void removeMember(QV4::Object *object, Identifier *identifier); + uint find(const QV4::String *string); uint find(const Identifier *id) { uint index = propertyTable.lookup(id); @@ -298,24 +312,37 @@ struct InternalClass : public QQmlJS::Managed { Q_REQUIRED_RESULT InternalClass *asProtoClass(); - void destroy(); + Q_REQUIRED_RESULT InternalClass *changeVTable(const VTable *vt) { + if (vtable == vt) + return this; + return changeVTableImpl(vt); + } + Q_REQUIRED_RESULT InternalClass *changePrototype(Heap::Object *proto) { + if (prototype == proto) + return this; + return changePrototypeImpl(proto); + } void updateProtoUsage(Heap::Object *o); + static void markObjects(Heap::Base *ic, MarkStack *stack); + private: Q_QML_EXPORT InternalClass *changeVTableImpl(const VTable *vt); Q_QML_EXPORT InternalClass *changePrototypeImpl(Heap::Object *proto); InternalClass *addMemberImpl(Identifier *identifier, PropertyAttributes data, uint *index); - void updateInternalClassIdRecursive(); + + void removeChildEntry(InternalClass *child); friend struct ExecutionEngine; - InternalClass(ExecutionEngine *engine); - InternalClass(const InternalClass &other); }; -struct InternalClassPool : public QQmlJS::MemoryPool +inline +void Base::markObjects(Base *b, MarkStack *stack) { - void markObjects(MarkStack *markStack); -}; + b->internalClass->mark(stack); +} + +} } |