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
static_assert
(
std
::
is_trivially_copyable_v
<
V4PointerCheck
>);
58
static_assert
(
std
::
is_trivially_default_constructible_v
<
V4PointerCheck
>);
59
60
struct
Q_QML_EXPORT
Base
{
61
void
*
operator
new
(
size_t
) =
delete
;
62
63
static
void
markObjects
(
Base
*,
MarkStack
*);
64
65
Pointer
<
InternalClass
*, 0>
internalClass
;
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
();
73
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
h
-
c
->
realBase
()));
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
();
79
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
h
-
c
->
realBase
()));
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
();
86
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
h
-
c
->
realBase
()));
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
97
enum
{
Uninitialized
= 0,
Initialized
,
Destroyed
}
_livenessStatus
;
98
void
_checkIsInitialized
() {
99
if
(
_livenessStatus
==
Uninitialized
)
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
);
105
Q_ASSERT
(
_livenessStatus
==
Initialized
);
106
}
107
void
_checkIsDestroyed
() {
108
if
(
_livenessStatus
==
Initialized
)
109
fprintf
(
stderr
,
"ERROR: object '%s' was never destroyed completely !!\n"
,
110
vtable
()->
className
);
111
Q_ASSERT
(
_livenessStatus
==
Destroyed
);
112
}
113
void
_setInitialized
() {
Q_ASSERT
(
_livenessStatus
==
Uninitialized
);
_livenessStatus
=
Initialized
; }
114
void
_setDestroyed
() {
115
if
(
_livenessStatus
==
Uninitialized
)
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
);
121
Q_ASSERT
(
_livenessStatus
==
Initialized
);
122
_livenessStatus
=
Destroyed
;
123
}
124
#
else
125
Q_ALWAYS_INLINE
void
_checkIsInitialized
() {}
126
Q_ALWAYS_INLINE
void
_checkIsDestroyed
() {}
127
Q_ALWAYS_INLINE
void
_setInitialized
() {}
128
Q_ALWAYS_INLINE
void
_setDestroyed
() {}
129
#
endif
130
};
131
static_assert
(
std
::
is_trivially_copyable_v
<
Base
>);
132
static_assert
(
std
::
is_trivially_default_constructible_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.
136
static_assert
(
std
::
is_standard_layout
<
Base
>::
value
);
137
static_assert
(offsetof(Base, internalClass) == 0);
138
static_assert
(
sizeof
(
Base
) ==
QT_POINTER_SIZE
);
139
140
inline
141
void
Base
::
mark
(
QV4
::
MarkStack
*
markStack
)
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
();
147
Q_ASSERT
(!
Chunk
::
testBit
(
c
->
extendsBitmap
,
index
));
148
quintptr
*
bitmap
=
c
->
blackBitmap
+
Chunk
::
bitmapIndex
(
index
);
149
quintptr
bit
=
Chunk
::
bitForIndex
(
index
);
150
if
(!(*
bitmap
&
bit
)) {
151
*
bitmap
|=
bit
;
152
markStack
->
push
(
this
);
153
}
154
}
155
156
template
<
typename
T, size_t o>
157
Base
*
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
166
template
<
class
T
>
167
struct
QV4QPointer
{
168
};
169
#
else
170
template
<
class
T>
171
struct
QV4QPointer
{
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
(
)
; }
201
QV4QPointer
&
operator
=(T *o)
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
219
private
:
220
QtSharedPointer::ExternalRefCountData *d;
221
T *qObject;
222
};
223
static_assert
(
std
::
is_trivially_copyable_v
<
QV4QPointer
<
QObject
>>);
224
static_assert
(
std
::
is_trivially_default_constructible_v
<
QV4QPointer
<
QObject
>>);
225
#
endif
226
227
}
228
229
QT_END_NAMESPACE
230
231
#
endif
QV4::Heap
Definition
qv4compileddata_p.h:73
QV4::Heap::V4PointerCheck
Pointer< char *, 0 > V4PointerCheck
Definition
qv4heap_p.h:56
QV4
Definition
qjsvalue.h:24
QV4::Heap::Base
Definition
qv4heap_p.h:60
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:157
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:171
QV4::QV4QPointer::init
void init()
Definition
qv4heap_p.h:172
QV4::QV4QPointer::isValid
bool isValid() const noexcept
Definition
qv4heap_p.h:214
QV4::QV4QPointer::destroy
void destroy()
Definition
qv4heap_p.h:188
QV4::QV4QPointer::init
void init(T *o)
Definition
qv4heap_p.h:178
QV4::QV4QPointer::data
T * data() const
Definition
qv4heap_p.h:196
QV4::QV4QPointer::operator->
T * operator->() const
Definition
qv4heap_p.h:200
QV4::QV4QPointer::operator T*
operator T*() const
Definition
qv4heap_p.h:199
QV4::QV4QPointer::isNull
bool isNull() const noexcept
Definition
qv4heap_p.h:209
QV4::QV4QPointer::operator=
QV4QPointer & operator=(T *o)
Definition
qv4heap_p.h:201
qtdeclarative
src
qml
memory
qv4heap_p.h
Generated on
for Qt by
1.16.1