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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtdeclarative/src/qml/memory/qv4writebarrier_p.h