, 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);
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;
}
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;
}
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;
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);
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 {
{
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();
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();
}
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());
//
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);
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;
Q_ASSERT(c->inUse());
if (!c->isMarked()) {
c->setMarkBit();
- c->gcGetInternalClass()->vtable->markObjects(c, this);
+ c->gcGetVtable()->markObjects(c, this);
}
c = c->parent;
}
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);
ExecutionContextSaver ctxSaver(scope, v4->currentContext());
CallContext::Data ctx(v4);
+ ctx.vtable = CallContext::staticVTable();
ctx.strictMode = f->strictMode();
ctx.callData = callData;
ctx.function = f->d();
ExecutionContextSaver ctxSaver(scope, v4->currentContext());
CallContext::Data ctx(v4);
+ ctx.vtable = CallContext::staticVTable();
ctx.strictMode = f->strictMode();
ctx.callData = callData;
ctx.function = f->d();
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);
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);
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);
}
}
};
};
-void *Managed::operator new(size_t size, MemoryManager *mm)
-{
- assert(mm);
-
- return mm->allocManaged(size);
-}
-
ExecutionEngine *Managed::engine() const
{
return internalClass()->engine;
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();
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);
}
#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);
#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);
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);
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
#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
{
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);
}
}
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)
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),
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();
}
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();
}
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();
}
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();
}
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();
}
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();
}
*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)
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);
{
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);
}
}
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));
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();
{
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
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;
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;
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);
}