aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-01-24 12:07:33 +0100
committerLars Knoll <lars.knoll@qt.io>2017-03-09 08:58:04 +0000
commit6b4b2f5f1bbd706742cbab8764a1d07cbd912600 (patch)
treed11734823cbf27c557fea8b9be5225c1303d7b12 /src/qml/jsruntime
parent78dd18a0cd18449e1289e428ea6eca65e28fb114 (diff)
New mark table implementation
Automatically generate a table containing the data where JS Values and pointers are in objects in the JS heap. This will allow making the GC mark phase a lot more efficient. A bit of a special hack is currently required for MemberData and ArrayData, as they have a variable length, and we need to read the size from the object. We keep backwards compatibility with the old markObjects() functions for now (calling them if they are defined). Some further work on QV4::String and in a few other places is required before we can get remove the compatibility. Change-Id: I78528ace67e886bdbe4a4330c9677c7fc9f08a33 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp11
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h26
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp24
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h16
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp7
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h13
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h14
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp22
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h26
-rw-r--r--src/qml/jsruntime/qv4global_p.h1
-rw-r--r--src/qml/jsruntime/qv4managed.cpp1
-rw-r--r--src/qml/jsruntime/qv4managed_p.h5
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp7
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h14
-rw-r--r--src/qml/jsruntime/qv4object.cpp12
-rw-r--r--src/qml/jsruntime/qv4object_p.h18
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp11
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp9
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h20
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp6
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h29
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp7
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h9
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp6
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h19
28 files changed, 124 insertions, 237 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 7c1cc92a13..39b99e9876 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -235,17 +235,6 @@ void ArgumentsSetterFunction::call(const Managed *setter, Scope &scope, CallData
scope.result = Encode::undefined();
}
-void ArgumentsObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- ArgumentsObject::Data *o = static_cast<ArgumentsObject::Data *>(that);
- if (o->context)
- o->context->mark(e);
- if (o->mappedArguments)
- o->mappedArguments->mark(e);
-
- Object::markObjects(that, e);
-}
-
uint ArgumentsObject::getLength(const Managed *m)
{
const ArgumentsObject *a = static_cast<const ArgumentsObject *>(m);
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index f80ade9611..f579afff14 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -59,26 +59,35 @@ namespace QV4 {
namespace Heap {
-struct ArgumentsGetterFunction : FunctionObject {
+#define ArgumentsGetterFunctionMembers(class, Member) \
+ Member(class, uint, index)
+
+DECLARE_HEAP_OBJECT(ArgumentsGetterFunction, FunctionObject) {
+ DECLARE_MARK_TABLE(ArgumentsGetterFunction);
inline void init(QV4::ExecutionContext *scope, uint index);
- uint index;
};
-struct ArgumentsSetterFunction : FunctionObject {
+#define ArgumentsSetterFunctionMembers(class, Member) \
+ Member(class, uint, index)
+
+DECLARE_HEAP_OBJECT(ArgumentsSetterFunction, FunctionObject) {
+ DECLARE_MARK_TABLE(ArgumentsSetterFunction);
inline void init(QV4::ExecutionContext *scope, uint index);
- uint index;
};
-struct ArgumentsObject : Object {
+#define ArgumentsObjectMembers(class, Member) \
+ Member(class, Pointer<CallContext>, context) \
+ Member(class, Pointer<MemberData>, mappedArguments) \
+ Member(class, bool, fullyCreated)
+
+DECLARE_HEAP_OBJECT(ArgumentsObject, Object) {
+ DECLARE_MARK_TABLE(ArgumentsObject);
enum {
LengthPropertyIndex = 0,
CalleePropertyIndex = 1,
CallerPropertyIndex = 3
};
void init(QV4::CallContext *context);
- Pointer<CallContext> context;
- bool fullyCreated;
- Pointer<MemberData> mappedArguments;
};
}
@@ -131,7 +140,6 @@ struct ArgumentsObject: Object {
static bool putIndexed(Managed *m, uint index, const Value &value);
static bool deleteIndexedProperty(Managed *m, uint index);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
static uint getLength(const Managed *m);
void fullyCreate();
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index d8a7de5466..47d353ffd0 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -50,6 +50,7 @@ QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON
const QV4::VTable QV4::ArrayData::static_vtbl = {
0,
+ 0,
QV4::ArrayData::IsExecutionContext,
QV4::ArrayData::IsString,
QV4::ArrayData::IsObject,
@@ -233,20 +234,6 @@ void ArrayData::ensureAttributes(Object *o)
ArrayData::realloc(o, Heap::ArrayData::Simple, 0, true);
}
-
-void SimpleArrayData::markObjects(Heap::Base *d, ExecutionEngine *e)
-{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(d);
- uint end = dd->offset + dd->len;
- if (end > dd->alloc) {
- for (uint i = 0; i < end - dd->alloc; ++i)
- dd->arrayData[i].mark(e);
- end = dd->alloc;
- }
- for (uint i = dd->offset; i < end; ++i)
- dd->arrayData[i].mark(e);
-}
-
ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index)
{
const Heap::SimpleArrayData *dd = static_cast<const Heap::SimpleArrayData *>(d);
@@ -380,15 +367,6 @@ void SparseArrayData::free(Heap::ArrayData *d, uint idx)
d->attrs[idx].clear();
}
-
-void SparseArrayData::markObjects(Heap::Base *d, ExecutionEngine *e)
-{
- Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(d);
- uint l = dd->alloc;
- for (uint i = 0; i < l; ++i)
- dd->arrayData[i].mark(e);
-}
-
Heap::ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
{
realloc(o, Heap::ArrayData::Sparse, n, enforceAttributes);
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index 24b948f01e..919bd84762 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -90,7 +90,7 @@ struct ArrayVTable
namespace Heap {
-struct ArrayData : public Base {
+struct ArrayDataData {
enum Type {
Simple = 0,
Complex = 1,
@@ -110,6 +110,13 @@ struct ArrayData : public Base {
SparseArray *sparse;
};
Value arrayData[1];
+};
+static Q_CONSTEXPR quint64 ArrayData_markTable = \
+ (MarkFlagsForType<decltype(ArrayDataData::arrayData)>::markFlags << (offsetof(ArrayDataData, arrayData) >> 2)) \
+ << (sizeof(Base) >> 2) | QV4::Heap::Base::markTable;
+
+struct ArrayData : public Base, ArrayDataData {
+ DECLARE_MARK_TABLE(ArrayData);
bool isSparse() const { return type == Sparse; }
@@ -189,6 +196,9 @@ struct Q_QML_EXPORT ArrayData : public Managed
{
typedef Heap::ArrayData::Type Type;
V4_MANAGED(ArrayData, Managed)
+ enum {
+ IsArrayData = true
+ };
uint alloc() const { return d()->alloc; }
uint &alloc() { return d()->alloc; }
@@ -246,8 +256,6 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
static Heap::ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
- static void markObjects(Heap::Base *d, ExecutionEngine *e);
-
static ReturnedValue get(const Heap::ArrayData *d, uint index);
static bool put(Object *o, uint index, const Value &value);
static bool putArray(Object *o, uint index, const Value *values, uint n);
@@ -274,8 +282,6 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
- static void markObjects(Heap::Base *d, ExecutionEngine *e);
-
static Heap::ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
static ReturnedValue get(const Heap::ArrayData *d, uint index);
static bool put(Object *o, uint index, const Value &value);
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index a810b38f24..aa7d01d16c 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -84,13 +84,6 @@ void DataViewCtor::call(const Managed *that, Scope &scope, CallData *callData)
construct(that, scope, callData);
}
-
-void DataView::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- DataView::Data *v = static_cast<DataView::Data *>(that);
- v->buffer->mark(e);
-}
-
void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
index 11cc0a6bd9..f61a2a1780 100644
--- a/src/qml/jsruntime/qv4dataview_p.h
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -63,11 +63,14 @@ struct DataViewCtor : FunctionObject {
void init(QV4::ExecutionContext *scope);
};
-struct DataView : Object {
+#define DataViewMembers(class, Member) \
+ Member(class, Pointer<ArrayBuffer>, buffer) \
+ Member(class, uint, byteLength) \
+ Member(class, uint, byteOffset)
+
+DECLARE_HEAP_OBJECT(DataView, Object) {
+ DECLARE_MARK_TABLE(DataView);
void init() { Object::init(); }
- Pointer<ArrayBuffer> buffer;
- uint byteLength;
- uint byteOffset;
};
}
@@ -84,8 +87,6 @@ struct DataView : Object
{
V4_OBJECT2(DataView, Object)
V4_PROTOTYPE(dataViewPrototype)
-
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
struct DataViewPrototype: Object
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index f290bc5136..798a14086d 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -173,14 +173,6 @@ void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallDa
scope.result = This->d()->stack;
}
-void ErrorObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- ErrorObject::Data *This = static_cast<ErrorObject::Data *>(that);
- if (This->stack)
- This->stack->mark(e);
- Object::markObjects(that, e);
-}
-
DEFINE_OBJECT_VTABLE(ErrorObject);
DEFINE_OBJECT_VTABLE(SyntaxErrorObject);
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 9ba9f05234..a5af0b6ab6 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -62,7 +62,12 @@ struct SyntaxErrorObject;
namespace Heap {
-struct ErrorObject : Object {
+
+#define ErrorObjectMembers(class, Member) \
+ Member(class, Pointer<String>, stack)
+
+DECLARE_HEAP_OBJECT(ErrorObject, Object) {
+ DECLARE_MARK_TABLE(ErrorObject);
enum ErrorType {
Error,
EvalError,
@@ -72,6 +77,8 @@ struct ErrorObject : Object {
TypeError,
URIError
};
+ StackTrace *stackTrace;
+ ErrorType errorType;
void init();
void init(const Value &message, ErrorType t = Error);
@@ -80,10 +87,6 @@ struct ErrorObject : Object {
delete stackTrace;
Object::destroy();
}
-
- ErrorType errorType;
- StackTrace *stackTrace;
- Pointer<String> stack;
};
struct EvalErrorObject : ErrorObject {
@@ -173,7 +176,6 @@ struct ErrorObject: Object {
static const char *className(Heap::ErrorObject::ErrorType t);
static void method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
template<>
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index e9431ed25e..ae1a403ea1 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -69,6 +69,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(FunctionObject);
+Q_STATIC_ASSERT((Heap::FunctionObject::markTable & Heap::Object::markTable) == Heap::Object::markTable);
+
void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, bool createProto)
{
Object::init();
@@ -149,15 +151,6 @@ void FunctionObject::call(const Managed *, Scope &scope, CallData *)
scope.result = Encode::undefined();
}
-void FunctionObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- Heap::FunctionObject *o = static_cast<Heap::FunctionObject *>(that);
- if (o->scope)
- o->scope->mark(e);
-
- Object::markObjects(that, e);
-}
-
Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function)
{
return scope->d()->engine->memoryManager->allocObject<ScriptFunction>(scope, function);
@@ -606,14 +599,3 @@ void BoundFunction::construct(const Managed *that, Scope &scope, CallData *dd)
ScopedFunctionObject t(scope, f->target());
t->construct(scope, callData);
}
-
-void BoundFunction::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- BoundFunction::Data *o = static_cast<BoundFunction::Data *>(that);
- if (o->target)
- o->target->mark(e);
- o->boundThis.mark(e);
- if (o->boundArgs)
- o->boundArgs->mark(e);
- FunctionObject::markObjects(that, e);
-}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 45d7485f1b..083ff4343b 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -65,7 +65,12 @@ struct BuiltinFunction;
namespace Heap {
-struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
+#define FunctionObjectMembers(class, Member) \
+ Member(class, Pointer<ExecutionContext>, scope) \
+ Member(class, Function *, function)
+
+DECLARE_HEAP_OBJECT(FunctionObject, Object) {
+ DECLARE_MARK_TABLE(FunctionObject);
enum {
Index_Prototype = 0,
Index_ProtoConstructor = 0
@@ -82,9 +87,6 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
bool needsActivation() const { return function ? function->needsActivation() : false; }
const QV4::Object *protoProperty() const { return propertyData(Index_Prototype)->cast<QV4::Object>(); }
-
- Pointer<ExecutionContext> scope;
- Function *function;
};
struct FunctionCtor : FunctionObject {
@@ -119,11 +121,15 @@ struct ScriptFunction : FunctionObject {
void init(QV4::ExecutionContext *scope, Function *function);
};
-struct BoundFunction : FunctionObject {
+#define BoundFunctionMembers(class, Member) \
+ Member(class, Pointer<FunctionObject>, target) \
+ Member(class, Value, boundThis) \
+ Member(class, Pointer<MemberData>, boundArgs)
+
+DECLARE_HEAP_OBJECT(BoundFunction, FunctionObject) {
+ DECLARE_MARK_TABLE(BoundFunction);
+
void init(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs);
- Pointer<FunctionObject> target;
- Value boundThis;
- Pointer<MemberData> boundArgs;
};
}
@@ -160,8 +166,6 @@ struct Q_QML_EXPORT FunctionObject: Object {
bool isBoundFunction() const;
QQmlSourceLocation sourceLocation() const;
-
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
template<>
@@ -259,8 +263,6 @@ struct BoundFunction: FunctionObject {
static void construct(const Managed *, Scope &scope, CallData *d);
static void call(const Managed *that, Scope &scope, CallData *dd);
-
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
}
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index b0d14fc2b4..0f4859f0fa 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -184,6 +184,7 @@ namespace Heap {
struct DataView;
struct TypedArray;
+ template <typename T> struct Pointer;
}
class MemoryManager;
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index 3a84a83b9c..1b43fd86e8 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -47,6 +47,7 @@ using namespace QV4;
const VTable Managed::static_vtbl =
{
0,
+ 0,
Managed::IsExecutionContext,
Managed::IsString,
Managed::IsObject,
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 5c764e7ff0..d4cc31b96a 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -91,6 +91,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
dptr->_checkIsInitialized(); \
return dptr; \
} \
+ static Q_CONSTEXPR quint64 markTable = QV4::Heap::DataClass::markTable; \
V4_ASSERT_IS_TRIVIAL(QV4::Heap::DataClass)
#define V4_MANAGED(DataClass, superClass) \
@@ -129,6 +130,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
#define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \
{ \
parentVTable, \
+ markTable, \
classname::IsExecutionContext, \
classname::IsString, \
classname::IsObject, \
@@ -139,7 +141,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
classname::MyType, \
#classname, \
Q_VTABLE_FUNCTION(classname, destroy), \
- markObjects, \
+ Q_VTABLE_FUNCTION(classname, markObjects), \
isEqualTo \
}
@@ -206,6 +208,7 @@ public:
bool markBit() const { return d()->isMarked(); }
static void destroy(Heap::Base *) {}
+ static void markObjects(Heap::Base *, ExecutionEngine *) {}
Q_ALWAYS_INLINE Heap::Base *heapObject() const {
return m();
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index db45c77472..3a6d66a030 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -45,13 +45,6 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(MemberData);
-void MemberData::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- Heap::MemberData *m = static_cast<Heap::MemberData *>(that);
- for (uint i = 0; i < m->size; ++i)
- m->data[i].mark(e);
-}
-
Heap::MemberData *MemberData::allocate(ExecutionEngine *e, uint n, Heap::MemberData *old)
{
Q_ASSERT(!old || old->size < n);
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index 5c89dfe8ec..c4e797ff8d 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -59,12 +59,12 @@ namespace QV4 {
namespace Heap {
-struct MemberData : Base {
- union {
- uint size;
- double _dummy;
- };
- Value data[1];
+#define MemberDataMembers(class, Member) \
+ Member(class, uint, size) \
+ Member(class, ValueArray, data)
+
+DECLARE_HEAP_OBJECT(MemberData, Base) {
+ DECLARE_MARK_TABLE(MemberData);
};
V4_ASSERT_IS_TRIVIAL(MemberData)
@@ -80,8 +80,6 @@ struct MemberData : Managed
inline uint size() const { return d()->size; }
static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old = 0);
-
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index dd3bbccde3..095aa6b4da 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -258,18 +258,6 @@ void Object::defineReadonlyConfigurableProperty(String *name, const Value &value
insertMember(name, value, Attr_ReadOnly_ButConfigurable);
}
-void Object::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- Heap::Object *o = static_cast<Heap::Object *>(that);
-
- if (o->memberData)
- o->memberData->mark(e);
- if (o->arrayData)
- o->arrayData->mark(e);
- if (o->prototype)
- o->prototype->mark(e);
-}
-
void Object::insertMember(String *s, const Property *p, PropertyAttributes attributes)
{
uint idx;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 0d17afbf41..b0eec1adfc 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -67,17 +67,19 @@ struct BuiltinFunction;
namespace Heap {
-struct Object : Base {
+#define ObjectMembers(class, Member) \
+ Member(class, InternalClass *, internalClass) \
+ Member(class, Pointer<Object>, prototype) \
+ Member(class, Pointer<MemberData>, memberData) \
+ Member(class, Pointer<ArrayData>, arrayData)
+
+DECLARE_HEAP_OBJECT(Object, Base) {
+ DECLARE_MARK_TABLE(Object);
void init() { Base::init(); }
void destroy() { Base::destroy(); }
const Value *propertyData(uint index) const { return memberData->data + index; }
Value *propertyData(uint index) { return memberData->data + index; }
-
- InternalClass *internalClass;
- Pointer<Object> prototype;
- Pointer<MemberData> memberData;
- Pointer<ArrayData> arrayData;
};
}
@@ -114,7 +116,8 @@ struct Object : Base {
dptr->_checkIsInitialized(); \
return dptr; \
} \
- V4_ASSERT_IS_TRIVIAL(QV4::Heap::DataClass);
+ V4_ASSERT_IS_TRIVIAL(QV4::Heap::DataClass); \
+ static Q_CONSTEXPR quint64 markTable = QV4::Heap::DataClass::markTable;
#define V4_INTERNALCLASS(c) \
static QV4::InternalClass *defaultInternalClass(QV4::ExecutionEngine *e) \
@@ -400,7 +403,6 @@ public:
inline void call(Scope &scope, CallData *d) const
{ vtable()->call(this, scope, d); }
protected:
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
static void construct(const Managed *m, Scope &scope, CallData *);
static void call(const Managed *m, Scope &scope, CallData *);
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index 987c322e47..de82bf835f 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -215,15 +215,6 @@ void PersistentValueStorage::free(Value *v)
freePage(p);
}
-static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
-{
- while (engine->jsStackTop > markBase) {
- Heap::Base *h = engine->popForGC();
- Q_ASSERT (h->vtable()->markObjects);
- h->vtable()->markObjects(h, engine);
- }
-}
-
void PersistentValueStorage::mark(ExecutionEngine *e)
{
Value *markBase = e->jsStackTop;
@@ -234,7 +225,7 @@ void PersistentValueStorage::mark(ExecutionEngine *e)
if (Managed *m = p->values[i].as<Managed>())
m->mark(e);
}
- drainMarkStack(e, markBase);
+ e->memoryManager->drainMarkStack(markBase);
p = p->header.next;
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index c9b4b433bd..deea893632 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1841,15 +1841,6 @@ void QObjectMethod::callInternal(CallData *callData, Scope &scope) const
}
}
-void QObjectMethod::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- QObjectMethod::Data *This = static_cast<QObjectMethod::Data*>(that);
- if (This->valueTypeWrapper)
- This->valueTypeWrapper->mark(e);
-
- FunctionObject::markObjects(that, e);
-}
-
DEFINE_OBJECT_VTABLE(QObjectMethod);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index d81ef2a680..002e1f2eb0 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -95,7 +95,15 @@ private:
QQmlQPointer<QObject> qObj;
};
-struct QObjectMethod : FunctionObject {
+#define QObjectMethodMembers(class, Member) \
+ Member(class, Pointer<QQmlValueTypeWrapper>, valueTypeWrapper) \
+ Member(class, QQmlQPointer<QObject>, qObj) \
+ Member(class, QQmlPropertyCache *, _propertyCache) \
+ Member(class, int, index)
+
+DECLARE_HEAP_OBJECT(QObjectMethod, FunctionObject) {
+ DECLARE_MARK_TABLE(QObjectMethod);
+
void init(QV4::ExecutionContext *scope);
void destroy()
{
@@ -113,18 +121,10 @@ struct QObjectMethod : FunctionObject {
_propertyCache = c;
}
- Pointer<QQmlValueTypeWrapper> valueTypeWrapper;
-
const QMetaObject *metaObject();
QObject *object() const { return qObj.data(); }
void setObject(QObject *o) { qObj = o; }
-private:
- QQmlQPointer<QObject> qObj;
- QQmlPropertyCache *_propertyCache;
-
-public:
- int index;
};
struct QMetaObjectWrapper : FunctionObject {
@@ -243,8 +243,6 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject
void callInternal(CallData *callData, Scope &scope) const;
- static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
-
static QPair<QObject *, int> extractQtMethod(const QV4::FunctionObject *function);
};
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 9e94c58432..6778145ff1 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -126,9 +126,3 @@ void Heap::RegExp::destroy()
delete pattern;
Base::destroy();
}
-
-void RegExp::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- Q_UNUSED(that);
- Q_UNUSED(e);
-}
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index d3e63375a5..348af0fb14 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -119,8 +119,6 @@ struct RegExp : public Managed
int captureCount() const { return subPatternCount() + 1; }
- static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
-
friend class RegExpCache;
};
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 0894d0c25b..ca893839ef 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -162,15 +162,6 @@ void RegExpObject::initProperties()
*propertyData(Index_Multiline) = Primitive::fromBoolean(value()->multiLine);
}
-
-void RegExpObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- RegExpObject::Data *re = static_cast<RegExpObject::Data *>(that);
- if (re->value)
- re->value->mark(e);
- Object::markObjects(that, e);
-}
-
Value *RegExpObject::lastIndexProperty()
{
Q_ASSERT(0 == internalClass()->find(engine()->id_lastIndex()));
@@ -303,15 +294,6 @@ void RegExpCtor::call(const Managed *that, Scope &scope, CallData *callData)
construct(that, scope, callData);
}
-void RegExpCtor::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- RegExpCtor::Data *This = static_cast<RegExpCtor::Data *>(that);
- This->lastMatch.mark(e);
- if (This->lastInput)
- This->lastInput->mark(e);
- FunctionObject::markObjects(that, e);
-}
-
void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
{
Scope scope(engine);
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index c0c7dfa78a..6726568eec 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -73,21 +73,28 @@ namespace QV4 {
namespace Heap {
-struct RegExpObject : Object {
+#define RegExpObjectMembers(class, Member) \
+ Member(class, Pointer<RegExp>, value) \
+ Member(class, bool, global)
+
+DECLARE_HEAP_OBJECT(RegExpObject, Object) {
+ DECLARE_MARK_TABLE(RegExpObject);
+
void init();
void init(QV4::RegExp *value, bool global);
void init(const QRegExp &re);
-
- Pointer<RegExp> value;
- bool global;
};
-struct RegExpCtor : FunctionObject {
+#define RegExpCtorMembers(class, Member) \
+ Member(class, Value, lastMatch) \
+ Member(class, Pointer<String>, lastInput) \
+ Member(class, int, lastMatchStart) \
+ Member(class, int, lastMatchEnd)
+
+DECLARE_HEAP_OBJECT(RegExpCtor, FunctionObject) {
+ DECLARE_MARK_TABLE(RegExpCtor);
+
void init(QV4::ExecutionContext *scope);
- Value lastMatch;
- Pointer<String> lastInput;
- int lastMatchStart;
- int lastMatchEnd;
void clearLastMatch();
};
@@ -126,9 +133,6 @@ struct RegExpObject: Object {
QString toString() const;
QString source() const;
uint flags() const;
-
-protected:
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
struct RegExpCtor: FunctionObject
@@ -142,7 +146,6 @@ struct RegExpCtor: FunctionObject
static void construct(const Managed *m, Scope &scope, CallData *callData);
static void call(const Managed *that, Scope &scope, CallData *callData);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
struct RegExpPrototype: RegExpObject
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 72be11eca0..c6cc5a4639 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -145,13 +145,6 @@ void StringObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name,
return Object::advanceIterator(m, it, name, index, p, attrs);
}
-void StringObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- StringObject::Data *o = static_cast<StringObject::Data *>(that);
- o->string->mark(e);
- Object::markObjects(that, e);
-}
-
DEFINE_OBJECT_VTABLE(StringCtor);
void Heap::StringCtor::init(QV4::ExecutionContext *scope)
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index aed3bc1e28..ae9377abb4 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -60,14 +60,18 @@ namespace QV4 {
namespace Heap {
-struct StringObject : Object {
+#define StringObjectMembers(class, Member) \
+ Member(class, Pointer<String>, string)
+
+DECLARE_HEAP_OBJECT(StringObject, Object) {
+ DECLARE_MARK_TABLE(StringObject);
+
enum {
LengthPropertyIndex = 0
};
void init();
void init(const QV4::String *string);
- String *string;
Heap::String *getIndex(uint index) const;
uint length() const;
@@ -96,7 +100,6 @@ struct StringObject: Object {
protected:
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
struct StringCtor: FunctionObject
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 5573a2e57f..e936158ab1 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -375,12 +375,6 @@ Heap::TypedArray *TypedArray::create(ExecutionEngine *e, Heap::TypedArray::Type
return e->memoryManager->allocObject<TypedArray>(e->emptyClass, e->typedArrayPrototype + t, t);
}
-void TypedArray::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- static_cast<TypedArray::Data *>(that)->buffer->mark(e);
- Object::markObjects(that, e);
-}
-
ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
Scope scope(static_cast<const Object *>(m)->engine());
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index fbf13c9815..f6b302a396 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -72,7 +72,15 @@ struct TypedArrayOperations {
namespace Heap {
-struct TypedArray : Object {
+#define TypedArrayMembers(class, Member) \
+ Member(class, Pointer<ArrayBuffer>, buffer) \
+ Member(class, const TypedArrayOperations *, type) \
+ Member(class, uint, byteLength) \
+ Member(class, uint, byteOffset) \
+ Member(class, uint, arrayType)
+
+DECLARE_HEAP_OBJECT(TypedArray, Object) {
+ DECLARE_MARK_TABLE(TypedArray);
enum Type {
Int8Array,
UInt8Array,
@@ -87,12 +95,6 @@ struct TypedArray : Object {
};
void init(Type t);
-
- const TypedArrayOperations *type;
- Pointer<ArrayBuffer> buffer;
- uint byteLength;
- uint byteOffset;
- Type arrayType;
};
struct TypedArrayCtor : FunctionObject {
@@ -128,10 +130,9 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object
}
Heap::TypedArray::Type arrayType() const {
- return d()->arrayType;
+ return static_cast<Heap::TypedArray::Type>(d()->arrayType);
}
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static bool putIndexed(Managed *m, uint index, const Value &value);
};