Move vtable out of internalClass
authorLars Knoll <lars.knoll@theqtcompany.com>
Sat, 10 Jan 2015 16:55:29 +0000 (17:55 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 20 Jan 2015 12:29:59 +0000 (13:29 +0100)
We can move the internalClass to Object later on, and such save
having the internalClass on lots of Heap objects.

This commit basically adds and starts making use of a new
vtable pointer in Heap::Base. In addition, the construction
methods in the memory manager now automatically setup the
correct vtable.

Removing the vtable code from InternalClass and moving it into
Object will come in a separate commit

Change-Id: If49e8d73c769bf65bf47fe4dbf8b9546c8019dbc
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
21 files changed:
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/jsruntime/qv4argumentsobject_p.h
src/qml/jsruntime/qv4arraydata.cpp
src/qml/jsruntime/qv4arraydata_p.h
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4identifiertable_p.h
src/qml/jsruntime/qv4managed.cpp
src/qml/jsruntime/qv4managed_p.h
src/qml/jsruntime/qv4memberdata.cpp
src/qml/jsruntime/qv4mm.cpp
src/qml/jsruntime/qv4mm_p.h
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4persistent.cpp
src/qml/jsruntime/qv4string.cpp
src/qml/jsruntime/qv4stringobject.cpp
src/qml/jsruntime/qv4value_inl_p.h
src/qml/jsruntime/qv4value_p.h
src/qml/qml/v8/qqmlbuiltinfunctions.cpp

index 33529db..48e8bb6 100644 (file)
@@ -44,7 +44,7 @@ Heap::ArgumentsObject::ArgumentsObject(QV4::CallContext *context)
     , context(context->d())
     , fullyCreated(false)
 {
-    Q_ASSERT(internalClass->vtable == QV4::ArgumentsObject::staticVTable());
+    Q_ASSERT(vtable == QV4::ArgumentsObject::staticVTable());
 
     ExecutionEngine *v4 = context->d()->engine;
     Scope scope(v4);
index dfa7ec4..bf5b532 100644 (file)
@@ -108,7 +108,7 @@ struct ArgumentsObject: Object {
     Heap::MemberData *mappedArguments() { return d()->mappedArguments; }
 
     static bool isNonStrictArgumentsObject(Managed *m) {
-        return m->internalClass()->vtable->type == Type_ArgumentsObject &&
+        return m->d()->vtable->type == Type_ArgumentsObject &&
                 !static_cast<ArgumentsObject *>(m)->context()->strictMode;
     }
 
index a4f67c7..f0fbc85 100644 (file)
@@ -128,13 +128,13 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
 
     Scoped<ArrayData> newData(scope);
     if (newType < Heap::ArrayData::Sparse) {
-        Heap::SimpleArrayData *n = static_cast<Heap::SimpleArrayData *>(scope.engine->memoryManager->allocManaged(size));
+        Heap::SimpleArrayData *n = scope.engine->memoryManager->allocManaged<SimpleArrayData>(size);
         new (n) Heap::SimpleArrayData(scope.engine);
         n->offset = 0;
         n->len = d ? d->d()->len : 0;
         newData = n;
     } else {
-        Heap::SparseArrayData *n = static_cast<Heap::SparseArrayData *>(scope.engine->memoryManager->allocManaged(size));
+        Heap::SparseArrayData *n = scope.engine->memoryManager->allocManaged<SparseArrayData>(size);
         new (n) Heap::SparseArrayData(scope.engine);
         newData = n;
     }
index 533d51c..2ba6ced 100644 (file)
@@ -42,14 +42,15 @@ QT_BEGIN_NAMESPACE
 
 namespace QV4 {
 
-#define V4_ARRAYDATA(Data) \
+#define V4_ARRAYDATA(DataClass) \
     public: \
         Q_MANAGED_CHECK \
+        typedef QV4::Heap::DataClass Data; \
         static const QV4::ArrayVTable static_vtbl; \
         static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
         V4_MANAGED_SIZE_TEST \
-        const QV4::Heap::Data *d() const { return static_cast<const QV4::Heap::Data *>(m); } \
-        QV4::Heap::Data *d() { return static_cast<QV4::Heap::Data *>(m); }
+        const Data *d() const { return static_cast<const Data *>(m); } \
+        Data *d() { return static_cast<Data *>(m); }
 
 
 struct ArrayData;
@@ -98,7 +99,7 @@ struct ArrayData : public Base {
 
     bool isSparse() const { return type == Sparse; }
 
-    const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass->vtable); }
+    const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(Base::vtable); }
 
     inline ReturnedValue get(uint i) const {
         return vtable()->get(this, i);
@@ -182,7 +183,7 @@ struct Q_QML_EXPORT ArrayData : public Managed
     const Value *arrayData() const { return &d()->arrayData[0]; }
     Value *arrayData() { return &d()->arrayData[0]; }
 
-    const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass()->vtable); }
+    const ArrayVTable *vtable() const { return d()->vtable(); }
     bool isSparse() const { return type() == Heap::ArrayData::Sparse; }
 
     uint length() const {
index 408ccf0..29f4278 100644 (file)
@@ -53,7 +53,7 @@ Heap::CallContext *ExecutionContext::newCallContext(FunctionObject *function, Ca
 {
     Q_ASSERT(function->function());
 
-    Heap::CallContext *c = static_cast<Heap::CallContext *>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(function, callData->argc)));
+    Heap::CallContext *c = d()->engine->memoryManager->allocManaged<CallContext>(requiredMemoryForExecutionContect(function, callData->argc));
     new (c) Heap::CallContext(d()->engine, Heap::ExecutionContext::Type_CallContext);
 
     c->function = function->d();
@@ -95,7 +95,7 @@ Heap::CatchContext *ExecutionContext::newCatchContext(String *exceptionVarName,
 Heap::CallContext *ExecutionContext::newQmlContext(FunctionObject *f, Object *qml)
 {
     Scope scope(this);
-    Scoped<CallContext> c(scope, static_cast<Heap::CallContext*>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0))));
+    Scoped<CallContext> c(scope, d()->engine->memoryManager->allocManaged<CallContext>(requiredMemoryForExecutionContect(f, 0)));
     new (c->d()) Heap::CallContext(d()->engine, qml, f);
     return c->d();
 }
