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
#
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
27
QT_BEGIN_NAMESPACE
28
29
namespace
QV4
{
30
31
namespace
Heap
{
32
33
template
<
typename
T, size_t o>
34
struct
Pointer
{
35
static
constexpr
size_t
offset
= o;
36
T
operator
->()
const
{
return
get
(
)
; }
37
operator
T ()
const
{
return
get
(
)
; }
38
39
Base
*
base
();
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
52
private
:
53
Base *ptr;
54
};
55
typedef
Pointer
<
char
*, 0>
V4PointerCheck
;
56
Q_STATIC_ASSERT
(
std
::
is_trivial_v
<
V4PointerCheck
>);
57
58
struct
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
123
Q_ALWAYS_INLINE
void
_checkIsInitialized
() {}
124
Q_ALWAYS_INLINE
void
_checkIsDestroyed
() {}
125
Q_ALWAYS_INLINE
void
_setInitialized
() {}
126
Q_ALWAYS_INLINE
void
_setDestroyed
() {}
127
#
endif
128
};
129
Q_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.
133
Q_STATIC_ASSERT
(
std
::
is_standard_layout
<
Base
>::
value
);
134
Q_STATIC_ASSERT
(
offsetof
(
Base
,
internalClass
) == 0);
135
Q_STATIC_ASSERT
(
sizeof
(
Base
) ==
QT_POINTER_SIZE
);
136
137
inline
138
void
Base
::
mark
(
QV4
::
MarkStack
*
markStack
)
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
);
146
quintptr
bit
=
Chunk
::
bitForIndex
(
index
);
147
if
(!(*
bitmap
&
bit
)) {
148
*
bitmap
|=
bit
;
149
markStack
->
push
(
this
);
150
}
151
}
152
153
template
<
typename
T, size_t o>
154
Base
*
Pointer
<T, o>::
base
() {
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
163
template
<
class
T
>
164
struct
QV4QPointer
{
165
};
166
#
else
167
template
<
class
T>
168
struct
QV4QPointer
{
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) {
180
d = QtSharedPointer::ExternalRefCountData::getAndRef(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
(
)
; }
198
QV4QPointer
&
operator
=(T *o)
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
216
private
:
217
QtSharedPointer::ExternalRefCountData *d;
218
T *qObject;
219
};
220
Q_STATIC_ASSERT
(
std
::
is_trivial_v
<
QV4QPointer
<
QObject
>>);
221
#
endif
222
223
}
224
225
QT_END_NAMESPACE
226
227
#
endif
QV4::Heap
Definition
qv4compileddata_p.h:72
QV4::Heap::V4PointerCheck
Pointer< char *, 0 > V4PointerCheck
Definition
qv4heap_p.h:55
QV4::Heap::Q_STATIC_ASSERT
Q_STATIC_ASSERT(std::is_trivial_v< ArrayData >)
QV4
Definition
qjsvalue.h:23
QV4::Heap::Base
Definition
qv4heap_p.h:58
QV4::Heap::Pointer
Definition
qv4heap_p.h:34
QV4::Heap::Pointer::heapObject
Base * heapObject() const
Definition
qv4heap_p.h:50
QV4::Heap::Pointer::base
Base * base()
Definition
qv4heap_p.h:154
QV4::Heap::Pointer::cast
Type * cast()
Definition
qv4heap_p.h:48
QV4::Heap::Pointer::set
void set(EngineBase *e, T newVal)
Definition
qv4heap_p.h:41
QV4::Heap::Pointer::operator->
T operator->() const
Definition
qv4heap_p.h:36
QV4::Heap::Pointer::get
T get() const
Definition
qv4heap_p.h:45
QV4::Heap::Pointer::offset
static constexpr size_t offset
Definition
qv4heap_p.h:35
QV4::Heap::Pointer::operator T
operator T() const
Definition
qv4heap_p.h:37
QV4::QV4QPointer
Definition
qv4heap_p.h:168
QV4::QV4QPointer::init
void init()
Definition
qv4heap_p.h:169
QV4::QV4QPointer::isValid
bool isValid() const noexcept
Definition
qv4heap_p.h:211
QV4::QV4QPointer::destroy
void destroy()
Definition
qv4heap_p.h:185
QV4::QV4QPointer::init
void init(T *o)
Definition
qv4heap_p.h:175
QV4::QV4QPointer::data
T * data() const
Definition
qv4heap_p.h:193
QV4::QV4QPointer::operator->
T * operator->() const
Definition
qv4heap_p.h:197
QV4::QV4QPointer::operator T*
operator T*() const
Definition
qv4heap_p.h:196
QV4::QV4QPointer::isNull
bool isNull() const noexcept
Definition
qv4heap_p.h:206
QV4::QV4QPointer::operator=
QV4QPointer & operator=(T *o)
Definition
qv4heap_p.h:198
qtdeclarative
src
qml
memory
qv4heap_p.h
Generated on
for Qt by
1.14.0