From 878b11e0a94e892c0377bca01b49706c150926ed Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 1 Nov 2014 20:56:47 +0100 Subject: Let markObjects() operate directly on HeapObjects This decouples things a bit better and helps moving over to directly store heapobject pointers in other objects. Change-Id: I798f922e018b0a3ca6f8768e4a810187f34d82f6 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4argumentsobject.cpp | 10 +++---- src/qml/jsruntime/qv4argumentsobject_p.h | 2 +- src/qml/jsruntime/qv4arraydata.cpp | 16 +++++----- src/qml/jsruntime/qv4arraydata_p.h | 4 +-- src/qml/jsruntime/qv4context.cpp | 50 ++++++++++++++++---------------- src/qml/jsruntime/qv4context_p.h | 2 +- src/qml/jsruntime/qv4dataview.cpp | 6 ++-- src/qml/jsruntime/qv4dataview_p.h | 2 +- src/qml/jsruntime/qv4engine.cpp | 2 +- src/qml/jsruntime/qv4engine_p.h | 20 ++++++++++--- src/qml/jsruntime/qv4errorobject.cpp | 8 ++--- src/qml/jsruntime/qv4errorobject_p.h | 2 +- src/qml/jsruntime/qv4functionobject.cpp | 18 ++++++------ src/qml/jsruntime/qv4functionobject_p.h | 4 +-- src/qml/jsruntime/qv4global_p.h | 1 + src/qml/jsruntime/qv4identifiertable_p.h | 2 +- src/qml/jsruntime/qv4managed.cpp | 2 +- src/qml/jsruntime/qv4managed_p.h | 37 +++-------------------- src/qml/jsruntime/qv4memberdata.cpp | 8 ++--- src/qml/jsruntime/qv4memberdata_p.h | 2 +- src/qml/jsruntime/qv4mm.cpp | 6 ++-- src/qml/jsruntime/qv4object.cpp | 10 +++---- src/qml/jsruntime/qv4object_p.h | 2 +- src/qml/jsruntime/qv4objectiterator.cpp | 8 ++--- src/qml/jsruntime/qv4objectiterator_p.h | 2 +- src/qml/jsruntime/qv4qobjectwrapper.cpp | 6 ++-- src/qml/jsruntime/qv4qobjectwrapper_p.h | 2 +- src/qml/jsruntime/qv4regexp.cpp | 2 +- src/qml/jsruntime/qv4regexp_p.h | 2 +- src/qml/jsruntime/qv4regexpobject.cpp | 16 +++++----- src/qml/jsruntime/qv4regexpobject_p.h | 4 +-- src/qml/jsruntime/qv4script.cpp | 12 ++++---- src/qml/jsruntime/qv4script_p.h | 2 +- src/qml/jsruntime/qv4string.cpp | 10 +++---- src/qml/jsruntime/qv4string_p.h | 2 +- src/qml/jsruntime/qv4stringobject.cpp | 8 ++--- src/qml/jsruntime/qv4stringobject_p.h | 2 +- src/qml/jsruntime/qv4typedarray.cpp | 5 ++-- src/qml/jsruntime/qv4typedarray_p.h | 2 +- src/qml/jsruntime/qv4value_p.h | 41 +++++++++++++++++++++++++- 40 files changed, 183 insertions(+), 159 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index a83e20a4d3..e8cb788b74 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -222,12 +222,12 @@ ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData) return Encode::undefined(); } -void ArgumentsObject::markObjects(Managed *that, ExecutionEngine *e) +void ArgumentsObject::markObjects(HeapObject *that, ExecutionEngine *e) { - ArgumentsObject *o = static_cast(that); - if (o->context()) - o->context()->mark(e); - o->mappedArguments().mark(e); + ArgumentsObject::Data *o = static_cast(that); + if (o->context) + o->context->mark(e); + o->mappedArguments.mark(e); Object::markObjects(that, e); } diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index 786cb36d0a..73c6bb26f3 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -106,7 +106,7 @@ struct ArgumentsObject: Object { static void putIndexed(Managed *m, uint index, const ValueRef value); static bool deleteIndexedProperty(Managed *m, uint index); static PropertyAttributes queryIndexed(const Managed *m, uint index); - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); void fullyCreate(); }; diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 12bffef04e..5aaed1a98d 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -213,12 +213,12 @@ void ArrayData::ensureAttributes(Object *o) } -void SimpleArrayData::markObjects(Managed *d, ExecutionEngine *e) +void SimpleArrayData::markObjects(HeapObject *d, ExecutionEngine *e) { - SimpleArrayData *dd = static_cast(d); - uint l = dd->len(); + SimpleArrayData::Data *dd = static_cast(d); + uint l = dd->len; for (uint i = 0; i < l; ++i) - dd->data(i).mark(e); + dd->arrayData[i].mark(e); } ReturnedValue SimpleArrayData::get(const ArrayData *d, uint index) @@ -363,12 +363,12 @@ void SparseArrayData::destroy(Managed *d) delete dd->sparse(); } -void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e) +void SparseArrayData::markObjects(HeapObject *d, ExecutionEngine *e) { - SparseArrayData *dd = static_cast(d); - uint l = dd->alloc(); + SparseArrayData::Data *dd = static_cast(d); + uint l = dd->alloc; for (uint i = 0; i < l; ++i) - dd->arrayData()[i].mark(e); + dd->arrayData[i].mark(e); } ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes) diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index b69d200665..5286be875b 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -172,7 +172,7 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes); - static void markObjects(Managed *d, ExecutionEngine *e); + static void markObjects(HeapObject *d, ExecutionEngine *e); static ReturnedValue get(const ArrayData *d, uint index); static bool put(Object *o, uint index, ValueRef value); @@ -218,7 +218,7 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData } static void destroy(Managed *d); - static void markObjects(Managed *d, ExecutionEngine *e); + static void markObjects(HeapObject *d, ExecutionEngine *e); static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes); static ReturnedValue get(const ArrayData *d, uint index); diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 0d9c047521..2dc8e8b608 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -246,35 +246,35 @@ bool CallContext::needsOwnArguments() const return d()->function->needsActivation() || d()->callData->argc < static_cast(d()->function->formalParameterCount()); } -void ExecutionContext::markObjects(Managed *m, ExecutionEngine *engine) +void ExecutionContext::markObjects(HeapObject *m, ExecutionEngine *engine) { - ExecutionContext *ctx = static_cast(m); + ExecutionContext::Data *ctx = static_cast(m); - if (ctx->d()->outer) - ctx->d()->outer->mark(engine); + if (ctx->outer) + ctx->outer->mark(engine); // ### shouldn't need these 3 lines - ctx->d()->callData->thisObject.mark(engine); - for (int arg = 0; arg < ctx->d()->callData->argc; ++arg) - ctx->d()->callData->args[arg].mark(engine); - - if (ctx->d()->type >= Type_CallContext) { - QV4::CallContext *c = static_cast(ctx); - for (unsigned local = 0, lastLocal = c->d()->function->varCount(); local < lastLocal; ++local) - c->d()->locals[local].mark(engine); - if (c->d()->activation) - c->d()->activation->mark(engine); - c->d()->function->mark(engine); - } else if (ctx->d()->type == Type_WithContext) { - WithContext *w = static_cast(ctx); - w->d()->withObject->mark(engine); - } else if (ctx->d()->type == Type_CatchContext) { - CatchContext *c = static_cast(ctx); - c->d()->exceptionVarName->mark(engine); - c->d()->exceptionValue.mark(engine); - } else if (ctx->d()->type == Type_GlobalContext) { - GlobalContext *g = static_cast(ctx); - g->d()->global->mark(engine); + ctx->callData->thisObject.mark(engine); + for (int arg = 0; arg < ctx->callData->argc; ++arg) + ctx->callData->args[arg].mark(engine); + + if (ctx->type >= Type_CallContext) { + QV4::CallContext::Data *c = static_cast(ctx); + for (unsigned local = 0, lastLocal = c->function->varCount(); local < lastLocal; ++local) + c->locals[local].mark(engine); + if (c->activation) + c->activation->mark(engine); + c->function->mark(engine); + } else if (ctx->type == Type_WithContext) { + WithContext::Data *w = static_cast(ctx); + w->withObject->mark(engine); + } else if (ctx->type == Type_CatchContext) { + CatchContext::Data *c = static_cast(ctx); + c->exceptionVarName->mark(engine); + c->exceptionValue.mark(engine); + } else if (ctx->type == Type_GlobalContext) { + GlobalContext::Data *g = static_cast(ctx); + g->global->mark(engine); } } diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 4f0f16b357..a942c12f6c 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -137,7 +137,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed inline CallContext *asCallContext(); inline const CallContext *asCallContext() const; - static void markObjects(Managed *m, ExecutionEngine *e); + static void markObjects(HeapObject *m, ExecutionEngine *e); }; struct CallContext : public ExecutionContext diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index 717a8f681f..11cb04e22f 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -85,10 +85,10 @@ DataView::Data::Data(ExecutionEngine *e) } -void DataView::markObjects(Managed *that, ExecutionEngine *e) +void DataView::markObjects(HeapObject *that, ExecutionEngine *e) { - DataView *v = static_cast(that); - v->d()->buffer->mark(e); + DataView::Data *v = static_cast(that); + v->buffer->mark(e); } void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor) diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h index aa8a0201d9..b1c2e361f4 100644 --- a/src/qml/jsruntime/qv4dataview_p.h +++ b/src/qml/jsruntime/qv4dataview_p.h @@ -64,7 +64,7 @@ struct DataView : Object }; V4_OBJECT(Object) - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; struct DataViewPrototype: Object diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index f72c2f8071..c47420583c 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -885,7 +885,7 @@ void ExecutionEngine::markObjects() Q_ASSERT(c->inUse()); if (!c->markBit()) { c->d()->markBit = 1; - c->markObjects(c, this); + c->markObjects(c->d(), this); } c = c->d()->parent; } diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 6186c3c3d8..1da54b1129 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -152,13 +152,13 @@ public: jsStackTop -= nValues; } - void pushForGC(Managed *m) { - *jsStackTop = Value::fromManaged(m); + void pushForGC(HeapObject *m) { + *jsStackTop = Value::fromHeapObject(m); ++jsStackTop; } - Managed *popForGC() { + HeapObject *popForGC() { --jsStackTop; - return jsStackTop->managed(); + return jsStackTop->heapObject(); } IdentifierTable *identifierTable; @@ -386,6 +386,7 @@ private: QmlExtensions *m_qmlExtensions; }; +// ### Remove me inline void Managed::mark(QV4::ExecutionEngine *engine) { @@ -393,6 +394,17 @@ void Managed::mark(QV4::ExecutionEngine *engine) if (markBit()) return; d()->markBit = 1; + engine->pushForGC(d()); +} + + +inline +void HeapObject::mark(QV4::ExecutionEngine *engine) +{ + Q_ASSERT(inUse); + if (markBit) + return; + markBit = 1; engine->pushForGC(this); } diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index 19b5a8097f..ef664f2830 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -170,11 +170,11 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx) return This->d()->stack->asReturnedValue(); } -void ErrorObject::markObjects(Managed *that, ExecutionEngine *e) +void ErrorObject::markObjects(HeapObject *that, ExecutionEngine *e) { - ErrorObject *This = that->asErrorObject(); - if (This->d()->stack) - This->d()->stack->mark(e); + ErrorObject::Data *This = static_cast(that); + if (This->stack) + This->stack->mark(e); Object::markObjects(that, e); } diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index 6070fe6210..bb31b505e8 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -70,7 +70,7 @@ struct ErrorObject: Object { SyntaxErrorObject *asSyntaxError(); static ReturnedValue method_get_stack(CallContext *ctx); - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); static void destroy(Managed *that) { static_cast(that)->~ErrorObject(); } }; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 417aaff756..deb9e62591 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -152,11 +152,11 @@ ReturnedValue FunctionObject::call(Managed *, CallData *) return Encode::undefined(); } -void FunctionObject::markObjects(Managed *that, ExecutionEngine *e) +void FunctionObject::markObjects(HeapObject *that, ExecutionEngine *e) { - FunctionObject *o = static_cast(that); - if (o->scope()) - o->scope()->mark(e); + FunctionObject::Data *o = static_cast(that); + if (o->scope) + o->scope->mark(e); Object::markObjects(that, e); } @@ -637,11 +637,11 @@ ReturnedValue BoundFunction::construct(Managed *that, CallData *dd) return f->target()->construct(callData); } -void BoundFunction::markObjects(Managed *that, ExecutionEngine *e) +void BoundFunction::markObjects(HeapObject *that, ExecutionEngine *e) { - BoundFunction *o = static_cast(that); - o->target()->mark(e); - o->boundThis().mark(e); - o->boundArgs().mark(e); + BoundFunction::Data *o = static_cast(that); + o->target->mark(e); + o->boundThis.mark(e); + 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 fc57ac0dfe..1ff8124e6a 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -102,7 +102,7 @@ struct Q_QML_EXPORT FunctionObject: Object { bool strictMode() const { return d()->strictMode; } bool bindingKeyFlag() const { return d()->bindingKeyFlag; } - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; template<> @@ -221,7 +221,7 @@ struct BoundFunction: FunctionObject { static ReturnedValue construct(Managed *, CallData *d); static ReturnedValue call(Managed *that, CallData *dd); - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; } diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index f265ed5f4f..71f217395b 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -129,6 +129,7 @@ struct Value; struct Lookup; struct HeapObject; struct ArrayData; +struct ManagedVTable; struct BooleanObject; struct NumberObject; diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h index 6ae2ec06d6..cc792fa3b4 100644 --- a/src/qml/jsruntime/qv4identifiertable_p.h +++ b/src/qml/jsruntime/qv4identifiertable_p.h @@ -78,7 +78,7 @@ public: continue; entry->d()->markBit = 1; Q_ASSERT(entry->internalClass()->vtable->markObjects); - entry->internalClass()->vtable->markObjects(entry, e); + entry->internalClass()->vtable->markObjects(entry->d(), e); } } }; diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index c7327addfd..93286b3945 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -157,7 +157,7 @@ void Managed::setVTable(const ManagedVTable *vt) d()->internalClass = internalClass()->changeVTable(vt); } -void Managed::Data::setVTable(const ManagedVTable *vt) +void HeapObject::setVTable(const ManagedVTable *vt) { Q_ASSERT(internalClass); internalClass = internalClass->changeVTable(vt); diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index e382ad2739..91dc0fb034 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -110,7 +110,7 @@ struct ManagedVTable uint type : 8; const char *className; void (*destroy)(Managed *); - void (*markObjects)(Managed *, ExecutionEngine *e); + void (*markObjects)(HeapObject *, ExecutionEngine *e); bool (*isEqualTo)(Managed *m, Managed *other); }; @@ -177,39 +177,10 @@ const QV4::ObjectVTable classname::static_vtbl = \ struct Q_QML_PRIVATE_EXPORT Managed { struct Q_QML_PRIVATE_EXPORT Data : HeapObject { - Data() {} + Data() : HeapObject(0) {} Data(InternalClass *internal) - : internalClass(internal) - , markBit(0) - , inUse(1) - , extensible(1) - { - // #### -// Q_ASSERT(internal && internal->vtable); - } - InternalClass *internalClass; - struct { - uchar markBit : 1; - uchar inUse : 1; - uchar extensible : 1; // used by Object - uchar _unused : 1; - uchar needsActivation : 1; // used by FunctionObject - uchar strictMode : 1; // used by FunctionObject - uchar bindingKeyFlag : 1; - uchar hasAccessorProperty : 1; - uchar _type; - mutable uchar subtype; - uchar _flags; - }; - - void setVTable(const ManagedVTable *vt); - ReturnedValue asReturnedValue() const { - return Value::fromHeapObject(const_cast(this)).asReturnedValue(); - } - - void *operator new(size_t, Managed *m) { return m; } - void *operator new(size_t, Managed::Data *m) { return m; } - void operator delete(void *, Managed::Data *) {} + : HeapObject(internal) + {} }; Data data; V4_MANAGED(Managed) diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp index 418323445a..de226305f1 100644 --- a/src/qml/jsruntime/qv4memberdata.cpp +++ b/src/qml/jsruntime/qv4memberdata.cpp @@ -38,11 +38,11 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(MemberData); -void MemberData::markObjects(Managed *that, ExecutionEngine *e) +void MemberData::markObjects(HeapObject *that, ExecutionEngine *e) { - MemberData *m = static_cast(that); - for (uint i = 0; i < m->d()->size; ++i) - m->d()->data[i].mark(e); + MemberData::Data *m = static_cast(that); + for (uint i = 0; i < m->size; ++i) + m->data[i].mark(e); } void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx) diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h index 83732113a9..cc7b10ff81 100644 --- a/src/qml/jsruntime/qv4memberdata_p.h +++ b/src/qml/jsruntime/qv4memberdata_p.h @@ -54,7 +54,7 @@ struct MemberData : Managed MemberData(QV4::InternalClass *ic) : Managed(ic) {} Value &operator[] (uint idx) { return d()->data[idx]; } - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; struct Members : Value diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index 8174fa93ec..df439e1c5e 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -264,9 +264,9 @@ Managed *MemoryManager::allocData(std::size_t size) static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase) { while (engine->jsStackTop > markBase) { - Managed *m = engine->popForGC(); - Q_ASSERT (m->internalClass()->vtable->markObjects); - m->internalClass()->vtable->markObjects(m, engine); + HeapObject *h = engine->popForGC(); + Q_ASSERT (h->internalClass->vtable->markObjects); + h->internalClass->vtable->markObjects(h, engine); } } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 5d003ba287..576537dcef 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -178,13 +178,13 @@ void Object::defineReadonlyProperty(String *name, ValueRef value) insertMember(name, value, Attr_ReadOnly); } -void Object::markObjects(Managed *that, ExecutionEngine *e) +void Object::markObjects(HeapObject *that, ExecutionEngine *e) { - Object *o = static_cast(that); + Object::Data *o = static_cast(that); - o->memberData().mark(e); - if (o->arrayData()) - o->arrayData()->mark(e); + o->memberData.mark(e); + if (o->arrayData) + o->arrayData->mark(e); } void Object::ensureMemberIndex(uint idx) diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index d57d1bf0f8..f11220f55c 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -224,7 +224,7 @@ public: inline ReturnedValue call(CallData *d) { return vtable()->call(this, d); } protected: - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); static ReturnedValue construct(Managed *m, CallData *); static ReturnedValue call(Managed *m, CallData *); static ReturnedValue get(Managed *m, String *name, bool *hasProperty); diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index b2875a192d..e0f7087437 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -210,10 +210,10 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString() DEFINE_OBJECT_VTABLE(ForEachIteratorObject); -void ForEachIteratorObject::markObjects(Managed *that, ExecutionEngine *e) +void ForEachIteratorObject::markObjects(HeapObject *that, ExecutionEngine *e) { - ForEachIteratorObject *o = static_cast(that); - o->d()->workArea[0].mark(e); - o->d()->workArea[1].mark(e); + ForEachIteratorObject::Data *o = static_cast(that); + o->workArea[0].mark(e); + o->workArea[1].mark(e); Object::markObjects(that, e); } diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h index 24efd7eb86..10f75a1e0d 100644 --- a/src/qml/jsruntime/qv4objectiterator_p.h +++ b/src/qml/jsruntime/qv4objectiterator_p.h @@ -83,7 +83,7 @@ struct ForEachIteratorObject: Object { ReturnedValue nextPropertyName() { return d()->it.nextPropertyNameAsString(); } protected: - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 77bfc24a29..cf59fe027c 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -985,11 +985,11 @@ static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine * } } -void QObjectWrapper::markObjects(Managed *that, QV4::ExecutionEngine *e) +void QObjectWrapper::markObjects(HeapObject *that, QV4::ExecutionEngine *e) { - QObjectWrapper *This = static_cast(that); + QObjectWrapper::Data *This = static_cast(that); - if (QObject *o = This->d()->object.data()) { + if (QObject *o = This->object.data()) { QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(o); if (vme) vme->mark(e); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 1a31b5af4b..6458f03037 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -108,7 +108,7 @@ private: static void put(Managed *m, String *name, const ValueRef value); static PropertyAttributes query(const Managed *, String *name); static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes); - static void markObjects(Managed *that, QV4::ExecutionEngine *e); + static void markObjects(HeapObject *that, QV4::ExecutionEngine *e); static void destroy(Managed *that); static ReturnedValue method_connect(CallContext *ctx); diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index 4c33424f0b..659221b0d9 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -119,7 +119,7 @@ void RegExp::destroy(Managed *that) static_cast(that)->d()->~Data(); } -void RegExp::markObjects(Managed *that, ExecutionEngine *e) +void RegExp::markObjects(HeapObject *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 a46dd980f9..7aad1a32f2 100644 --- a/src/qml/jsruntime/qv4regexp_p.h +++ b/src/qml/jsruntime/qv4regexp_p.h @@ -94,7 +94,7 @@ struct RegExp : public Managed int captureCount() const { return subPatternCount() + 1; } static void destroy(Managed *that); - static void markObjects(Managed *that, QV4::ExecutionEngine *e); + static void markObjects(HeapObject *that, QV4::ExecutionEngine *e); friend class RegExpCache; }; diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index b16a6bd875..23b46c8492 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -170,11 +170,11 @@ void RegExpObject::init(ExecutionEngine *engine) } -void RegExpObject::markObjects(Managed *that, ExecutionEngine *e) +void RegExpObject::markObjects(HeapObject *that, ExecutionEngine *e) { - RegExpObject *re = static_cast(that); - if (re->value()) - re->value()->mark(e); + RegExpObject::Data *re = static_cast(that); + if (re->value) + re->value->mark(e); Object::markObjects(that, e); } @@ -303,11 +303,11 @@ ReturnedValue RegExpCtor::call(Managed *that, CallData *callData) return construct(that, callData); } -void RegExpCtor::markObjects(Managed *that, ExecutionEngine *e) +void RegExpCtor::markObjects(HeapObject *that, ExecutionEngine *e) { - RegExpCtor *This = static_cast(that); - This->lastMatch().mark(e); - This->lastInput().mark(e); + RegExpCtor::Data *This = static_cast(that); + This->lastMatch.mark(e); + This->lastInput.mark(e); FunctionObject::markObjects(that, e); } diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index e2f8049157..cf59ca12c0 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -91,7 +91,7 @@ struct RegExpObject: Object { uint flags() const; protected: - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; struct RegExpCtor: FunctionObject @@ -113,7 +113,7 @@ struct RegExpCtor: FunctionObject static ReturnedValue construct(Managed *m, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; struct RegExpPrototype: RegExpObject diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index a3454d8dc6..5c0c3f32ff 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -111,14 +111,14 @@ ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *) return result.asReturnedValue(); } -void QmlBindingWrapper::markObjects(Managed *m, ExecutionEngine *e) +void QmlBindingWrapper::markObjects(HeapObject *m, ExecutionEngine *e) { - QmlBindingWrapper *wrapper = static_cast(m); - if (wrapper->d()->qml) - wrapper->d()->qml->mark(e); + QmlBindingWrapper::Data *wrapper = static_cast(m); + if (wrapper->qml) + wrapper->qml->mark(e); FunctionObject::markObjects(m, e); - if (wrapper->d()->qmlContext) - wrapper->d()->qmlContext->mark(e); + if (wrapper->qmlContext) + wrapper->qmlContext->mark(e); } static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex) diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index ed93ce49ae..f12d5ad6fc 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -82,7 +82,7 @@ struct Q_QML_EXPORT QmlBindingWrapper : FunctionObject { V4_OBJECT(FunctionObject) static ReturnedValue call(Managed *that, CallData *); - static void markObjects(Managed *m, ExecutionEngine *e); + static void markObjects(HeapObject *m, ExecutionEngine *e); CallContext *context() const { return d()->qmlContext; } diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index bd8a5ffccb..4ae10f6506 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -122,12 +122,12 @@ void String::destroy(Managed *that) static_cast(that)->d()->~Data(); } -void String::markObjects(Managed *that, ExecutionEngine *e) +void String::markObjects(HeapObject *that, ExecutionEngine *e) { - String *s = static_cast(that); - if (s->d()->largestSubLength) { - s->d()->left->mark(e); - s->d()->right->mark(e); + String::Data *s = static_cast(that); + if (s->largestSubLength) { + s->left->mark(e); + s->right->mark(e); } } diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 901a12c5a8..1e53132fe3 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -154,7 +154,7 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed { protected: static void destroy(Managed *); - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); static void put(Managed *m, String *name, const ValueRef value); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 0591a05b37..19ef7892ad 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -149,11 +149,11 @@ void StringObject::advanceIterator(Managed *m, ObjectIterator *it, String *&name return Object::advanceIterator(m, it, name, index, p, attrs); } -void StringObject::markObjects(Managed *that, ExecutionEngine *e) +void StringObject::markObjects(HeapObject *that, ExecutionEngine *e) { - StringObject *o = static_cast(that); - o->d()->value.stringValue()->mark(e); - o->d()->tmpProperty.value.mark(e); + StringObject::Data *o = static_cast(that); + o->value.stringValue()->mark(e); + o->tmpProperty.value.mark(e); Object::markObjects(that, e); } diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index 5d3c0c9ccb..28e944c791 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -59,7 +59,7 @@ struct StringObject: Object { protected: static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs); - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); }; struct StringCtor: FunctionObject diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index 06712831c2..72823efa12 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -339,9 +339,10 @@ TypedArray::Data::Data(ExecutionEngine *e, Type t) { } -void TypedArray::markObjects(Managed *that, ExecutionEngine *e) +void TypedArray::markObjects(HeapObject *that, ExecutionEngine *e) { - static_cast(that)->d()->buffer->mark(e); + static_cast(that)->buffer->mark(e); + Object::markObjects(that, e); } ReturnedValue TypedArray::getIndexed(Managed *m, uint index, bool *hasProperty) diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index deafb0eed8..28847e0c85 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -82,7 +82,7 @@ struct TypedArray : Object } - static void markObjects(Managed *that, ExecutionEngine *e); + static void markObjects(HeapObject *that, ExecutionEngine *e); static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); static void putIndexed(Managed *m, uint index, const ValueRef value); }; diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index bf8367c9eb..fa2d544fcf 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -44,7 +44,40 @@ namespace QV4 { typedef uint Bool; -struct HeapObject {}; +struct Q_QML_EXPORT HeapObject { + HeapObject(InternalClass *internal) + : internalClass(internal) + , markBit(0) + , inUse(1) + , extensible(1) + { + // #### + // Q_ASSERT(internal && internal->vtable); + } + InternalClass *internalClass; + struct { + uchar markBit : 1; + uchar inUse : 1; + uchar extensible : 1; // used by Object + uchar _unused : 1; + uchar needsActivation : 1; // used by FunctionObject + uchar strictMode : 1; // used by FunctionObject + uchar bindingKeyFlag : 1; + uchar hasAccessorProperty : 1; + uchar _type; + mutable uchar subtype; + uchar _flags; + + }; + + void setVTable(const ManagedVTable *vt); + inline ReturnedValue asReturnedValue() const; + inline void mark(QV4::ExecutionEngine *engine); + + void *operator new(size_t, Managed *m) { return m; } + void *operator new(size_t, HeapObject *m) { return m; } + void operator delete(void *, HeapObject *) {} +}; template struct Returned : private HeapObject @@ -547,6 +580,12 @@ private: Value *ptr; }; +inline +ReturnedValue HeapObject::asReturnedValue() const +{ + return Value::fromHeapObject(const_cast(this)).asReturnedValue(); +} + template T *value_cast(const Value &v) -- cgit v1.2.3