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
qv4writebarrier_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 QV4WRITEBARRIER_P_H
5#define QV4WRITEBARRIER_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/qv4enginebase_p.h>
20
21QT_BEGIN_NAMESPACE
22
23namespace QV4 {
24struct EngineBase;
25typedef quint64 ReturnedValue;
26
28
29 static constexpr bool isInsertionBarrier = true;
30
31 Q_ALWAYS_INLINE static void write(EngineBase *engine, Heap::Base *base, ReturnedValue *slot, ReturnedValue value)
32 {
33 if (engine->isGCOngoing)
34 write_slowpath(engine, base, slot, value);
35 *slot = value;
36 }
37 Q_QML_EXPORT Q_NEVER_INLINE static void write_slowpath(
40
41 Q_ALWAYS_INLINE static void write(EngineBase *engine, Heap::Base *base, Heap::Base **slot, Heap::Base *value)
42 {
43 if (engine->isGCOngoing)
44 write_slowpath(engine, base, slot, value);
45 *slot = value;
46 }
49 Heap::Base **slot, Heap::Base *value);
50
51 // MemoryManager isn't a complete type here, so make Engine a template argument
52 // so that we can still call engine->memoryManager->markStack()
53 template<typename F, typename Engine = EngineBase>
54 static void markCustom(Engine *engine, F &&markFunction) {
55 if (engine->isGCOngoing)
56 (std::forward<F>(markFunction))(engine->memoryManager->markStack());
57 }
58
59 // HeapObjectWrapper(Base) are helper classes to ensure that
60 // we always use a WriteBarrier when setting heap-objects
61 // they are also trivial; if triviality is not required, use Pointer instead
63 {
64 // enum class avoids accidental construction via brace-init
65 enum class PointerWrapper : quintptr {};
67
68 void clear() { wrapped = PointerWrapper(quintptr(0)); }
69 };
70
71 template<typename HeapType>
73 {
74 HeapType *get() const { return reinterpret_cast<HeapType *>(wrapped); }
75 operator HeapType *() const { return get(); }
76 HeapType * operator->() const { return get(); }
77
78 template <typename ConvertibleToHeapType>
79 void set(QV4::EngineBase *engine, ConvertibleToHeapType *heapObject)
80 {
81 WriteBarrier::markCustom(engine, [heapObject](QV4::MarkStack *ms){
82 if (heapObject)
83 heapObject->mark(ms);
84 });
85 wrapped = static_cast<HeapObjectWrapperBase::PointerWrapper>(quintptr(heapObject));
86 }
87 };
88
89 // all types are trivial; we however want to block copies bypassing the write barrier
90 // therefore, all members use a PhantomTag to reduce the likelihood
91 template<typename HeapType, int PhantomTag>
93
94 /* similar Heap::Pointer, but without the Base conversion (and its inUse assert)
95 and for storing references in engine classes stored on the native heap
96 Stores a "non-owning" reference to a heap-item (in the C++ sense), but should
97 generally mark the heap-item; therefore set goes through a write-barrier
98 */
99 template<typename T>
100 struct Pointer
101 {
102 Pointer() = default;
103 ~Pointer() = default;
105 T* operator->() const { return get(); }
106 operator T* () const { return get(); }
107
110 if (newVal)
111 newVal->mark(ms);
112 });
113 ptr = newVal;
114 }
115
116 T* get() const { return ptr; }
117
118
119
120 private:
121 T *ptr = nullptr;
122 };
123};
124
125 // ### this needs to be filled with a real memory fence once marking is concurrent
127
128}
129
130QT_END_NAMESPACE
131
132#endif
Definition qjsvalue.h:24
Q_ALWAYS_INLINE void fence()
void set(QV4::EngineBase *engine, ConvertibleToHeapType *heapObject)
static Q_ALWAYS_INLINE void write(EngineBase *engine, Heap::Base *base, Heap::Base **slot, Heap::Base *value)
static void markCustom(Engine *engine, F &&markFunction)
static constexpr bool isInsertionBarrier
static Q_ALWAYS_INLINE void write(EngineBase *engine, Heap::Base *base, ReturnedValue *slot, ReturnedValue value)