index 3d3423b..0ee4daf 100644 (file)
@@ -306,7 +306,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     Q_ASSERT(strictArgumentsObjectClass->vtable == ArgumentsObject::staticVTable());
 
     m_globalObject = newObject();
-    Q_ASSERT(globalObject()->internalClass()->vtable);
+    Q_ASSERT(globalObject()->d()->vtable);
     initRootContext();
 
     stringPrototype = memoryManager->alloc<StringPrototype>(InternalClass::create(this, StringPrototype::staticVTable()), objectPrototype.asObject());
@@ -421,7 +421,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     //
     rootContext()->global = globalObject()->d();
     rootContext()->callData->thisObject = globalObject();
-    Q_ASSERT(globalObject()->internalClass()->vtable);
+    Q_ASSERT(globalObject()->d()->vtable);
 
     globalObject()->defineDefaultProperty(QStringLiteral("Object"), objectCtor);
     globalObject()->defineDefaultProperty(QStringLiteral("String"), stringCtor);
@@ -515,7 +515,7 @@ void ExecutionEngine::enableProfiler()
 void ExecutionEngine::initRootContext()
 {
     Scope scope(this);
-    Scoped<GlobalContext> r(scope, static_cast<Heap::GlobalContext*>(memoryManager->allocManaged(sizeof(GlobalContext::Data) + sizeof(CallData))));
+    Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>(sizeof(GlobalContext::Data) + sizeof(CallData)));
     new (r->d()) GlobalContext::Data(this);
     r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1);
     r->d()->callData->tag = QV4::Value::_Integer_Type;
@@ -913,7 +913,7 @@ void ExecutionEngine::markObjects()
         Q_ASSERT(c->inUse());
         if (!c->isMarked()) {
             c->setMarkBit();
-            c->gcGetInternalClass()->vtable->markObjects(c, this);
+            c->gcGetVtable()->markObjects(c, this);
         }
         c = c->parent;
     }
