diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-08-29 14:31:32 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-02 17:27:36 +0200 |
commit | edee5c3dc0d922ec3b6a44d66193e9a57b8a979e (patch) | |
tree | 5e40caa777c01a7999d736ead63ae239d1eb5b98 /src/qml/jsruntime/qv4internalclass.cpp | |
parent | 3ad8b0f0e8193bb7b62ffee6b33588ef6b51459c (diff) |
Move prototype pointer into QV4::InternalClass
The prototype is actually the same for most objects. By
moving it into the internal class, we can save 8 bytes
per object, as well as allowing for some future
optimizations.
Also fix a bug in the implementation of the Error
prototype objects.
Change-Id: I4d4b641055f644a9b088f27be34bfdb0446279b7
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 50803db73d..59b1989e72 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -50,6 +50,9 @@ QT_BEGIN_NAMESPACE uint QV4::qHash(const QV4::InternalClassTransition &t, uint) { + if (t.flags == QV4::InternalClassTransition::ProtoChange) + // INT_MAX is prime, so this should give a decent distribution of keys + return (uint)((quintptr)t.prototype * INT_MAX); return t.id->hashValue ^ t.flags; } @@ -160,6 +163,8 @@ InternalClass *InternalClass::changeMember(String *string, PropertyAttributes da // create a new class and add it to the tree InternalClass *newClass = engine->newClass(*this); newClass->propertyData[idx] = data; + + transitions.insert(t, newClass); return newClass; } @@ -178,8 +183,17 @@ InternalClass *InternalClass::changePrototype(Object *proto) return tit.value(); // create a new class and add it to the tree - InternalClass *newClass = engine->newClass(*this); - newClass->prototype = proto; + InternalClass *newClass; + if (this == engine->emptyClass) { + newClass = engine->newClass(*this); + newClass->prototype = proto; + } else { + newClass = engine->emptyClass->changePrototype(proto); + for (int i = 0; i < nameMap.size(); ++i) + newClass = newClass->addMember(nameMap.at(i), propertyData.at(i)); + } + + transitions.insert(t, newClass); return newClass; } @@ -231,7 +245,7 @@ void InternalClass::removeMember(Object *object, Identifier *id) } // create a new class and add it to the tree - object->internalClass = engine->emptyClass; + object->internalClass = engine->emptyClass->changePrototype(prototype); for (int i = 0; i < nameMap.size(); ++i) { if (i == propIdx) continue; @@ -259,6 +273,7 @@ InternalClass *InternalClass::sealed() return m_sealed; m_sealed = engine->emptyClass; + m_sealed = m_sealed->changePrototype(prototype); for (int i = 0; i < nameMap.size(); ++i) { PropertyAttributes attrs = propertyData.at(i); attrs.setConfigurable(false); @@ -275,6 +290,7 @@ InternalClass *InternalClass::frozen() return m_frozen; m_frozen = engine->emptyClass; + m_frozen = m_frozen->changePrototype(prototype); for (int i = 0; i < nameMap.size(); ++i) { PropertyAttributes attrs = propertyData.at(i); attrs.setWritable(false); @@ -315,7 +331,8 @@ void InternalClass::destroy() void InternalClass::markObjects() { - prototype->mark(); + if (prototype) + prototype->mark(); for (QHash<Transition, InternalClass *>::ConstIterator it = transitions.begin(), end = transitions.end(); it != end; ++it) it.value()->markObjects(); |