diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-11-21 13:15:46 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-04 09:45:45 +0100 |
commit | fbcd0a22f643f0b0ec1404507d63bdf35cd9a195 (patch) | |
tree | b759029b5ca0f9db8d3bf1863ca319a92edb6baf /src/qml/jsruntime/qv4internalclass.cpp | |
parent | 5e8bee55aa78551c2d31b24228227c0bbbdc1d8d (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.cpp | 49 |
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); } |