aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2024-01-26 12:23:41 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2024-02-03 11:36:43 +0100
commit81f8cd92e7adbf6582e6fa01cf9444070c32d346 (patch)
tree4c236fdeca62de0c17164ab6a8f6431505ab401f /src/qml/jsruntime
parent718ed149327c03bec33e8befcefaadf2033270d6 (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.h18
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);