From 8a23c8a613b5eb360a48ee6c64ea3507caf878e2 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 10 Jan 2015 17:55:29 +0100 Subject: Move vtable out of internalClass 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 --- src/qml/jsruntime/qv4argumentsobject.cpp | 2 +- src/qml/jsruntime/qv4argumentsobject_p.h | 2 +- src/qml/jsruntime/qv4arraydata.cpp | 4 ++-- src/qml/jsruntime/qv4arraydata_p.h | 11 ++++++----- src/qml/jsruntime/qv4context.cpp | 4 ++-- src/qml/jsruntime/qv4engine.cpp | 8 ++++---- src/qml/jsruntime/qv4functionobject.cpp | 8 ++++++-- src/qml/jsruntime/qv4identifiertable_p.h | 4 ++-- src/qml/jsruntime/qv4managed.cpp | 11 +++-------- src/qml/jsruntime/qv4managed_p.h | 32 ++++++++++++++++---------------- src/qml/jsruntime/qv4memberdata.cpp | 2 +- src/qml/jsruntime/qv4mm.cpp | 14 +++++++------- src/qml/jsruntime/qv4mm_p.h | 18 ++++++++++-------- src/qml/jsruntime/qv4object.cpp | 2 +- src/qml/jsruntime/qv4object_p.h | 2 +- src/qml/jsruntime/qv4persistent.cpp | 4 ++-- src/qml/jsruntime/qv4string.cpp | 2 +- src/qml/jsruntime/qv4stringobject.cpp | 2 +- src/qml/jsruntime/qv4value_inl_p.h | 4 ++-- src/qml/jsruntime/qv4value_p.h | 9 +++++---- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 3 ++- 21 files changed, 76 insertions(+), 72 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 33529dbfab..48e8bb67d4 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -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); diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index dfa7ec4219..bf5b532216 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -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(m)->context()->strictMode; } diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index a4f67c7656..f0fbc85a9a 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -128,13 +128,13 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt Scoped newData(scope); if (newType < Heap::ArrayData::Sparse) { - Heap::SimpleArrayData *n = static_cast(scope.engine->memoryManager->allocManaged(size)); + Heap::SimpleArrayData *n = scope.engine->memoryManager->allocManaged(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(scope.engine->memoryManager->allocManaged(size)); + Heap::SparseArrayData *n = scope.engine->memoryManager->allocManaged(size); new (n) Heap::SparseArrayData(scope.engine); newData = n; } diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index 533d51cd91..2ba6cedf90 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -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(m); } \ - QV4::Heap::Data *d() { return static_cast(m); } + const Data *d() const { return static_cast(m); } \ + Data *d() { return static_cast(m); } struct ArrayData; @@ -98,7 +99,7 @@ struct ArrayData : public Base { bool isSparse() const { return type == Sparse; } - const ArrayVTable *vtable() const { return reinterpret_cast(internalClass->vtable); } + const ArrayVTable *vtable() const { return reinterpret_cast(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(internalClass()->vtable); } + const ArrayVTable *vtable() const { return d()->vtable(); } bool isSparse() const { return type() == Heap::ArrayData::Sparse; } uint length() const { diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 408ccf051a..29f4278879 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -53,7 +53,7 @@ Heap::CallContext *ExecutionContext::newCallContext(FunctionObject *function, Ca { Q_ASSERT(function->function()); - Heap::CallContext *c = static_cast(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(function, callData->argc))); + Heap::CallContext *c = d()->engine->memoryManager->allocManaged(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 c(scope, static_cast(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0)))); + Scoped c(scope, d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0))); new (c->d()) Heap::CallContext(d()->engine, qml, f); return c->d(); } diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 3d3423b03a..0ee4dafcf0 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -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(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 r(scope, static_cast(memoryManager->allocManaged(sizeof(GlobalContext::Data) + sizeof(CallData)))); + Scoped r(scope, memoryManager->allocManaged(sizeof(GlobalContext::Data) + sizeof(CallData))); new (r->d()) GlobalContext::Data(this); r->d()->callData = reinterpret_cast(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; } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index e74acf78d4..3f06776dae 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -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); diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h index 5d29d44dc0..7bcf224181 100644 --- a/src/qml/jsruntime/qv4identifiertable_p.h +++ b/src/qml/jsruntime/qv4identifiertable_p.h @@ -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); } } }; diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index 668e7d296d..f784f4a781 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -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); } diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index fad3b85b2e..69d81442b7 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -237,7 +237,7 @@ public: #if !defined(QT_NO_QOBJECT_CHECK) static_cast(this)->qt_check_for_QMANAGED_macro(static_cast(this)); #endif - const ManagedVTable *vt = internalClass()->vtable; + const ManagedVTable *vt = d()->vtable; while (vt) { if (vt == T::staticVTable()) return static_cast(this); @@ -251,7 +251,7 @@ public: #if !defined(QT_NO_QOBJECT_CHECK) static_cast(this)->qt_check_for_QMANAGED_macro(static_cast(const_cast(this))); #endif - const ManagedVTable *vt = internalClass()->vtable; + const ManagedVTable *vt = d()->vtable; while (vt) { if (vt == T::staticVTable()) return static_cast(this); @@ -260,28 +260,28 @@ public: return 0; } - String *asString() { return internalClass()->vtable->isString ? reinterpret_cast(this) : 0; } - Object *asObject() { return internalClass()->vtable->isObject ? reinterpret_cast(this) : 0; } - ArrayObject *asArrayObject() { return internalClass()->vtable->type == Type_ArrayObject ? reinterpret_cast(this) : 0; } - FunctionObject *asFunctionObject() { return internalClass()->vtable->isFunctionObject ? reinterpret_cast(this) : 0; } - BooleanObject *asBooleanObject() { return internalClass()->vtable->type == Type_BooleanObject ? reinterpret_cast(this) : 0; } - NumberObject *asNumberObject() { return internalClass()->vtable->type == Type_NumberObject ? reinterpret_cast(this) : 0; } - StringObject *asStringObject() { return internalClass()->vtable->type == Type_StringObject ? reinterpret_cast(this) : 0; } - DateObject *asDateObject() { return internalClass()->vtable->type == Type_DateObject ? reinterpret_cast(this) : 0; } - ErrorObject *asErrorObject() { return internalClass()->vtable->isErrorObject ? reinterpret_cast(this) : 0; } - ArgumentsObject *asArgumentsObject() { return internalClass()->vtable->type == Type_ArgumentsObject ? reinterpret_cast(this) : 0; } + String *asString() { return d()->vtable->isString ? reinterpret_cast(this) : 0; } + Object *asObject() { return d()->vtable->isObject ? reinterpret_cast(this) : 0; } + ArrayObject *asArrayObject() { return d()->vtable->type == Type_ArrayObject ? reinterpret_cast(this) : 0; } + FunctionObject *asFunctionObject() { return d()->vtable->isFunctionObject ? reinterpret_cast(this) : 0; } + BooleanObject *asBooleanObject() { return d()->vtable->type == Type_BooleanObject ? reinterpret_cast(this) : 0; } + NumberObject *asNumberObject() { return d()->vtable->type == Type_NumberObject ? reinterpret_cast(this) : 0; } + StringObject *asStringObject() { return d()->vtable->type == Type_StringObject ? reinterpret_cast(this) : 0; } + DateObject *asDateObject() { return d()->vtable->type == Type_DateObject ? reinterpret_cast(this) : 0; } + ErrorObject *asErrorObject() { return d()->vtable->isErrorObject ? reinterpret_cast(this) : 0; } + ArgumentsObject *asArgumentsObject() { return d()->vtable->type == Type_ArgumentsObject ? reinterpret_cast(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(this), const_cast(other)); } + { return d()->vtable->isEqualTo(const_cast(this), const_cast(other)); } static bool isEqualTo(Managed *m, Managed *other); diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp index d4e196f091..2cdf901502 100644 --- a/src/qml/jsruntime/qv4memberdata.cpp +++ b/src/qml/jsruntime/qv4memberdata.cpp @@ -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 newMemberData(scope, static_cast(e->memoryManager->allocManaged(alloc))); + Scoped newMemberData(scope, e->memoryManager->allocManaged(alloc)); if (old) memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + s*sizeof(Value)); else diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index f4c3d930ac..66b291ddcf 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -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((*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), diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h index 6049eb2d8a..f0d6165089 100644 --- a/src/qml/jsruntime/qv4mm_p.h +++ b/src/qml/jsruntime/qv4mm_p.h @@ -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 + 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(o); } template typename ManagedType::Data *alloc() { Scope scope(engine()); - Scoped t(scope, static_cast(allocManaged(sizeof(typename ManagedType::Data)))); + Scoped t(scope, allocManaged(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 t(scope, static_cast(allocManaged(sizeof(typename ManagedType::Data)))); + Scoped t(scope, allocManaged(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 t(scope, static_cast(allocManaged(sizeof(typename ManagedType::Data)))); + Scoped t(scope, allocManaged(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 t(scope, static_cast(allocManaged(sizeof(typename ManagedType::Data)))); + Scoped t(scope, allocManaged(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 t(scope, static_cast(allocManaged(sizeof(typename ManagedType::Data)))); + Scoped t(scope, allocManaged(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 t(scope, static_cast(allocManaged(sizeof(typename ManagedType::Data)))); + Scoped t(scope, allocManaged(sizeof(typename ManagedType::Data))); (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4, arg5); return t->d(); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 77ac2a6049..020607a2d0 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -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(o)->getIndex(index); if (p) { if (attrs) diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 298779906b..939b14f4d2 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -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(internalClass()->vtable); } + const ObjectVTable *vtable() const { return reinterpret_cast(d()->vtable); } Heap::Object *prototype() const { return d()->prototype; } bool setPrototype(Object *proto); diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp index ff5061d968..1b191f3384 100644 --- a/src/qml/jsruntime/qv4persistent.cpp +++ b/src/qml/jsruntime/qv4persistent.cpp @@ -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); } } diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 7626d13c59..86624b23bf 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -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(t)->isEqualTo(static_cast(o)); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 5fc6b884d0..b5efdfa410 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -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(); diff --git a/src/qml/jsruntime/qv4value_inl_p.h b/src/qml/jsruntime/qv4value_inl_p.h index a551ac7e6b..6d19d87095 100644 --- a/src/qml/jsruntime/qv4value_inl_p.h +++ b/src/qml/jsruntime/qv4value_inl_p.h @@ -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 diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 0a0da27f41..8ae8676b7b 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -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(mm_data & PointerMask); + ManagedVTable *gcGetVtable() const { + return reinterpret_cast(mm_data & PointerMask); } inline bool isMarked() const { return mm_data & MarkBit; diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 6eaa020218..140572a99a 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1169,7 +1169,8 @@ ReturnedValue QQmlBindingFunction::call(Managed *that, CallData *callData) void QQmlBindingFunction::markObjects(Heap::Base *that, ExecutionEngine *e) { QQmlBindingFunction::Data *This = static_cast(that); - This->originalFunction->mark(e); + if (This->originalFunction) + This->originalFunction->mark(e); QV4::FunctionObject::markObjects(that, e); } -- cgit v1.2.3