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
28
QT_BEGIN_NAMESPACE
29
30
namespace
QV4
{
31
32
namespace
Heap
{
33
34
template
<
typename
T, size_t o>
35
struct
Pointer
{
36
static
constexpr
size_t
offset
= o;
37
T
operator
->()
const
{
return
get
(
)
; }
38
operator
T ()
const
{
return
get
(
)
; }
39
40
Base
*
base
();
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
53
private
:
54
Base *ptr;
55
};
56
typedef
Pointer
<
char
*, 0>
V4PointerCheck
;
57
Q_STATIC_ASSERT
(
std
::
is_trivial_v
<
V4PointerCheck
>);
58
59
struct
Q_QML_EXPORT
Base
{
60
void
*
operator
new
(
size_t
) =
delete
;
61
62
static
void
markObjects
(
Base
*,
MarkStack
*);
63
64
Pointer
<
InternalClass
*, 0>
internalClass
;
65
66
inline
ReturnedValue
asReturnedValue
()
const
;
67
inline
void
mark
(
QV4
::
MarkStack
*
markStack
);
68
69
inline
bool
isMarked
()
const
{
70
const
HeapItem
*
h
=
reinterpret_cast
<
const
HeapItem
*>(
this
);
71
Chunk
*
c
=
h
->
chunk
();
72
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
h
-
c
->
realBase
()));
73
return
Chunk
::
testBit
(
c
->
blackBitmap
,
h
-
c
->
realBase
());
74
}
75
inline
void
setMarkBit
() {
76
const
HeapItem
*
h
=
reinterpret_cast
<
const
HeapItem
*>(
this
);
77
Chunk
*
c
=
h
->
chunk
();
78
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
h
-
c
->
realBase
()));
79
return
Chunk
::
setBit
(
c
->
blackBitmap
,
h
-
c
->
realBase
());
80
}
81
82
inline
bool
inUse
()
const
{
83
const
HeapItem
*
h
=
reinterpret_cast
<
const
HeapItem
*>(
this
);
84
Chunk
*
c
=
h
->
chunk
();
85
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
h
-
c
->
realBase
()));
86
return
Chunk
::
testBit
(
c
->
objectBitmap
,
h
-
c
->
realBase
());
87
}
88
89
void
*
operator
new
(
size_t
,
Managed
*
m
) {
return
m
; }
90
void
*
operator
new
(
size_t
,
Base
*
m
) {
return
m
; }
91
void
operator
delete
(
void
*,
Base
*) {}
92
93
void
init
() {
_setInitialized
(); }
94
void
destroy
() {
_setDestroyed
(); }
95
#
ifdef
QML_CHECK_INIT_DESTROY_CALLS
96
enum
{
Uninitialized
= 0,
Initialized
,
Destroyed
}
_livenessStatus
;
97
void
_checkIsInitialized
() {
98
if
(
_livenessStatus
==
Uninitialized
)
99
fprintf
(
stderr
,
"ERROR: use of object '%s' before call to init() !!\n"
,
100
vtable
()->
className
);
101
else
if
(
_livenessStatus
==
Destroyed
)
102
fprintf
(
stderr
,
"ERROR: use of object '%s' after call to destroy() !!\n"
,
103
vtable
()->
className
);
104
Q_ASSERT
(
_livenessStatus
==
Initialized
);
105
}
106
void
_checkIsDestroyed
() {
107
if
(
_livenessStatus
==
Initialized
)
108
fprintf
(
stderr
,
"ERROR: object '%s' was never destroyed completely !!\n"
,
109
vtable
()->
className
);
110
Q_ASSERT
(
_livenessStatus
==
Destroyed
);
111
}
112
void
_setInitialized
() {
Q_ASSERT
(
_livenessStatus
==
Uninitialized
);
_livenessStatus
=
Initialized
; }
113
void
_setDestroyed
() {
114
if
(
_livenessStatus
==
Uninitialized
)
115
fprintf
(
stderr
,
"ERROR: attempting to destroy an uninitialized object '%s' !!\n"
,
116
vtable
()->
className
);
117
else
if
(
_livenessStatus
==
Destroyed
)
118
fprintf
(
stderr
,
"ERROR: attempting to destroy repeatedly object '%s' !!\n"
,
119
vtable
()->
className
);
120
Q_ASSERT
(
_livenessStatus
==
Initialized
);
121
_livenessStatus
=
Destroyed
;
122
}
123
#
else
124
Q_ALWAYS_INLINE
void
_checkIsInitialized
() {}
125
Q_ALWAYS_INLINE
void
_checkIsDestroyed
() {}
126
Q_ALWAYS_INLINE
void
_setInitialized
() {}
127
Q_ALWAYS_INLINE
void
_setDestroyed
() {}
128
#
endif
129
};
130
Q_STATIC_ASSERT
(
std
::
is_trivial_v
<
Base
>);
131
// This class needs to consist only of pointer sized members to allow
132
// for a size/offset translation when cross-compiling between 32- and
133
// 64-bit.
134
Q_STATIC_ASSERT
(
std
::
is_standard_layout
<
Base
>::
value
);
135
Q_STATIC_ASSERT
(offsetof(
Base
, internalClass) == 0);
136
Q_STATIC_ASSERT
(
sizeof
(
Base
) ==
QT_POINTER_SIZE
);
137
138
inline
139
void
Base
::
mark
(
QV4
::
MarkStack
*
markStack
)
140
{
141
Q_ASSERT
(
inUse
());
142
const
HeapItem
*
h
=
reinterpret_cast
<
const
HeapItem
*>(
this
);
143
Chunk
*
c
=
h
->
chunk
();
144
size_t
index
=
h
-
c
->
realBase
();
145
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
index
));
146
quintptr
*
bitmap
=
c
->
blackBitmap
+
Chunk
::
bitmapIndex
(
index
);
147
quintptr
bit
=
Chunk
::
bitForIndex
(
index
);
148
if
(!(*
bitmap
&
bit
)) {
149
*
bitmap
|=
bit
;
150
markStack
->
push
(
this
);
151
}
152
}
153
154
template
<
typename
T, size_t o>
155
Base
*
Pointer
<T, o>::
base
() {
156
Base *base =
reinterpret_cast
<Base *>(
this
) - (offset/
sizeof
(Base *));
157
Q_ASSERT(base->inUse());
158
return
base;
159
}
160
161
}
162
163
#
ifdef
QT_NO_QOBJECT
164
template
<
class
T
>
165
struct
QV4QPointer
{
166
};
167
#
else
168
template
<
class
T>
169
struct
QV4QPointer
{
170
void
init
()
171
{
172
d =
nullptr
;
173
qObject =
nullptr
;
174
}
175
176
void
init
(T *o)
177
{
178
Q_ASSERT(d ==
nullptr
);
179
Q_ASSERT(qObject ==
nullptr
);
180
if
(o) {
181
d = QtSharedPointer::ExternalRefCountData::getAndRef(o);
182
qObject = o;
183
}
184
}
185
186
void
destroy
()
187
{
188
if
(d && !d->weakref.deref())
189
delete
d;
190
d =
nullptr
;
191
qObject =
nullptr
;
192
}
193
194
T *
data
()
const
{
195
return
d ==
nullptr
|| d->strongref.loadRelaxed() == 0 ?
nullptr
: qObject;
196
}
197
operator
T*()
const
{
return
data
(
)
; }
198
inline
T*
operator
->()
const
{
return
data
(
)
; }
199
QV4QPointer
&
operator
=(T *o)
200
{
201
if
(d)
202
destroy
(
)
;
203
init(o);
204
return
*
this
;
205
}
206
207
bool
isNull
()
const
noexcept
208
{
209
return
!isValid() || d->strongref.loadRelaxed() == 0;
210
}
211
212
bool
isValid
()
const
noexcept
213
{
214
return
d !=
nullptr
&& qObject !=
nullptr
;
215
}
216
217
private
:
218
QtSharedPointer::ExternalRefCountData *d;
219
T *qObject;
220
};
221
Q_STATIC_ASSERT
(
std
::
is_trivial_v
<
QV4QPointer
<
QObject
>>);
222
#
endif
223
224
}
225
226
QT_END_NAMESPACE
227
228
#
endif
QV4::Heap
Definition
qv4compileddata_p.h:73
QV4::Heap::V4PointerCheck
Pointer< char *, 0 > V4PointerCheck
Definition
qv4heap_p.h:56
QV4::Heap::Q_STATIC_ASSERT
Q_STATIC_ASSERT(std::is_trivial_v< ArrayData >)
QV4
Definition
qjsvalue.h:24
QV4::Heap::Base
Definition
qv4heap_p.h:59
QV4::Heap::Pointer
Definition
qv4heap_p.h:35
QV4::Heap::Pointer::heapObject
Base * heapObject() const
Definition
qv4heap_p.h:51
QV4::Heap::Pointer::base
Base * base()
Definition
qv4heap_p.h:155
QV4::Heap::Pointer::cast
Type * cast()
Definition
qv4heap_p.h:49
QV4::Heap::Pointer::set
void set(EngineBase *e, T newVal)
Definition
qv4heap_p.h:42
QV4::Heap::Pointer::operator->
T operator->() const
Definition
qv4heap_p.h:37
QV4::Heap::Pointer::get
T get() const
Definition
qv4heap_p.h:46
QV4::Heap::Pointer::offset
static constexpr size_t offset
Definition
qv4heap_p.h:36
QV4::Heap::Pointer::operator T
operator T() const
Definition
qv4heap_p.h:38
QV4::QV4QPointer
Definition
qv4heap_p.h:169
QV4::QV4QPointer::init
void init()
Definition
qv4heap_p.h:170
QV4::QV4QPointer::isValid
bool isValid() const noexcept
Definition
qv4heap_p.h:212
QV4::QV4QPointer::destroy
void destroy()
Definition
qv4heap_p.h:186
QV4::QV4QPointer::init
void init(T *o)
Definition
qv4heap_p.h:176
QV4::QV4QPointer::data
T * data() const
Definition
qv4heap_p.h:194
QV4::QV4QPointer::operator->
T * operator->() const
Definition
qv4heap_p.h:198
QV4::QV4QPointer::operator T*
operator T*() const
Definition
qv4heap_p.h:197
QV4::QV4QPointer::isNull
bool isNull() const noexcept
Definition
qv4heap_p.h:207
QV4::QV4QPointer::operator=
QV4QPointer & operator=(T *o)
Definition
qv4heap_p.h:199
qtdeclarative
src
qml
memory
qv4heap_p.h
Generated on
for Qt by
1.16.1