index e74acf7..3f06776 100644 (file)
@@ -203,12 +203,12 @@ Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *sco
 
 bool FunctionObject::isBinding() const
 {
-    return d()->internalClass->vtable == QQmlBindingFunction::staticVTable();
+    return d()->vtable == QQmlBindingFunction::staticVTable();
 }
 
 bool FunctionObject::isBoundFunction() const
 {
-    return d()->internalClass->vtable == BoundFunction::staticVTable();
+    return d()->vtable == BoundFunction::staticVTable();
 }
 
 DEFINE_OBJECT_VTABLE(FunctionCtor);
@@ -494,6 +494,7 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
     ExecutionContextSaver ctxSaver(scope, v4->currentContext());
 
     CallContext::Data ctx(v4);
+    ctx.vtable = CallContext::staticVTable();
     ctx.strictMode = f->strictMode();
     ctx.callData = callData;
     ctx.function = f->d();
@@ -530,6 +531,7 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
     ExecutionContextSaver ctxSaver(scope, v4->currentContext());
 
     CallContext::Data ctx(v4);
+    ctx.vtable = CallContext::staticVTable();
     ctx.strictMode = f->strictMode();
     ctx.callData = callData;
     ctx.function = f->d();
@@ -588,6 +590,7 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
     ExecutionContextSaver ctxSaver(scope, v4->currentContext());
 
     CallContext::Data ctx(v4);
+    ctx.vtable = CallContext::staticVTable();
     ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
     ctx.callData = callData;
     Q_ASSERT(v4->currentContext() == &ctx);
@@ -608,6 +611,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
     ExecutionContextSaver ctxSaver(scope, v4->currentContext());
 
     CallContext::Data ctx(v4);
+    ctx.vtable = CallContext::staticVTable();
     ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
     ctx.callData = callData;
     Q_ASSERT(v4->currentContext() == &ctx);
index 5d29d44..7bcf224 100644 (file)
@@ -80,8 +80,8 @@ public:
             if (!entry || entry->isMarked())
                 continue;
             entry->setMarkBit();
-            Q_ASSERT(entry->gcGetInternalClass()->vtable->markObjects);
-            entry->gcGetInternalClass()->vtable->markObjects(entry, e);
+            Q_ASSERT(entry->gcGetVtable()->markObjects);
+            entry->gcGetVtable()->markObjects(entry, e);
         }
     }
 };
index 668e7d2..f784f4a 100644 (file)
@@ -56,13 +56,6 @@ const ManagedVTable Managed::static_vtbl =
 };
 
 
