aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2026-09-11 07:26:30 +0000
committerUlf Hermann <ulf.hermann@qt.io>2026-09-14 06:19:56 +0000
commit624d1680730963e57dd724282e64ebdd8e05af73 (patch)
tree9608d58837ebc96559b8c9b6288ecd72f219c7dc
parentee3721b70b08f02799ca7e60b7ae936f3e2db1fa (diff)
QtQml: Remove the rotten init/destroy call checking
QML_CHECK_INIT_DESTROY_CALLS was meant to catch heap objects being used before init(), used after destroy(), destroyed twice, or never destroyed. It has not compiled for a long time, and it's impossible to revive it without large scale refactoring. We can't stash an extra field into Heap::Base without changing the object layout quite a bit. Since it has been unused for a long time, we don't even know if it works correctly. Let's drop it. Without the checking there is no difference between d() and d_unchecked() anymore. Drop the latter. Task-number: QTBUG-149512 Change-Id: Ic489d76177509c39536c23ff362c0026ac53d0f5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4managed_p.h7
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/qml/jsruntime/qv4string_p.h7
-rw-r--r--src/qml/jsruntime/qv4vtable_p.h7
-rw-r--r--src/qml/memory/qv4heap_p.h42
-rw-r--r--src/qml/memory/qv4mm.cpp12
-rw-r--r--src/qml/memory/qv4mm_p.h4
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp2
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp2
10 files changed, 14 insertions, 73 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 5729d0e037..fbd75bf8d7 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -946,7 +946,7 @@ void ExecutionEngine::initRootContext()
{
Scope scope(this);
Scoped<ExecutionContext> r(scope, memoryManager->allocManaged<ExecutionContext>());
- r->d_unchecked()->init(Heap::ExecutionContext::Type_GlobalContext);
+ r->d()->init(Heap::ExecutionContext::Type_GlobalContext);
r->d()->activation.set(this, globalObject->d());
jsObjects[RootContext] = r;
jsObjects[ScriptContext] = r;
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index ef0f922fa3..3bb5c45906 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -48,12 +48,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
static const QV4::VTable static_vtbl; \
static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \
V4_MANAGED_SIZE_TEST \
- QV4::Heap::DataClass *d_unchecked() const { return static_cast<QV4::Heap::DataClass *>(m()); } \
- QV4::Heap::DataClass *d() const { \
- QV4::Heap::DataClass *dptr = d_unchecked(); \
- dptr->_checkIsInitialized(); \
- return dptr; \
- }
+ QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m()); }
#define V4_MANAGED(DataClass, superClass) \
private: \
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index adcca8b92c..4be9adedd3 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -2887,7 +2887,7 @@ ReturnedValue QmlSignalHandler::call(const Value *thisObject, const Value *argv,
void QmlSignalHandler::initProto(ExecutionEngine *engine)
{
- if (engine->signalHandlerPrototype()->d_unchecked())
+ if (engine->signalHandlerPrototype()->d())
return;
Scope scope(engine);
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 828e5664f0..d144a623ac 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -246,12 +246,7 @@ public:
struct ComplexString : String {
typedef QV4::Heap::ComplexString Data;
- QV4::Heap::ComplexString *d_unchecked() const { return static_cast<QV4::Heap::ComplexString *>(m()); }
- QV4::Heap::ComplexString *d() const {
- QV4::Heap::ComplexString *dptr = d_unchecked();
- dptr->_checkIsInitialized();
- return dptr;
- }
+ QV4::Heap::ComplexString *d() const { return static_cast<QV4::Heap::ComplexString *>(m()); }
};
inline
diff --git a/src/qml/jsruntime/qv4vtable_p.h b/src/qml/jsruntime/qv4vtable_p.h
index b8bae7ba72..ea0dd33992 100644
--- a/src/qml/jsruntime/qv4vtable_p.h
+++ b/src/qml/jsruntime/qv4vtable_p.h
@@ -271,12 +271,7 @@ const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname,
static const QV4::VTable static_vtbl; \
static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \
V4_MANAGED_SIZE_TEST \
- QV4::Heap::DataClass *d_unchecked() const { return static_cast<QV4::Heap::DataClass *>(m()); } \
- QV4::Heap::DataClass *d() const { \
- QV4::Heap::DataClass *dptr = d_unchecked(); \
- dptr->_checkIsInitialized(); \
- return dptr; \
- } \
+ QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m()); } \
static_assert(std::is_trivially_copyable_v<QV4::Heap::DataClass>); \
static_assert(std::is_trivially_default_constructible_v<QV4::Heap::DataClass>);
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index 46b53c1cea..c888ffca2e 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -21,10 +21,6 @@
#include <private/qv4vtable_p.h>
#include <QtCore/QSharedPointer>
-// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
-// parent's init all up the inheritance chain), define QML_CHECK_INIT_DESTROY_CALLS below.
-#undef QML_CHECK_INIT_DESTROY_CALLS
-
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -91,42 +87,8 @@ struct Q_QML_EXPORT Base {
void *operator new(size_t, Base *m) { return m; }
void operator delete(void *, Base *) {}
- void init() { _setInitialized(); }
- void destroy() { _setDestroyed(); }
-#ifdef QML_CHECK_INIT_DESTROY_CALLS
- enum { Uninitialized = 0, Initialized, Destroyed } _livenessStatus;
- void _checkIsInitialized() {
- if (_livenessStatus == Uninitialized)
- fprintf(stderr, "ERROR: use of object '%s' before call to init() !!\n",
- vtable()->className);
- else if (_livenessStatus == Destroyed)
- fprintf(stderr, "ERROR: use of object '%s' after call to destroy() !!\n",
- vtable()->className);
- Q_ASSERT(_livenessStatus == Initialized);
- }
- void _checkIsDestroyed() {
- if (_livenessStatus == Initialized)
- fprintf(stderr, "ERROR: object '%s' was never destroyed completely !!\n",
- vtable()->className);
- Q_ASSERT(_livenessStatus == Destroyed);
- }
- void _setInitialized() { Q_ASSERT(_livenessStatus == Uninitialized); _livenessStatus = Initialized; }
- void _setDestroyed() {
- if (_livenessStatus == Uninitialized)
- fprintf(stderr, "ERROR: attempting to destroy an uninitialized object '%s' !!\n",
- vtable()->className);
- else if (_livenessStatus == Destroyed)
- fprintf(stderr, "ERROR: attempting to destroy repeatedly object '%s' !!\n",
- vtable()->className);
- Q_ASSERT(_livenessStatus == Initialized);
- _livenessStatus = Destroyed;
- }
-#else
- Q_ALWAYS_INLINE void _checkIsInitialized() {}
- Q_ALWAYS_INLINE void _checkIsDestroyed() {}
- Q_ALWAYS_INLINE void _setInitialized() {}
- Q_ALWAYS_INLINE void _setDestroyed() {}
-#endif
+ void init() {}
+ void destroy() {}
};
static_assert(std::is_trivially_copyable_v<Base>);
static_assert(std::is_trivially_default_constructible_v<Base>);
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 31634ed0e0..84d2c2b79f 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -292,10 +292,8 @@ bool Chunk::sweep(ExecutionEngine *engine)
const VTable *v = b->internalClass->vtable;
// if (Q_UNLIKELY(classCountPtr))
// classCountPtr(v->className);
- if (v->destroy) {
+ if (v->destroy)
v->destroy(b);
- b->_checkIsDestroyed();
- }
#ifdef V4_USE_HEAPTRACK
heaptrack_report_free(itemToFree);
#endif
@@ -338,10 +336,8 @@ void Chunk::freeAll(ExecutionEngine *engine)
HeapItem *itemToFree = o + index;
Heap::Base *b = *itemToFree;
- if (b->internalClass->vtable->destroy) {
+ if (b->internalClass->vtable->destroy)
b->internalClass->vtable->destroy(b);
- b->_checkIsDestroyed();
- }
#ifdef V4_USE_HEAPTRACK
heaptrack_report_free(itemToFree);
#endif
@@ -591,10 +587,8 @@ static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocato
Heap::Base *b = *itemToFree;
const VTable *v = b->internalClass->vtable;
- if (v->destroy) {
+ if (v->destroy)
v->destroy(b);
- b->_checkIsDestroyed();
- }
if (c.segment) {
// own memory segment
c.segment->free(c.chunk, c.size);
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 30ae40f12a..631138dec5 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -373,7 +373,7 @@ public:
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>());
- t->d_unchecked()->init(std::forward<Args>(args)...);
+ t->d()->init(std::forward<Args>(args)...);
return t->d();
}
@@ -382,7 +382,7 @@ public:
{
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>());
- t->d_unchecked()->init(std::forward<Args>(args)...);
+ t->d()->init(std::forward<Args>(args)...);
return t->d();
}
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index fea5cfb97a..1cdc7664b0 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -230,7 +230,7 @@ ReturnedValue QQmlTypeWrapper::method_toString(
void QQmlTypeWrapper::initProto(ExecutionEngine *v4)
{
- if (v4->typeWrapperPrototype()->d_unchecked())
+ if (v4->typeWrapperPrototype()->d())
return;
Scope scope(v4);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 66a4606d3d..cffc2bfc22 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -118,7 +118,7 @@ ReturnedValue QQmlValueTypeWrapper::create(
void QQmlValueTypeWrapper::initProto(ExecutionEngine *v4)
{
- if (v4->valueTypeWrapperPrototype()->d_unchecked())
+ if (v4->valueTypeWrapperPrototype()->d())
return;
Scope scope(v4);