aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4internalclass_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-01-05 15:30:23 +0100
committerLars Knoll <lars.knoll@qt.io>2018-04-12 13:59:08 +0000
commit6002b48c3c5edc509c269c801fc8a088d5065ce8 (patch)
treea8fc764de87bfbd5f201930dcec1c7459502eb7e /src/qml/jsruntime/qv4internalclass_p.h
parent3932536b59df7b2fa010be6dd9f2501f6e306c8b (diff)
garbage collect InternalClass
Internal classes are now allocated and collected through the GC. As they are important to the deletion of other objects (because of the vtable pointer living inside the internal class), they need to get destroyed after regular objects have been sweeped. Achieve this by using a separate block allocator for internal class objects. Our lookups do often contain pointers to internal classes, so those need to be marked as well, so we don't accidentally collect them. Change-Id: I4762b054361c70c31f79f920f669ea0e8551601f Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass_p.h')
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h64
1 files changed, 38 insertions, 26 deletions
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 7533253873..0e6f52da43 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -54,6 +54,7 @@
#include <QHash>
#include <private/qv4identifier_p.h>
+#include <private/qv4heap_p.h>
QT_BEGIN_NAMESPACE
@@ -240,7 +241,7 @@ struct InternalClassTransition
const VTable *vtable;
Heap::Object *prototype;
};
- InternalClass *lookup;
+ Heap::InternalClass *lookup;
int flags;
enum {
// range 0-0xff is reserved for attribute changes
@@ -260,12 +261,14 @@ struct InternalClassTransition
{ return id < other.id || (id == other.id && flags < other.flags); }
};
-struct InternalClass {
- int id = 0; // unique across the engine, gets changed also when proto chain changes
+namespace Heap {
+
+struct InternalClass : Base {
+ int id; // unique across the engine, gets changed also when proto chain changes
ExecutionEngine *engine;
const VTable *vtable;
Heap::Object *prototype;
- InternalClass *parent = nullptr;
+ InternalClass *parent;
PropertyHash propertyTable; // id to valueIndex
SharedInternalClassData<Identifier *> nameMap;
@@ -279,27 +282,21 @@ struct InternalClass {
bool extensible;
bool isSealed;
bool isFrozen;
- bool isUsedAsProto = false;
+ 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 *id);
+ uint find(const QV4::String *string);
uint find(const Identifier *id)
{
uint index = propertyTable.lookup(id);
@@ -315,23 +312,38 @@ struct InternalClass {
Q_REQUIRED_RESULT InternalClass *asProtoClass();
- void destroyAll();
+ 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(InternalClass *ic, MarkStack *stack);
-
+ 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(InternalClass *other);
};
+inline
+void Base::markObjects(Base *b, MarkStack *stack)
+{
+ b->internalClass->mark(stack);
+}
+
+}
+
}
QT_END_NAMESPACE