aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-01-10 17:55:29 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2015-01-20 13:29:59 +0100
commit8a23c8a613b5eb360a48ee6c64ea3507caf878e2 (patch)
tree02282bda7d9f120389b5ea1341007d3617a4103f /src/qml
parent4690cc0cd3afa3bb0361da2b01834762b6c69646 (diff)
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 <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp4
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h11
-rw-r--r--src/qml/jsruntime/qv4context.cpp4
-rw-r--r--src/qml/jsruntime/qv4engine.cpp8
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h4
-rw-r--r--src/qml/jsruntime/qv4managed.cpp11
-rw-r--r--src/qml/jsruntime/qv4managed_p.h32
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp2
-rw-r--r--src/qml/jsruntime/qv4mm.cpp14
-rw-r--r--src/qml/jsruntime/qv4mm_p.h18
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp4
-rw-r--r--src/qml/jsruntime/qv4string.cpp2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4value_inl_p.h4
-rw-r--r--src/qml/jsruntime/qv4value_p.h9
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp3
21 files changed, 76 insertions, 72 deletions
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<ArgumentsObject *>(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<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;
}
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<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 {
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<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();
}
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<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;
}
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<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);
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<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
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<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),
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<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();
}
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<const Heap::StringObject *>(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<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);
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<String *>(t)->isEqualTo(static_cast<String *>(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<InternalClass *>(mm_data & PointerMask);
+ ManagedVTable *gcGetVtable() const {
+ return reinterpret_cast<ManagedVTable *>(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<QQmlBindingFunction::Data *>(that);
- This->originalFunction->mark(e);
+ if (This->originalFunction)
+ This->originalFunction->mark(e);
QV4::FunctionObject::markObjects(that, e);
}