From 81f8cd92e7adbf6582e6fa01cf9444070c32d346 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Fri, 26 Jan 2024 12:23:41 +0100 Subject: 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 --- src/qml/jsruntime/qv4internalclass_p.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/qml/jsruntime') 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 { 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 { SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate &other, uint pos, PropertyKey value); ~SharedInternalClassDataPrivate() {} + template + void markIfNecessary(const PropertyKey &value); + void grow(); uint alloc() const; uint size() const; @@ -196,6 +201,17 @@ private: Heap::MemberData *data; }; +template +void QV4::SharedInternalClassDataPrivate::markIfNecessary(const PropertyKey &value) +{ + QV4::WriteBarrier::markCustom(engine, [&](QV4::MarkStack *stack) { + if constexpr (QV4::WriteBarrier::isInsertionBarrier) { + if (auto s = value.asStringOrSymbol()) + s->mark(stack); + } + }); +} + template struct SharedInternalClassData { using Private = SharedInternalClassDataPrivate; @@ -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); -- cgit v1.2.3