Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4heap_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef QV4HEAP_P_H
4#define QV4HEAP_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <private/qv4global_p.h>
18#include <private/qv4mmdefs_p.h>
19#include <private/qv4writebarrier_p.h>
20#include <private/qv4vtable_p.h>
21#include <QtCore/QSharedPointer>
22
23// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
24// parent's init all up the inheritance chain), define QML_CHECK_INIT_DESTROY_CALLS below.
25#undef QML_CHECK_INIT_DESTROY_CALLS
26
28
29namespace QV4 {
30
31namespace Heap {
32
33template <typename T, size_t o>
34struct Pointer {
35 static constexpr size_t offset = o;
36 T operator->() const { return get(); }
37 operator T () const { return get(); }
38
40
41 void set(EngineBase *e, T newVal) {
42 WriteBarrier::write(e, base(), &ptr, reinterpret_cast<Base *>(newVal));
43 }
44
45 T get() const { return reinterpret_cast<T>(ptr); }
46
47 template <typename Type>
48 Type *cast() { return static_cast<Type *>(ptr); }
49
50 Base *heapObject() const { return ptr; }
51
52private:
53 Base *ptr;
54};
55typedef Pointer<char *, 0> V4PointerCheck;
56Q_STATIC_ASSERT(std::is_trivial_v<V4PointerCheck>);
57
58struct Q_QML_EXPORT Base {
59 void *operator new(size_t) = delete;
60
61 static void markObjects(Base *, MarkStack *);
62
63 Pointer<InternalClass *, 0> internalClass;
64
65 inline ReturnedValue asReturnedValue() const;
66 inline void mark(QV4::MarkStack *markStack);
67
68 inline bool isMarked() const {
69 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
70 Chunk *c = h->chunk();
71 Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
72 return Chunk::testBit(c->blackBitmap, h - c->realBase());
73 }
74 inline void setMarkBit() {
75 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
76 Chunk *c = h->chunk();
77 Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
78 return Chunk::setBit(c->blackBitmap, h - c->realBase());
79 }
80
81 inline bool inUse() const {
82 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
83 Chunk *c = h->chunk();
84 Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
85 return Chunk::testBit(c->objectBitmap, h - c->realBase());
86 }
87
88 void *operator new(size_t, Managed *m) { return m; }
89 void *operator new(size_t, Base *m) { return m; }
90 void operator delete(void *, Base *) {}
91
92 void init() { _setInitialized(); }
93 void destroy() { _setDestroyed(); }
94#ifdef QML_CHECK_INIT_DESTROY_CALLS
95 enum { Uninitialized = 0, Initialized, Destroyed } _livenessStatus;
96 void _checkIsInitialized() {
97 if (_livenessStatus == Uninitialized)
98 fprintf(stderr, "ERROR: use of object '%s' before call to init() !!\n",
99 vtable()->className);
100 else if (_livenessStatus == Destroyed)
101 fprintf(stderr, "ERROR: use of object '%s' after call to destroy() !!\n",
102 vtable()->className);
103 Q_ASSERT(_livenessStatus == Initialized);
104 }
105 void _checkIsDestroyed() {
106 if (_livenessStatus == Initialized)
107 fprintf(stderr, "ERROR: object '%s' was never destroyed completely !!\n",
108 vtable()->className);
109 Q_ASSERT(_livenessStatus == Destroyed);
110 }
111 void _setInitialized() { Q_ASSERT(_livenessStatus == Uninitialized); _livenessStatus = Initialized; }
112 void _setDestroyed() {
113 if (_livenessStatus == Uninitialized)
114 fprintf(stderr, "ERROR: attempting to destroy an uninitialized object '%s' !!\n",
115 vtable()->className);
116 else if (_livenessStatus == Destroyed)
117 fprintf(stderr, "ERROR: attempting to destroy repeatedly object '%s' !!\n",
118 vtable()->className);
119 Q_ASSERT(_livenessStatus == Initialized);
120 _livenessStatus = Destroyed;
121 }
122#else
127#endif
128};
129Q_STATIC_ASSERT(std::is_trivial_v<Base>);
130// This class needs to consist only of pointer sized members to allow
131// for a size/offset translation when cross-compiling between 32- and
132// 64-bit.
133Q_STATIC_ASSERT(std::is_standard_layout<Base>::value);
134Q_STATIC_ASSERT(offsetof(Base, internalClass) == 0);
136
137inline
139{
140 Q_ASSERT(inUse());
141 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
142 Chunk *c = h->chunk();
143 size_t index = h - c->realBase();
144 Q_ASSERT(!Chunk::testBit(c->extendsBitmap, index));
145 quintptr *bitmap = c->blackBitmap + Chunk::bitmapIndex(index);
147 if (!(*bitmap & bit)) {
148 *bitmap |= bit;
149 markStack->push(this);
150 }
151}
152
153template<typename T, size_t o>
155 Base *base = reinterpret_cast<Base *>(this) - (offset/sizeof(Base *));
156 Q_ASSERT(base->inUse());
157 return base;
158}
159
160}
161
162#ifdef QT_NO_QOBJECT
163template <class T>
164struct QV4QPointer {
165};
166#else
167template <class T>
169 void init()
170 {
171 d = nullptr;
172 qObject = nullptr;
173 }
174
175 void init(T *o)
176 {
177 Q_ASSERT(d == nullptr);
178 Q_ASSERT(qObject == nullptr);
179 if (o) {
181 qObject = o;
182 }
183 }
184
185 void destroy()
186 {
187 if (d && !d->weakref.deref())
188 delete d;
189 d = nullptr;
190 qObject = nullptr;
191 }
192
193 T *data() const {
194 return d == nullptr || d->strongref.loadRelaxed() == 0 ? nullptr : qObject;
195 }
196 operator T*() const { return data(); }
197 inline T* operator->() const { return data(); }
199 {
200 if (d)
201 destroy();
202 init(o);
203 return *this;
204 }
205
206 bool isNull() const noexcept
207 {
208 return !isValid() || d->strongref.loadRelaxed() == 0;
209 }
210
211 bool isValid() const noexcept
212 {
213 return d != nullptr && qObject != nullptr;
214 }
215
216private:
218 QObject *qObject;
219};
220Q_STATIC_ASSERT(std::is_trivial_v<QV4QPointer<QObject>>);
221#endif
222
223}
224
226
227#endif
bool deref() noexcept
T loadRelaxed() const noexcept
\inmodule QtCore
Definition qobject.h:103
Combined button and popup list for selecting options.
Pointer< char *, 0 > V4PointerCheck
Definition qv4heap_p.h:55
quint64 ReturnedValue
#define Q_STATIC_ASSERT(Condition)
Definition qassert.h:108
#define Q_ALWAYS_INLINE
constexpr int Uninitialized
const GLfloat * m
GLuint index
[2]
GLenum GLuint GLintptr offset
GLfloat GLfloat GLfloat GLfloat h
const GLubyte * c
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
#define QT_POINTER_SIZE
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
size_t quintptr
Definition qtypes.h:167
static const uint base
Definition qurlidna.cpp:20
const char className[16]
[1]
Definition qwizard.cpp:100
QObject::connect nullptr
static bool testBit(quintptr *bitmap, size_t index)
static Q_ALWAYS_INLINE quintptr bitForIndex(size_t index)
Definition qv4mmdefs_p.h:87
HeapItem * realBase()
static Q_ALWAYS_INLINE size_t bitmapIndex(size_t index)
Definition qv4mmdefs_p.h:84
void mark(QV4::MarkStack *markStack)
Definition qv4heap_p.h:138
Q_ALWAYS_INLINE void _setInitialized()
Definition qv4heap_p.h:125
Q_ALWAYS_INLINE void _checkIsInitialized()
Definition qv4heap_p.h:123
Q_ALWAYS_INLINE void _setDestroyed()
Definition qv4heap_p.h:126
void setMarkBit()
Definition qv4heap_p.h:74
Q_ALWAYS_INLINE void _checkIsDestroyed()
Definition qv4heap_p.h:124
Pointer< InternalClass *, 0 > internalClass
Definition qv4heap_p.h:63
bool inUse() const
Definition qv4heap_p.h:81
bool isMarked() const
Definition qv4heap_p.h:68
Base * heapObject() const
Definition qv4heap_p.h:50
void set(EngineBase *e, T newVal)
Definition qv4heap_p.h:41
T operator->() const
Definition qv4heap_p.h:36
void push(Heap::Base *m)
bool isValid() const noexcept
Definition qv4heap_p.h:211
void init(T *o)
Definition qv4heap_p.h:175
T * data() const
Definition qv4heap_p.h:193
T * operator->() const
Definition qv4heap_p.h:197
bool isNull() const noexcept
Definition qv4heap_p.h:206
QV4QPointer & operator=(T *o)
Definition qv4heap_p.h:198
static Q_ALWAYS_INLINE void write(EngineBase *engine, Heap::Base *base, ReturnedValue *slot, ReturnedValue value)
static Q_CORE_EXPORT ExternalRefCountData * getAndRef(const QObject *)
Definition moc.h:23