aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-05-12 15:12:45 +0200
committerLars Knoll <lars.knoll@qt.io>2017-05-19 06:23:26 +0000
commitcae7975a036352ca4bbcf1381a445362f8e01367 (patch)
treecb5c3213160cb20ac3a9927125bf01fc7b72a67b /src
parent0cdea188727e203ecc529ef8e4e8859cca0be232 (diff)
Move the internalClass field from Heap::Object to Heap::Base
And do not store the vtable in Heap::Base anymore. This change makes the internal class the main distinguishing feature of all garbage collected objects. It also saves one pointer on all Objects. No measurable impact on runtime performance. Change-Id: I040a28b7581b993f1886b5219e279173dfa567e8 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4context_p.h1
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp40
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h4
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp13
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h2
-rw-r--r--src/qml/jsruntime/qv4managed_p.h2
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4object.cpp1
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp1
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h1
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4string_p.h2
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp3
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h1
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h1
-rw-r--r--src/qml/memory/qv4heap_p.h10
-rw-r--r--src/qml/memory/qv4mm.cpp3
-rw-r--r--src/qml/memory/qv4mm_p.h17
24 files changed, 81 insertions, 36 deletions
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 9c8b1d67f1..ca2cf7d17a 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -76,6 +76,7 @@ struct BooleanCtor: FunctionObject
struct BooleanPrototype: BooleanObject
{
+ V4_PROTOTYPE(objectPrototype)
void init(ExecutionEngine *engine, Object *ctor);
static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index c769dcd142..c742df7b97 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -228,6 +228,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
V4_MANAGED(ExecutionContext, Managed)
Q_MANAGED_TYPE(ExecutionContext)
+ V4_INTERNALCLASS(ExecutionContext)
ExecutionEngine *engine() const { return d()->engine; }
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index a56d17f9b1..ecd57bcd8d 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -114,6 +114,8 @@ struct DateCtor: FunctionObject
struct DatePrototype: DateObject
{
+ V4_PROTOTYPE(objectPrototype)
+
void init(ExecutionEngine *engine, Object *ctor);
static double getThisDate(Scope &scope, CallData *callData);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 982db33092..6b05d9a05c 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -213,12 +213,12 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
classPool = new InternalClassPool;
internalClasses[Class_Empty] = new (classPool) InternalClass(this);
- internalClasses[Class_Object] = internalClasses[Class_Empty];
-
+ internalClasses[Class_Object] = internalClasses[Class_Empty]->changeVTable(QV4::Object::staticVTable());
internalClasses[Class_String] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::String::staticVTable());
internalClasses[Class_MemberData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::MemberData::staticVTable());
internalClasses[Class_SimpleArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
internalClasses[Class_SparseArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
+ internalClasses[Class_ExecutionContext] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
jsStrings[String_Empty] = newIdentifier(QString());
jsStrings[String_undefined] = newIdentifier(QStringLiteral("undefined"));
@@ -259,11 +259,13 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(internalClasses[Class_Object]);
- internalClasses[Class_ArrayObject] = internalClasses[Class_Object]->addMember(id_length(), Attr_NotConfigurable|Attr_NotEnumerable);
+ internalClasses[Class_ArrayObject] = internalClasses[Class_Empty]->changeVTable(QV4::ArrayObject::staticVTable());
+ internalClasses[Class_ArrayObject] = internalClasses[Class_ArrayObject]->addMember(id_length(), Attr_NotConfigurable|Attr_NotEnumerable);
jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(internalClasses[Class_ArrayObject], objectPrototype());
jsObjects[PropertyListProto] = memoryManager->allocObject<PropertyListPrototype>();
- InternalClass *argsClass = internalClasses[Class_Object]->addMember(id_length(), Attr_NotEnumerable);
+ InternalClass *argsClass = internalClasses[Class_Empty]->changeVTable(QV4::ArgumentsObject::staticVTable())
+ ->addMember(id_length(), Attr_NotEnumerable);
internalClasses[EngineBase::Class_ArgumentsObject] = argsClass->addMember(id_callee(), Attr_Data|Attr_NotEnumerable);
argsClass = argsClass->addMember(id_callee(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
internalClasses[EngineBase::Class_StrictArgumentsObject] = argsClass->addMember(id_caller(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
@@ -272,15 +274,18 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
Q_ASSERT(globalObject->d()->vtable());
initRootContext();
- internalClasses[EngineBase::Class_StringObject] = internalClasses[Class_Object]->addMember(id_length(), Attr_ReadOnly);
+ internalClasses[Class_StringObject] = internalClasses[Class_Empty]->changeVTable(QV4::StringObject::staticVTable());
+ internalClasses[EngineBase::Class_StringObject] = internalClasses[Class_StringObject]->addMember(id_length(), Attr_ReadOnly);
Q_ASSERT(internalClasses[EngineBase::Class_StringObject]->find(id_length()) == Heap::StringObject::LengthPropertyIndex);
jsObjects[StringProto] = memoryManager->allocObject<StringPrototype>(internalClasses[EngineBase::Class_StringObject], objectPrototype());
- jsObjects[NumberProto] = memoryManager->allocObject<NumberPrototype>(internalClasses[Class_Object], objectPrototype());
- jsObjects[BooleanProto] = memoryManager->allocObject<BooleanPrototype>(internalClasses[Class_Object], objectPrototype());
- jsObjects[DateProto] = memoryManager->allocObject<DatePrototype>(internalClasses[Class_Object], objectPrototype());
+ jsObjects[NumberProto] = memoryManager->allocObject<NumberPrototype>();
+ jsObjects[BooleanProto] = memoryManager->allocObject<BooleanPrototype>();
+ jsObjects[DateProto] = memoryManager->allocObject<DatePrototype>();
uint index;
- InternalClass *functionProtoClass = internalClasses[Class_Object]->addMember(id_prototype(), Attr_NotEnumerable, &index);
+ InternalClass *functionProtoClass =
+ internalClasses[Class_Empty]->changeVTable(QV4::FunctionPrototype::staticVTable())
+ ->addMember(id_prototype(), Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(functionProtoClass, objectPrototype());
internalClasses[EngineBase::Class_FunctionObject] = internalClasses[Class_Object]->addMember(id_prototype(), Attr_NotEnumerable|Attr_NotConfigurable, &index);
@@ -294,7 +299,10 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
Scope scope(this);
ScopedString str(scope);
- internalClasses[EngineBase::Class_RegExpObject] = internalClasses[Class_Object]->addMember(id_lastIndex(), Attr_NotEnumerable|Attr_NotConfigurable, &index);
+ internalClasses[Class_RegExp] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::RegExp::staticVTable());
+ internalClasses[EngineBase::Class_RegExpObject] =
+ internalClasses[Class_Empty]->changeVTable(QV4::RegExpObject::staticVTable())
+ ->addMember(id_lastIndex(), Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == RegExpObject::Index_LastIndex);
internalClasses[EngineBase::Class_RegExpObject] = internalClasses[EngineBase::Class_RegExpObject]->addMember((str = newIdentifier(QStringLiteral("source"))), Attr_ReadOnly, &index);
Q_ASSERT(index == RegExpObject::Index_Source);
@@ -311,7 +319,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
internalClasses[EngineBase::Class_RegExpExecArray] = internalClasses[EngineBase::Class_RegExpExecArray]->addMember(id_input(), Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
- internalClasses[EngineBase::Class_ErrorObject] = internalClasses[Class_Object]->addMember((str = newIdentifier(QStringLiteral("stack"))), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, &index);
+ internalClasses[EngineBase::Class_ErrorObject] =
+ internalClasses[Class_Empty]->changeVTable(QV4::ErrorObject::staticVTable())
+ ->addMember((str = newIdentifier(QStringLiteral("stack"))), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorObject::Index_Stack);
internalClasses[EngineBase::Class_ErrorObject] = internalClasses[EngineBase::Class_ErrorObject]->addMember((str = newIdentifier(QStringLiteral("fileName"))), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorObject::Index_FileName);
@@ -319,7 +329,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
Q_ASSERT(index == ErrorObject::Index_LineNumber);
internalClasses[EngineBase::Class_ErrorObjectWithMessage] = internalClasses[EngineBase::Class_ErrorObject]->addMember((str = newIdentifier(QStringLiteral("message"))), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorObject::Index_Message);
- internalClasses[EngineBase::Class_ErrorProto] = internalClasses[Class_Object]->addMember(id_constructor(), Attr_Data|Attr_NotEnumerable, &index);
+ internalClasses[EngineBase::Class_ErrorProto] =
+ internalClasses[Class_Empty]->changeVTable(QV4::ErrorPrototype::staticVTable())
+ ->addMember(id_constructor(), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorPrototype::Index_Constructor);
internalClasses[EngineBase::Class_ErrorProto] = internalClasses[EngineBase::Class_ErrorProto]->addMember((str = newIdentifier(QStringLiteral("message"))), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorPrototype::Index_Message);
@@ -337,10 +349,10 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
jsObjects[TypeErrorProto] = memoryManager->allocObject<TypeErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto], errorPrototype());
jsObjects[URIErrorProto] = memoryManager->allocObject<URIErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto], errorPrototype());
- jsObjects[VariantProto] = memoryManager->allocObject<VariantPrototype>(internalClasses[Class_Object], objectPrototype());
+ jsObjects[VariantProto] = memoryManager->allocObject<VariantPrototype>();
Q_ASSERT(variantPrototype()->prototype() == objectPrototype()->d());
- jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->allocObject<SequencePrototype>(internalClasses[Class_ArrayObject], arrayPrototype()));
+ jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->allocObject<SequencePrototype>());
ExecutionContext *global = rootContext();
jsObjects[Object_Ctor] = memoryManager->allocObject<ObjectCtor>(global);
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index 783ddc5bd3..e124adb810 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -87,14 +87,16 @@ struct EngineBase {
Class_MemberData,
Class_SimpleArrayData,
Class_SparseArrayData,
+ Class_ExecutionContext,
Class_Object,
Class_ArrayObject,
Class_FunctionObject,
Class_StringObject,
Class_ScriptFunction,
Class_ObjectProto,
- Class_RegExpExecArray,
+ Class_RegExp,
Class_RegExpObject,
+ Class_RegExpExecArray,
Class_ArgumentsObject,
Class_StrictArgumentsObject,
Class_ErrorObject,
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 63b778b56d..65507e2251 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -183,8 +183,6 @@ void ErrorObject::markObjects(Heap::Base *that, ExecutionEngine *e)
DEFINE_OBJECT_VTABLE(ErrorObject);
-DEFINE_OBJECT_VTABLE(SyntaxErrorObject);
-
void Heap::SyntaxErrorObject::init(const Value &msg)
{
Heap::ErrorObject::init(msg, SyntaxError);
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 896b54da5e..34e4b4a682 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -203,8 +203,10 @@ struct ReferenceErrorObject: ErrorObject {
};
struct SyntaxErrorObject: ErrorObject {
- V4_OBJECT2(SyntaxErrorObject, ErrorObject)
+ typedef Heap::SyntaxErrorObject Data;
V4_PROTOTYPE(syntaxErrorPrototype)
+ const Data *d() const { return static_cast<const Data *>(ErrorObject::d()); }
+ Data *d() { return static_cast<Data *>(ErrorObject::d()); }
};
struct TypeErrorObject: ErrorObject {
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index e117da1a04..9a4087485f 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -249,8 +249,17 @@ InternalClass *InternalClass::changeVTableImpl(const VTable *vt)
// create a new class and add it to the tree
InternalClass *newClass;
- newClass = engine->newClass(*this);
- newClass->vtable = vt;
+ if (this == engine->internalClasses[EngineBase::Class_Empty]) {
+ newClass = engine->newClass(*this);
+ newClass->vtable = vt;
+ } else {
+ newClass = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vt);
+ newClass = newClass->changePrototype(prototype);
+ for (uint i = 0; i < size; ++i) {
+ if (!propertyData.at(i).isEmpty())
+ newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
+ }
+ }
t.lookup = newClass;
Q_ASSERT(t.lookup);
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index c68a6638e7..3c4e0838d9 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -280,7 +280,7 @@ struct InternalClass : public QQmlJS::Managed {
void destroy();
private:
- InternalClass *changeVTableImpl(const VTable *vt);
+ Q_QML_EXPORT InternalClass *changeVTableImpl(const VTable *vt);
InternalClass *addMemberImpl(Identifier *identifier, PropertyAttributes data, uint *index);
friend struct ExecutionEngine;
InternalClass(ExecutionEngine *engine);
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 00bfad78dd..814755efe9 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -198,6 +198,8 @@ public:
};
Q_MANAGED_TYPE(Invalid)
+ InternalClass *internalClass() const { return d()->internalClass; }
+
bool isListType() const { return d()->vtable()->type == Type_QmlSequence; }
bool isArrayObject() const { return d()->vtable()->type == Type_ArrayObject; }
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 364b866a16..85d306020c 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -85,6 +85,7 @@ struct NumberCtor: FunctionObject
struct NumberPrototype: NumberObject
{
+ V4_PROTOTYPE(objectPrototype)
void init(ExecutionEngine *engine, Object *ctor);
static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index f5dafa7914..838ae96c59 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -61,6 +61,7 @@ DEFINE_OBJECT_VTABLE(Object);
void Object::setInternalClass(InternalClass *ic)
{
d()->internalClass = ic;
+ Q_ASSERT(ic && ic->vtable);
uint nInline = d()->vtable()->nInlineProperties;
if (ic->size <= nInline)
return;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 78ee263c80..951659a4bc 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -95,7 +95,6 @@ struct Object : Base {
return memberData->data + index;
}
- InternalClass *internalClass;
Pointer<Object> prototype;
Pointer<MemberData> memberData;
Pointer<ArrayData> arrayData;
@@ -204,7 +203,6 @@ struct Q_QML_EXPORT Object: Managed {
SetterOffset = 1
};
- InternalClass *internalClass() const { return d()->internalClass; }
void setInternalClass(InternalClass *ic);
const Value *propertyData(uint index) const { return d()->propertyData(index); }
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 889f4ea288..ef1a1c11ed 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -331,6 +331,7 @@ Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, cons
qml->setReadOnly(true);
Heap::QmlContext *c = parent->d()->engine->memoryManager->alloc<QmlContext>(parent, qml);
+ Q_ASSERT(c->vtable() == staticVTable());
return c;
}
@@ -340,6 +341,7 @@ Heap::QmlContext *QmlContext::create(ExecutionContext *parent, QQmlContextData *
Scoped<QmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QmlContextWrapper>(context, scopeObject));
Heap::QmlContext *c = parent->d()->engine->memoryManager->alloc<QmlContext>(parent, qml);
+ Q_ASSERT(c->vtable() == staticVTable());
return c;
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 67b1356e65..f484d56040 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -997,7 +997,6 @@ void QObjectWrapper::destroyObject(bool lastCall)
}
}
- h->internalClass = 0;
h->~Data();
}
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index d3e63375a5..04cdb468bf 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -100,6 +100,7 @@ struct RegExp : public Managed
V4_MANAGED(RegExp, Managed)
Q_MANAGED_TYPE(RegExp)
V4_NEEDS_DESTROY
+ V4_INTERNALCLASS(RegExp)
QString pattern() const { return *d()->pattern; }
JSC::Yarr::BytecodePattern *byteCode() { return d()->byteCode; }
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 6f96b9f760..0879f149fa 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -65,6 +65,7 @@ namespace QV4 {
struct SequencePrototype : public QV4::Object
{
+ V4_PROTOTYPE(arrayPrototype)
void init();
static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index bf8c48ceee..ad30165ce5 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -72,7 +72,6 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
};
#ifndef V4_BOOTSTRAP
- V4_INTERNALCLASS(String)
void init(MemoryManager *mm, const QString &text);
void init(MemoryManager *mm, String *l, String *n);
void destroy();
@@ -140,6 +139,7 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
#ifndef V4_BOOTSTRAP
V4_MANAGED(String, Managed)
Q_MANAGED_TYPE(String)
+ V4_INTERNALCLASS(String)
V4_NEEDS_DESTROY
enum {
IsString = true
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 542460ee81..bb28a7683c 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -372,7 +372,8 @@ void Heap::TypedArray::init(Type t)
Heap::TypedArray *TypedArray::create(ExecutionEngine *e, Heap::TypedArray::Type t)
{
- return e->memoryManager->allocObject<TypedArray>(e->internalClasses[EngineBase::Class_Object], e->typedArrayPrototype + t, t);
+ QV4::InternalClass *ic = e->internalClasses[EngineBase::Class_Empty]->changeVTable(staticVTable());
+ return e->memoryManager->allocObject<TypedArray>(ic, e->typedArrayPrototype + t, t);
}
void TypedArray::markObjects(Heap::Base *that, ExecutionEngine *e)
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index eefed2db4b..a6a74e4b9b 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -148,6 +148,7 @@ struct TypedArrayCtor: FunctionObject
struct TypedArrayPrototype : Object
{
V4_OBJECT2(TypedArrayPrototype, Object)
+ V4_PROTOTYPE(objectPrototype)
void init(ExecutionEngine *engine, TypedArrayCtor *ctor);
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index ef51b6632d..dba14b13fb 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -105,6 +105,7 @@ struct VariantObject : Object
struct VariantPrototype : VariantObject
{
public:
+ V4_PROTOTYPE(objectPrototype)
void init();
static void method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData);
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index cd0a6d9a81..a4e96b4c84 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -53,6 +53,7 @@
#include <QtCore/QString>
#include <private/qv4global_p.h>
#include <private/qv4mmdefs_p.h>
+#include <private/qv4internalclass_p.h>
#include <QSharedPointer>
// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
@@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+struct InternalClass;
+
struct VTable
{
const VTable * const parent;
@@ -93,13 +96,12 @@ namespace Heap {
struct Q_QML_EXPORT Base {
void *operator new(size_t) = delete;
- const VTable *vt;
+ InternalClass *internalClass;
inline ReturnedValue asReturnedValue() const;
inline void mark(QV4::ExecutionEngine *engine);
- void setVtable(const VTable *v) { vt = v; }
- const VTable *vtable() const { return vt; }
+ const VTable *vtable() const { return internalClass->vtable; }
inline bool isMarked() const {
const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
Chunk *c = h->chunk();
@@ -166,7 +168,7 @@ V4_ASSERT_IS_TRIVIAL(Base)
// for a size/offset translation when cross-compiling between 32- and
// 64-bit.
Q_STATIC_ASSERT(std::is_standard_layout<Base>::value);
-Q_STATIC_ASSERT(offsetof(Base, vt) == 0);
+Q_STATIC_ASSERT(offsetof(Base, internalClass) == 0);
Q_STATIC_ASSERT(sizeof(Base) == QT_POINTER_SIZE);
template <typename T>
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index ef36e62373..56f1254421 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -787,7 +787,8 @@ Heap::Object *MemoryManager::allocObjectWithMemberData(const QV4::VTable *vtable
m = *blockAllocator.allocate(memberSize, true);
memset(m, 0, memberSize);
o->memberData = static_cast<Heap::MemberData *>(m);
- o->memberData->setVtable(MemberData::staticVTable());
+ o->memberData->internalClass = engine->internalClasses[EngineBase::Class_MemberData];
+ Q_ASSERT(o->memberData->internalClass);
o->memberData->size = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
o->memberData->init();
// qDebug() << " got" << o->memberData << o->memberData->size;
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 9b4c2cd8df..8f12fa7cbd 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -210,7 +210,8 @@ public:
{
Heap::CallContext *ctxt = stackAllocator.allocate();
memset(ctxt, 0, sizeof(Heap::CallContext));
- ctxt->setVtable(QV4::CallContext::staticVTable());
+ ctxt->internalClass = CallContext::defaultInternalClass(engine);
+ Q_ASSERT(ctxt->internalClass && ctxt->internalClass->vtable);
ctxt->init(v4);
return ctxt;
@@ -224,7 +225,10 @@ public:
V4_ASSERT_IS_TRIVIAL(typename ManagedType::Data)
size = align(size);
Heap::Base *o = allocData(size);
- o->setVtable(ManagedType::staticVTable());
+ InternalClass *ic = ManagedType::defaultInternalClass(engine);
+ ic = ic->changeVTable(ManagedType::staticVTable());
+ o->internalClass = ic;
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
return static_cast<typename ManagedType::Data *>(o);
}
@@ -232,8 +236,9 @@ public:
typename ObjectType::Data *allocateObject(InternalClass *ic)
{
Heap::Object *o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->size);
- o->setVtable(ObjectType::staticVTable());
o->internalClass = ic;
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
+ Q_ASSERT(ic->vtable == ObjectType::staticVTable());
return static_cast<typename ObjectType::Data *>(o);
}
@@ -241,10 +246,11 @@ public:
typename ObjectType::Data *allocateObject()
{
InternalClass *ic = ObjectType::defaultInternalClass(engine);
+ ic = ic->changeVTable(ObjectType::staticVTable());
Heap::Object *o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->size);
- o->setVtable(ObjectType::staticVTable());
Object *prototype = ObjectType::defaultPrototype(engine);
o->internalClass = ic;
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
o->prototype = prototype->d();
return static_cast<typename ObjectType::Data *>(o);
}
@@ -253,7 +259,8 @@ public:
typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 arg1)
{
typename ManagedType::Data *o = reinterpret_cast<typename ManagedType::Data *>(allocString(unmanagedSize));
- o->setVtable(ManagedType::staticVTable());
+ o->internalClass = ManagedType::defaultInternalClass(engine);
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
o->init(this, arg1);
return o;
}