diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-01-26 12:23:41 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-02-03 11:36:43 +0100 |
commit | 81f8cd92e7adbf6582e6fa01cf9444070c32d346 (patch) | |
tree | 4c236fdeca62de0c17164ab6a8f6431505ab401f /src/qml/jsruntime | |
parent | 718ed149327c03bec33e8befcefaadf2033270d6 (diff) |
SharedInternalClassData: Mark newly inserted values
If a Heap value is inserted into a SharedInternalClassData instance
which was already marked, we would potentially never mark the entry at
all.
Note that this is only necessary for the PropertyKey specialization, as
PropertyAttributes does not contain any heap values.
Change-Id: I0da098936bcc940cd24123cb58a90b2ee4234f3f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index d14579b4ce..68c0fe57a0 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -133,6 +133,8 @@ struct SharedInternalClassDataPrivate<PropertyAttributes> { void grow(); + void markIfNecessary(const PropertyAttributes &) {} + uint alloc() const { return m_alloc; } uint size() const { return m_size; } void setSize(uint s) { m_size = s; } @@ -180,6 +182,9 @@ struct SharedInternalClassDataPrivate<PropertyKey> { SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate &other, uint pos, PropertyKey value); ~SharedInternalClassDataPrivate() {} + template<typename StringOrSymbol = Heap::StringOrSymbol> + void markIfNecessary(const PropertyKey &value); + void grow(); uint alloc() const; uint size() const; @@ -196,6 +201,17 @@ private: Heap::MemberData *data; }; +template<typename StringOrSymbol> +void QV4::SharedInternalClassDataPrivate<PropertyKey>::markIfNecessary(const PropertyKey &value) +{ + QV4::WriteBarrier::markCustom(engine, [&](QV4::MarkStack *stack) { + if constexpr (QV4::WriteBarrier::isInsertionBarrier) { + if (auto s = value.asStringOrSymbol<StringOrSymbol>()) + s->mark(stack); + } + }); +} + template <typename T> struct SharedInternalClassData { using Private = SharedInternalClassDataPrivate<T>; @@ -223,6 +239,7 @@ struct SharedInternalClassData { } void add(uint pos, T value) { + d->markIfNecessary(value); if (pos < d->size()) { Q_ASSERT(d->refcount > 1); // need to detach @@ -244,6 +261,7 @@ struct SharedInternalClassData { void set(uint pos, T value) { Q_ASSERT(pos < d->size()); + d->markIfNecessary(value); if (d->refcount > 1) { // need to detach Private *dd = new Private(*d); |