Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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// Qt-Security score:critical reason:low-level-memory-management
4#ifndef QV4HEAP_P_H
5#define QV4HEAP_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qv4global_p.h>
19#include <private/qv4mmdefs_p.h>
20#include <private/qv4writebarrier_p.h>
21#include <private/qv4vtable_p.h>
22#include <QtCore/QSharedPointer>
23
24// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
25// parent's init all up the inheritance chain), define QML_CHECK_INIT_DESTROY_CALLS below.
26#undef QML_CHECK_INIT_DESTROY_CALLS
27
28QT_BEGIN_NAMESPACE
29
30namespace QV4 {
31
32namespace Heap {
33
34template <typename T, size_t o>
35struct Pointer {
36 static constexpr size_t offset = o;
37 T operator->() const { return get(); }
38 operator T () const { return get(); }
39
41
42 void set(EngineBase *e, T newVal) {
43 WriteBarrier::write(e, base(), &ptr, reinterpret_cast<Base *>(newVal));
44 }
45
46 T get() const { return reinterpret_cast<T>(ptr); }
47
48 template <typename Type>
49 Type *cast() { return static_cast<Type *>(ptr); }
50
51 Base *heapObject() const { return ptr; }
52
53private:
54 Base *ptr;
55};
56typedef Pointer<char *, 0> V4PointerCheck;
59
60struct Q_QML_EXPORT Base {
61 void *operator new(size_t) = delete;
62
63 static void markObjects(Base *, MarkStack *);
64
66
67 inline ReturnedValue asReturnedValue() const;
68 inline void mark(QV4::MarkStack *markStack);
69
70 inline bool isMarked() const {
71 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
72 Chunk *c = h->chunk();
74 return Chunk::testBit(c->blackBitmap, h - c->realBase());
75 }
76 inline void setMarkBit() {
77 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
78 Chunk *c = h->chunk();
80 return Chunk::setBit(c->blackBitmap, h - c->realBase());
81 }
82
83 inline bool inUse() const {
84 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
85 Chunk *c = h->chunk();
87 return Chunk::testBit(c->objectBitmap, h - c->realBase());
88 }
89
90 void *operator new(size_t, Managed *m) { return m; }
91 void *operator new(size_t, Base *m) { return m; }
92 void operator delete(void *, Base *) {}
93
94 void init() { _setInitialized(); }
95 void destroy() { _setDestroyed(); }
96#ifdef QML_CHECK_INIT_DESTROY_CALLS
98 void _checkIsInitialized() {
100 fprintf(stderr, "ERROR: use of object '%s' before call to init() !!\n",
101 vtable()->className);
102 else if (_livenessStatus == Destroyed)
103 fprintf(stderr, "ERROR: use of object '%s' after call to destroy() !!\n",
104 vtable()->className);
106 }
107 void _checkIsDestroyed() {
109 fprintf(stderr, "ERROR: object '%s' was never destroyed completely !!\n",
110 vtable()->className);
112 }
114 void _setDestroyed() {
116 fprintf(stderr, "ERROR: attempting to destroy an uninitialized object '%s' !!\n",
117 vtable()->className);
118 else if (_livenessStatus == Destroyed)
119 fprintf(stderr, "ERROR: attempting to destroy repeatedly object '%s' !!\n",
120 vtable()->className);
123 }
124#else
129#endif
130};
131static_assert(std::is_trivially_copyable_v<Base>);
133// This class needs to consist only of pointer sized members to allow
134// for a size/offset translation when cross-compiling between 32- and
135// 64-bit.
136static_assert(std::is_standard_layout<Base>::value);
137static_assert(offsetof(Base, internalClass) == 0);
138static_assert(sizeof(Base) == QT_POINTER_SIZE);
139
140inline
142{
143 Q_ASSERT(inUse());
144 const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
145 Chunk *c = h->chunk();
146 size_t index = h - c->realBase();
150 if (!(*bitmap & bit)) {
151 *bitmap |= bit;
152 markStack->push(this);
153 }
154}
155
156template<typename T, size_t o>
157Base *Pointer<T, o>::base() {
158 Base *base = reinterpret_cast<Base *>(this) - (offset/sizeof(Base *));
159 Q_ASSERT(base->inUse());
160 return base;
161}
162
163}
164
165#ifdef QT_NO_QOBJECT
166template <class T>
167struct QV4QPointer {
168};
169#else
170template <class T>
172 void init()
173 {
174 d = nullptr;
175 qObject = nullptr;
176 }
177
178 void init(T *o)
179 {
180 Q_ASSERT(d == nullptr);
181 Q_ASSERT(qObject == nullptr);
182 if (o) {
183 d = QtSharedPointer::ExternalRefCountData::getAndRef(o);
184 qObject = o;
185 }
186 }
187
188 void destroy()
189 {
190 if (d && !d->weakref.deref())
191 delete d;
192 d = nullptr;
193 qObject = nullptr;
194 }
195
196 T *data() const {
197 return d == nullptr || d->strongref.loadRelaxed() == 0 ? nullptr : qObject;
198 }
199 operator T*() const { return data(); }
200 inline T* operator->() const { return data(); }
202 {
203 if (d)
204 destroy();
205 init(o);
206 return *this;
207 }
208
209 bool isNull() const noexcept
210 {
211 return !isValid() || d->strongref.loadRelaxed() == 0;
212 }
213
214 bool isValid() const noexcept
215 {
216 return d != nullptr && qObject != nullptr;
217 }
218
219private:
220 QtSharedPointer::ExternalRefCountData *d;
221 T *qObject;
222};
225#endif
226
227}
228
229QT_END_NAMESPACE
230
231#endif
Pointer< char *, 0 > V4PointerCheck
Definition qv4heap_p.h:56
Definition qjsvalue.h:24
Base * heapObject() const
Definition qv4heap_p.h:51
void set(EngineBase *e, T newVal)
Definition qv4heap_p.h:42
T operator->() const
Definition qv4heap_p.h:37
static constexpr size_t offset
Definition qv4heap_p.h:36
bool isValid() const noexcept
Definition qv4heap_p.h:214
void init(T *o)
Definition qv4heap_p.h:178
T * data() const
Definition qv4heap_p.h:196
T * operator->() const
Definition qv4heap_p.h:200
operator T*() const
Definition qv4heap_p.h:199
bool isNull() const noexcept
Definition qv4heap_p.h:209
QV4QPointer & operator=(T *o)
Definition qv4heap_p.h:201