diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-09-10 23:30:04 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-09-16 17:00:22 +0000 |
commit | e436fb3569603bca8ad0a71fef67c03d2920aedc (patch) | |
tree | a8076925a788fd721c8b46119f0f13009ca882e8 /src/qml/jsruntime/qv4internalclass.cpp | |
parent | 6982d0d6290c137468749bb8ab2f2e20dfa453fd (diff) |
Store InternalClass::nameMap in a MemberData
This helps make that memory known to the GC as well, and makes
marking of internal classes much more efficient, as we don't
mark the property keys repeatedly (even if they are shared
between different internal classes)
Change-Id: Ibb7e5383672d7657926bd08bf13f73f7680a9f31
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 100 |
1 files changed, 88 insertions, 12 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index c890dc0550..b22d3073b9 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -137,14 +137,83 @@ void PropertyHash::detach(bool grow, int classSize) d = dd; } + +SharedInternalClassDataPrivate<PropertyKey>::SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate<PropertyKey> &other) + : refcount(1), + engine(other.engine), + data(nullptr) +{ + if (other.alloc()) { + int s = other.size(); + data = MemberData::allocate(engine, other.alloc(), other.data); + setSize(s); + } +} + +SharedInternalClassDataPrivate<PropertyKey>::SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate<PropertyKey> &other, + uint pos, PropertyKey value) + : refcount(1), + engine(other.engine) +{ + data = MemberData::allocate(engine, other.alloc(), nullptr); + memcpy(data, other.data, sizeof(Heap::MemberData) - sizeof(Value) + pos*sizeof(Value)); + data->values.size = pos + 1; + data->values.set(engine, pos, Value::fromReturnedValue(value.id())); +} + +void SharedInternalClassDataPrivate<PropertyKey>::grow() +{ + uint a = alloc() * 2; + int s = size(); + data = MemberData::allocate(engine, a, data); + setSize(s); + Q_ASSERT(alloc() >= a); +} + +uint SharedInternalClassDataPrivate<PropertyKey>::alloc() const +{ + return data ? data->values.alloc : 0; +} + +uint SharedInternalClassDataPrivate<PropertyKey>::size() const +{ + return data ? data->values.size : 0; +} + +void SharedInternalClassDataPrivate<PropertyKey>::setSize(uint s) +{ + Q_ASSERT(data && s <= alloc()); + data->values.size = s; +} + +PropertyKey SharedInternalClassDataPrivate<PropertyKey>::at(uint i) +{ + Q_ASSERT(data && i < size()); + return PropertyKey::fromId(data->values.values[i].rawValue()); +} + +void SharedInternalClassDataPrivate<PropertyKey>::set(uint i, PropertyKey t) +{ + Q_ASSERT(data && i < size()); + data->values.values[i].rawValueRef() = t.id(); +} + +void SharedInternalClassDataPrivate<PropertyKey>::mark(MarkStack *s) +{ + if (data) + data->mark(s); +} + + + namespace Heap { void InternalClass::init(ExecutionEngine *engine) { Base::init(); new (&propertyTable) PropertyHash(); - new (&nameMap) SharedInternalClassData<PropertyKey>(); - new (&propertyData) SharedInternalClassData<PropertyAttributes>(); + new (&nameMap) SharedInternalClassData<PropertyKey>(engine); + new (&propertyData) SharedInternalClassData<PropertyAttributes>(engine); new (&transitions) std::vector<Transition>(); this->engine = engine; @@ -204,6 +273,11 @@ void InternalClass::destroy() Base::destroy(); } +QString InternalClass::keyAt(uint index) const +{ + return nameMap.at(index).toQString(); +} + static void insertHoleIntoPropertyData(QV4::Object *object, int idx) { Heap::Object *o = object->d(); @@ -288,8 +362,8 @@ Heap::InternalClass *InternalClass::changeMember(PropertyKey identifier, Propert if (data.isAccessor() != propertyData.at(idx).isAccessor()) { // this changes the layout of the class, so we need to rebuild the data newClass->propertyTable = PropertyHash(); - newClass->nameMap = SharedInternalClassData<PropertyKey>(); - newClass->propertyData = SharedInternalClassData<PropertyAttributes>(); + newClass->nameMap = SharedInternalClassData<PropertyKey>(engine); + newClass->propertyData = SharedInternalClassData<PropertyAttributes>(engine); newClass->size = 0; for (uint i = 0; i < size; ++i) { PropertyKey identifier = nameMap.at(i); @@ -423,7 +497,9 @@ Heap::InternalClass *InternalClass::addMemberImpl(PropertyKey identifier, Proper return t.lookup; // create a new class and add it to the tree - Heap::InternalClass *newClass = engine->newClass(this); + Scope scope(engine); + Scoped<QV4::InternalClass> ic(scope, engine->newClass(this)); + InternalClass *newClass = ic->d(); PropertyHash::Entry e = { identifier, newClass->size }; newClass->propertyTable.addEntry(e, newClass->size); @@ -504,7 +580,9 @@ Heap::InternalClass *InternalClass::sealed() return t.lookup; } - Heap::InternalClass *s = engine->newClass(this); + Scope scope(engine); + Scoped<QV4::InternalClass> ic(scope, engine->newClass(this)); + Heap::InternalClass *s = ic->d(); for (uint i = 0; i < size; ++i) { PropertyAttributes attrs = propertyData.at(i); @@ -550,7 +628,9 @@ Heap::InternalClass *InternalClass::frozen() return t.lookup; } - Heap::InternalClass *f = engine->newClass(this); + Scope scope(engine); + Scoped<QV4::InternalClass> ic(scope, engine->newClass(this)); + Heap::InternalClass *f = ic->d(); for (uint i = 0; i < size; ++i) { PropertyAttributes attrs = propertyData.at(i); @@ -631,11 +711,7 @@ void InternalClass::markObjects(Heap::Base *b, MarkStack *stack) if (ic->parent) ic->parent->mark(stack); - for (uint i = 0; i < ic->size; ++i) { - PropertyKey id = ic->nameMap.at(i); - if (Heap::Base *b = id.asStringOrSymbol()) - b->mark(stack); - } + ic->nameMap.mark(stack); } } |