aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2024-02-09 21:29:26 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2024-03-05 14:06:28 +0100
commite19750538268c4d45fc6c60d2c90b17dd25c81e8 (patch)
tree03326ac7eab1f453e318f9f93b3447d26724eb7e /src/qml/qml
parent688c98a12da19a88becc152f832beb5c5a01ec47 (diff)
Prepare for white allocations during gc (1/9): Write barrier for Lookups
Lookups can (and do) reference HeapItems. This was safe in a non-incremental gc world, as Lookups are always reachable via their containing CompilationUnits, which are part of the root set. However, when using an incremental gc, an already marked Lookup might reference a new heap item, which then becomes otherwise unreachable. This is alleviated by the fact that Lookups generally either refer to something already existing or a freshly allocated string. The latter however is only safe when we can rely on black allocations during gc, and the former is somewhat reckless. Remedy this by employing the WriteBarrier for Lookups. We wrap all HeapItems in a helper class, which -while trivial itself- can't be used for direct assignments. Intead, it employs a set method which ensures that the WriteBarrier is used. Task-number: QTBUG-121910 Change-Id: I6a0ede66ad044076d2e87f134bc95686cb586aee Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqml.cpp8
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp15
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp2
3 files changed, 13 insertions, 12 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 23cea45f9d..be41216e54 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -2009,9 +2009,9 @@ static void initTypeWrapperLookup(
wrapper = l->qmlContextPropertyGetter(l, context->engine->handle(), wrapper);
l->qmlContextPropertyGetter = qmlContextPropertyGetter;
if (qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupSingleton)
- l->qmlContextSingletonLookup.singletonObject = wrapper->heapObject();
+ l->qmlContextSingletonLookup.singletonObject.set(scope.engine, wrapper->heapObject());
else if (qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupType)
- l->qmlTypeLookup.qmlTypeWrapper = wrapper->heapObject();
+ l->qmlTypeLookup.qmlTypeWrapper.set(scope.engine, wrapper->heapObject());
return;
}
scope.engine->throwTypeError();
@@ -2082,7 +2082,7 @@ void AOTCompiledContext::initLoadAttachedLookup(
scope, QV4::QQmlTypeWrapper::create(scope.engine, object, type,
QV4::Heap::QQmlTypeWrapper::ExcludeEnums));
- l->qmlTypeLookup.qmlTypeWrapper = wrapper->d();
+ l->qmlTypeLookup.qmlTypeWrapper.set(scope.engine, wrapper->d());
l->getter = QV4::QObjectWrapper::lookupAttached;
}
@@ -2093,7 +2093,7 @@ bool AOTCompiledContext::loadTypeLookup(uint index, void *target) const
return false;
const QV4::Heap::QQmlTypeWrapper *typeWrapper = static_cast<const QV4::Heap::QQmlTypeWrapper *>(
- l->qmlTypeLookup.qmlTypeWrapper);
+ l->qmlTypeLookup.qmlTypeWrapper.get());
QMetaType metaType = typeWrapper->type().typeId();
*static_cast<const QMetaObject **>(target)
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index cce30c51c9..0d8786a9df 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -477,8 +477,9 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object,
if (property) {
ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton)));
if (qualifiesForMethodLookup(property)) {
+ QV4::Heap::QObjectMethod *method = nullptr;
setupQObjectMethodLookup(
- lookup, ddata, property, val->objectValue(), nullptr);
+ lookup, ddata, property, val->objectValue(), method);
lookup->getter = QQmlTypeWrapper::lookupSingletonMethod;
} else {
setupQObjectLookup(
@@ -502,7 +503,7 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object,
bool ok = false;
int value = type.enumValue(QQmlEnginePrivate::get(engine->qmlEngine()), name, &ok);
if (ok) {
- lookup->qmlEnumValueLookup.ic = This->internalClass();
+ lookup->qmlEnumValueLookup.ic.set(engine, This->internalClass());
lookup->qmlEnumValueLookup.encodedEnumValue
= QV4::Value::fromInt32(value).asReturnedValue();
lookup->getter = QQmlTypeWrapper::lookupEnumValue;
@@ -517,9 +518,9 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object,
QQmlType::refHandle(enumWrapper->d()->typePrivate);
enumWrapper->d()->scopeEnumIndex = value;
- lookup->qmlScopedEnumWrapperLookup.ic = This->internalClass();
- lookup->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper
- = static_cast<Heap::Object*>(enumWrapper->heapObject());
+ lookup->qmlScopedEnumWrapperLookup.ic.set(engine, This->internalClass());
+ lookup->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper.set(engine,
+ static_cast<Heap::Object*>(enumWrapper->heapObject()));
lookup->getter = QQmlTypeWrapper::lookupScopedEnum;
return enumWrapper.asReturnedValue();
}
@@ -652,12 +653,12 @@ ReturnedValue QQmlTypeWrapper::lookupScopedEnum(Lookup *l, ExecutionEngine *engi
{
Scope scope(engine);
Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, static_cast<Heap::QQmlScopedEnumWrapper *>(
- l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper));
+ l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper.get()));
auto *o = static_cast<Heap::Object *>(base.heapObject());
if (!o || o->internalClass != l->qmlScopedEnumWrapperLookup.ic) {
QQmlType::derefHandle(enumWrapper->d()->typePrivate);
- l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper = nullptr;
+ l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper.clear();
l->getter = Lookup::getterGeneric;
return Lookup::getterGeneric(l, engine, base);
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index e0d684e377..7075d0f5f6 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -644,7 +644,7 @@ ReturnedValue QQmlValueTypeWrapper::virtualResolveLookupGetter(const Object *obj
if (!result.isValid())
return QV4::Object::virtualResolveLookupGetter(object, engine, lookup);
- lookup->qgadgetLookup.ic = r->internalClass();
+ lookup->qgadgetLookup.ic.set(engine, r->internalClass());
// & 1 to tell the gc that this is not heap allocated; see markObjects in qv4lookup_p.h
lookup->qgadgetLookup.metaObject = quintptr(r->d()->metaObject()) + 1;
lookup->qgadgetLookup.metaType = result.propType().iface();