-void *Managed::operator new(size_t size, MemoryManager *mm)
-{
-    assert(mm);
-
-    return mm->allocManaged(size);
-}
-
 ExecutionEngine *Managed::engine() const
 {
     return internalClass()->engine;
@@ -71,7 +64,7 @@ ExecutionEngine *Managed::engine() const
 QString Managed::className() const
 {
     const char *s = 0;
-    switch (Type(internalClass()->vtable->type)) {
+    switch (Type(d()->vtable->type)) {
     case Type_Invalid:
     case Type_String:
         return QString();
@@ -153,12 +146,14 @@ QString Managed::className() const
 
 void Managed::setVTable(const ManagedVTable *vt)
 {
+    d()->vtable = vt;
     Q_ASSERT(internalClass());
     d()->internalClass = internalClass()->changeVTable(vt);
 }
 
 void Heap::Base::setVTable(const ManagedVTable *vt)
 {
+    vtable = vt;
     Q_ASSERT(internalClass);
     internalClass = internalClass->changeVTable(vt);
 }
index fad3b85..69d8144 100644 (file)
@@ -237,7 +237,7 @@ public:
 #if !defined(QT_NO_QOBJECT_CHECK)
         static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(this));
 #endif
-        const ManagedVTable *vt = internalClass()->vtable;
+        const ManagedVTable *vt = d()->vtable;
         while (vt) {
             if (vt == T::staticVTable())
                 return static_cast<T *>(this);
@@ -251,7 +251,7 @@ public:
 #if !defined(QT_NO_QOBJECT_CHECK)
         static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(const_cast<Managed *>(this)));
 #endif
-        const ManagedVTable *vt = internalClass()->vtable;
+        const ManagedVTable *vt = d()->vtable;
         while (vt) {
             if (vt == T::staticVTable())
                 return static_cast<T *>(this);
@@ -260,28 +260,28 @@ public:
         return 0;
     }
 
-    String *asString() { return internalClass()->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
-    Object *asObject() { return internalClass()->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
-    ArrayObject *asArrayObject() { return internalClass()->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
-    FunctionObject *asFunctionObject() { return internalClass()->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
-    BooleanObject *asBooleanObject() { return internalClass()->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
-    NumberObject *asNumberObject() { return internalClass()->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
-    StringObject *asStringObject() { return internalClass()->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
-    DateObject *asDateObject() { return internalClass()->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
-    ErrorObject *asErrorObject() { return internalClass()->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
-    ArgumentsObject *asArgumentsObject() { return internalClass()->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
+    String *asString() { return d()->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
+    Object *asObject() { return d()->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
+    ArrayObject *asArrayObject() { return d()->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
+    FunctionObject *asFunctionObject() { return d()->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
+    BooleanObject *asBooleanObject() { return d()->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
+    NumberObject *asNumberObject() { return d()->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
+    StringObject *asStringObject() { return d()->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
+    DateObject *asDateObject() { return d()->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
+    ErrorObject *asErrorObject() { return d()->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
+    ArgumentsObject *asArgumentsObject() { return d()->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
 
-    bool isListType() const { return internalClass()->vtable->type == Type_QmlSequence; }
+    bool isListType() const { return d()->vtable->type == Type_QmlSequence; }
 
-    bool isArrayObject() const { return internalClass()->vtable->type == Type_ArrayObject; }
-    bool isStringObject() const { return internalClass()->vtable->type == Type_StringObject; }
+    bool isArrayObject() const { return d()->vtable->type == Type_ArrayObject; }
+    bool isStringObject() const { return d()->vtable->type == Type_StringObject; }
 
     QString className() const;
 
     void setVTable(const ManagedVTable *vt);
 
     bool isEqualTo(const Managed *other) const
-    { return internalClass()->vtable->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
+    { return d()->vtable->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
 
     static bool isEqualTo(Managed *m, Managed *other);
 
index d4e196f..2cdf901 100644 (file)
@@ -54,7 +54,7 @@ Heap::MemberData *MemberData::reallocate(ExecutionEngine *e, Heap::MemberData *o
     int newAlloc = qMax((uint)4, 2*idx);
     uint alloc = sizeof(Heap::MemberData) + (newAlloc)*sizeof(Value);
     Scope scope(e);
-    Scoped<MemberData> newMemberData(scope, static_cast<Heap::MemberData *>(e->memoryManager->allocManaged(alloc)));
+    Scoped<MemberData> newMemberData(scope, e->memoryManager->allocManaged<MemberData>(alloc));
     if (old)
         memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + s*sizeof(Value));
     else
index f4c3d93..66b291d 100644 (file)
@@ -183,8 +183,8 @@ bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, Exec
 #ifdef V4_USE_VALGRIND
                 VALGRIND_ENABLE_ERROR_REPORTING;
 #endif
-                if (m->gcGetInternalClass()->vtable->destroy)
-                    m->gcGetInternalClass()->vtable->destroy(m);
+                if (m->gcGetVtable()->destroy)
+                    m->gcGetVtable()->destroy(m);
 
                 memset(m, 0, header->itemSize);
 #ifdef V4_USE_VALGRIND
@@ -324,8 +324,8 @@ static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
 {
     while (engine->jsStackTop > markBase) {
         Heap::Base *h = engine->popForGC();
-        Q_ASSERT (h->gcGetInternalClass()->vtable->markObjects);
-        h->gcGetInternalClass()->vtable->markObjects(h, engine);
+        Q_ASSERT (h->gcGetVtable()->markObjects);
+        h->gcGetVtable()->markObjects(h, engine);
     }
 }
 
@@ -348,7 +348,7 @@ void MemoryManager::mark()
     for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) {
         if (!(*it).isManaged())
             continue;
-        if ((*it).managed()->d()->gcGetInternalClass()->vtable != QObjectWrapper::staticVTable())
+        if ((*it).managed()->d()->gcGetVtable() != QObjectWrapper::staticVTable())
             continue;
         QObjectWrapper *qobjectWrapper = static_cast<QObjectWrapper*>((*it).managed());
         if (!qobjectWrapper)
@@ -444,8 +444,8 @@ void MemoryManager::sweep(bool lastSweep)
             i = i->next;
             continue;
         }
-        if (m->gcGetInternalClass()->vtable->destroy)
-            m->gcGetInternalClass()->vtable->destroy(m);
+        if (m->gcGetVtable()->destroy)
+            m->gcGetVtable()->destroy(m);
 
         *last = i->next;
         free(Q_V4_PROFILE_DEALLOC(m_d->engine, i, i->size + sizeof(Data::LargeItem),
index 6049eb2..f0d6165 100644 (file)
@@ -82,18 +82,20 @@ public:
     static inline std::size_t align(std::size_t size)
     { return (size + 15) & ~0xf; }
 
-    inline Heap::Base *allocManaged(std::size_t size)
+    template<typename ManagedType>
+    inline typename ManagedType::Data *allocManaged(std::size_t size)
     {
         size = align(size);
         Heap::Base *o = allocData(size);
-        return o;
+        o->vtable = ManagedType::staticVTable();
+        return static_cast<typename ManagedType::Data *>(o);
     }
 
     template <typename ManagedType>
     typename ManagedType::Data *alloc()
     {
         Scope scope(engine());
-        Scoped<ManagedType> t(scope, static_cast<typename ManagedType::Data *>(allocManaged(sizeof(typename ManagedType::Data))));
+        Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
         (void)new (t->d()) typename ManagedType::Data();
         return t->d();
     }
@@ -102,7 +104,7 @@ public:
     typename ManagedType::Data *alloc(Arg1 arg1)
     {
         Scope scope(engine());
-        Scoped<ManagedType> t(scope, static_cast<typename ManagedType::Data *>(allocManaged(sizeof(typename ManagedType::Data))));
+        Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
         (void)new (t->d()) typename ManagedType::Data(arg1);
         return t->d();
     }
@@ -111,7 +113,7 @@ public:
     typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2)
     {
         Scope scope(engine());
-        Scoped<ManagedType> t(scope, static_cast<typename ManagedType::Data *>(allocManaged(sizeof(typename ManagedType::Data))));
+        Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
         (void)new (t->d()) typename ManagedType::Data(arg1, arg2);
         return t->d();
     }
@@ -120,7 +122,7 @@ public:
     typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3)
     {
         Scope scope(engine());
-        Scoped<ManagedType> t(scope, static_cast<typename ManagedType::Data *>(allocManaged(sizeof(typename ManagedType::Data))));
+        Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
         (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3);
         return t->d();
     }
@@ -129,7 +131,7 @@ public:
     typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
     {
         Scope scope(engine());
-        Scoped<ManagedType> t(scope, static_cast<typename ManagedType::Data *>(allocManaged(sizeof(typename ManagedType::Data))));
+        Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
         (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4);
         return t->d();
     }
@@ -138,7 +140,7 @@ public:
     typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
     {
         Scope scope(engine());
-        Scoped<ManagedType> t(scope, static_cast<typename ManagedType::Data *>(allocManaged(sizeof(typename ManagedType::Data))));
+        Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
         (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4, arg5);
         return t->d();
     }
index 77ac2a6..020607a 100644 (file)
@@ -290,7 +290,7 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr
                 *attrs = o->arrayData->attributes(index);
             return p;
         }
-        if (o->internalClass->vtable->type == Type_StringObject) {
+        if (o->vtable->type == Type_StringObject) {
             Property *p = static_cast<const Heap::StringObject *>(o)->getIndex(index);
             if (p) {
                 if (attrs)
index 2987799..939b14f 100644 (file)
@@ -77,7 +77,7 @@ struct Q_QML_EXPORT Object: Managed {
     const Property *propertyAt(uint index) const { return d()->propertyAt(index); }
     Property *propertyAt(uint index) { return d()->propertyAt(index); }
 
-    const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass()->vtable); }
+    const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(d()->vtable); }
     Heap::Object *prototype() const { return d()->prototype; }
     bool setPrototype(Object *proto);
 
index ff5061d..1b191f3 100644 (file)
@@ -180,8 +180,8 @@ static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
 {
     while (engine->jsStackTop > markBase) {
         Heap::Base *h = engine->popForGC();
-        Q_ASSERT (h->gcGetInternalClass()->vtable->markObjects);
-        h->gcGetInternalClass()->vtable->markObjects(h, engine);
+        Q_ASSERT (h->gcGetVtable()->markObjects);
+        h->gcGetVtable()->markObjects(h, engine);
     }
 }
 
index 7626d13..86624b2 100644 (file)
@@ -110,7 +110,7 @@ bool String::isEqualTo(Managed *t, Managed *o)
     if (t == o)
         return true;
 
-    if (!o->internalClass()->vtable->isString)
+    if (!o->d()->vtable->isString)
         return false;
 
     return static_cast<String *>(t)->isEqualTo(static_cast<String *>(o));
index 5fc6b88..b5efdfa 100644 (file)
@@ -73,7 +73,7 @@ DEFINE_OBJECT_VTABLE(StringObject);
 Heap::StringObject::StringObject(InternalClass *ic, QV4::Object *prototype)
     : Heap::Object(ic, prototype)
 {
-    Q_ASSERT(internalClass->vtable == QV4::StringObject::staticVTable());
+    Q_ASSERT(vtable == QV4::StringObject::staticVTable());
     value = ic->engine->newString()->asReturnedValue();
     tmpProperty.value = Primitive::undefinedValue();
 
index a551ac7..6d19d87 100644 (file)
@@ -49,13 +49,13 @@ inline bool Value::isString() const
 {
     if (!isManaged())
         return false;
-    return m && m->internalClass->vtable->isString;
+    return m && m->vtable->isString;
 }
 inline bool Value::isObject() const
 {
     if (!isManaged())
         return false;
-    return m && m->internalClass->vtable->isObject;
+    return m && m->vtable->isObject;
 }
 
 inline bool Value::isPrimitive() const
index 0a0da27..8ae8676 100644 (file)
@@ -51,14 +51,15 @@ struct Q_QML_EXPORT Base {
     Base(InternalClass *internal)
         : internalClass(internal)
     {
-        Q_ASSERT(inUse() && !isMarked());
+//        Q_ASSERT(vtable && inUse() && !isMarked());
         // ####
     //            Q_ASSERT(internal && internal->vtable);
     }
     union {
-        InternalClass *internalClass;
+        const ManagedVTable *vtable;
         quintptr mm_data;
     };
+    InternalClass *internalClass;
 
     void setVTable(const ManagedVTable *vt);
     inline ReturnedValue asReturnedValue() const;
@@ -70,8 +71,8 @@ struct Q_QML_EXPORT Base {
         PointerMask = ~0x3
     };
 
-    InternalClass *gcGetInternalClass() const {
-        return reinterpret_cast<InternalClass *>(mm_data & PointerMask);
+    ManagedVTable *gcGetVtable() const {
+        return reinterpret_cast<ManagedVTable *>(mm_data & PointerMask);
     }
     inline bool isMarked() const {
         return mm_data & MarkBit;
index 6eaa020..140572a 100644 (file)
@@ -1169,7 +1169,8 @@ ReturnedValue QQmlBindingFunction::call(Managed *that, CallData *callData)
 void QQmlBindingFunction::markObjects(Heap::Base *that, ExecutionEngine *e)
 {
     QQmlBindingFunction::Data *This = static_cast<QQmlBindingFunction::Data *>(that);
-    This->originalFunction->mark(e);
+    if (This->originalFunction)
+        This->originalFunction->mark(e);
     QV4::FunctionObject::markObjects(that, e);
 }