aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4internalclass.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-09-10 23:30:04 +0200
committerLars Knoll <lars.knoll@qt.io>2018-09-16 17:00:22 +0000
commite436fb3569603bca8ad0a71fef67c03d2920aedc (patch)
treea8076925a788fd721c8b46119f0f13009ca882e8 /src/qml/jsruntime/qv4internalclass.cpp
parent6982d0d6290c137468749bb8ab2f2e20dfa453fd (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.cpp100
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);
}
}