aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4internalclass.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-11-21 13:15:46 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-04 09:45:45 +0100
commitfbcd0a22f643f0b0ec1404507d63bdf35cd9a195 (patch)
treeb759029b5ca0f9db8d3bf1863ca319a92edb6baf /src/qml/jsruntime/qv4internalclass.cpp
parent5e8bee55aa78551c2d31b24228227c0bbbdc1d8d (diff)
Move the vtable pointer from the object to the internal class
This saves one pointer per object, and willmake other optimizations easier in the future. Change-Id: I1324cad31998896b5dc76af3c8a7ee9d86283bfe Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass.cpp')
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index cb799a473c..3b4890fcb3 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -126,10 +126,21 @@ uint PropertyHash::lookup(const Identifier *identifier) const
}
}
+InternalClass::InternalClass(ExecutionEngine *engine)
+ : engine(engine)
+ , prototype(0)
+ , vtable(&Managed::static_vtbl)
+ , m_sealed(0)
+ , m_frozen(0)
+ , size(0)
+{
+}
+
InternalClass::InternalClass(const QV4::InternalClass &other)
: engine(other.engine)
, prototype(other.prototype)
+ , vtable(other.vtable)
, propertyTable(other.propertyTable)
, nameMap(other.nameMap)
, propertyData(other.propertyData)
@@ -184,11 +195,41 @@ InternalClass *InternalClass::changePrototype(Object *proto)
// create a new class and add it to the tree
InternalClass *newClass;
- if (this == engine->emptyClass) {
+ if (!size) {
newClass = engine->newClass(*this);
newClass->prototype = proto;
} else {
- newClass = engine->emptyClass->changePrototype(proto);
+ newClass = engine->emptyClass->changeVTable(vtable);
+ newClass = newClass->changePrototype(proto);
+ for (uint i = 0; i < size; ++i)
+ newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
+ }
+
+ transitions.insert(t, newClass);
+ return newClass;
+}
+
+InternalClass *InternalClass::changeVTable(const ManagedVTable *vt)
+{
+ if (vtable == vt)
+ return this;
+
+ Transition t;
+ t.vtable = vt;
+ t.flags = Transition::VTableChange;
+
+ QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t);
+ if (tit != transitions.constEnd())
+ return tit.value();
+
+ // create a new class and add it to the tree
+ InternalClass *newClass;
+ if (this == engine->emptyClass) {
+ newClass = engine->newClass(*this);
+ newClass->vtable = vt;
+ } else {
+ newClass = engine->emptyClass->changeVTable(vt);
+ newClass = newClass->changePrototype(prototype);
for (uint i = 0; i < size; ++i)
newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
}
@@ -343,7 +384,9 @@ void InternalClass::markObjects()
for (QHash<Transition, InternalClass *>::ConstIterator it = transitions.begin(), end = transitions.end();
it != end; ++it) {
- if (it.key().flags == Transition::ProtoChange) {
+ if (it.key().flags == Transition::VTableChange) {
+ it.value()->markObjects();
+ } else if (it.key().flags == Transition::ProtoChange) {
Q_ASSERT(it.value()->prototype);
it.value()->prototype->mark(engine);
}