diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2023-11-21 19:36:26 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2023-12-20 08:38:26 +0100 |
commit | b9d37a328ba09bcb2a7a95b5778cb8c63d0ace26 (patch) | |
tree | 340739253c3e15f0b6c051434d94061e8e3385c6 /src/qml/memory/qv4writebarrier_p.h | |
parent | d08ede57dd530a67c3420b3858fe39bf1e5eb598 (diff) |
Long live incremental garbage collection in QML!
The design of the garbage collector is described in
src/qml/memory/design.md.
The gc and gcdone test helpers are adjusted to drive the gc to
completion, even when in incremental mode.
Parts of tst_qv4mm and tst_qqmlqt need to run with the incremental gc
disabled, as they call gc inside QML and assumes that the GC finishes
before returning.
Initial-patch-by: Rafal Chomentowski <rafal.chomentowski@ge.com>
Task-number: QTBUG-119274
Change-Id: I1d94f41bc7a434fad67de0fd46454b6db285f2eb
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/memory/qv4writebarrier_p.h')
-rw-r--r-- | src/qml/memory/qv4writebarrier_p.h | 77 |
1 files changed, 35 insertions, 42 deletions
diff --git a/src/qml/memory/qv4writebarrier_p.h b/src/qml/memory/qv4writebarrier_p.h index 813d360841..9b26766ee5 100644 --- a/src/qml/memory/qv4writebarrier_p.h +++ b/src/qml/memory/qv4writebarrier_p.h @@ -15,57 +15,50 @@ // #include <private/qv4global_p.h> +#include <private/qv4enginebase_p.h> QT_BEGIN_NAMESPACE -#define WRITEBARRIER_none 1 - -#define WRITEBARRIER(x) (1/WRITEBARRIER_##x == 1) - namespace QV4 { struct EngineBase; - -namespace WriteBarrier { - -enum Type { - NoBarrier, - Barrier +typedef quint64 ReturnedValue; + +struct WriteBarrier { + + static constexpr bool isInsertionBarrier = true; + + Q_ALWAYS_INLINE static void write(EngineBase *engine, Heap::Base *base, ReturnedValue *slot, ReturnedValue value) + { + if (engine->isGCOngoing) + write_slowpath(engine, base, slot, value); + *slot = value; + } + Q_QML_EXPORT Q_NEVER_INLINE static void write_slowpath( + EngineBase *engine, Heap::Base *base, + ReturnedValue *slot, ReturnedValue value); + + Q_ALWAYS_INLINE static void write(EngineBase *engine, Heap::Base *base, Heap::Base **slot, Heap::Base *value) + { + if (engine->isGCOngoing) + write_slowpath(engine, base, slot, value); + *slot = value; + } + Q_QML_EXPORT Q_NEVER_INLINE static void write_slowpath( + EngineBase *engine, Heap::Base *base, + Heap::Base **slot, Heap::Base *value); + + // MemoryManager isn't a complete type here, so make Engine a template argument + // so that we can still call engine->memoryManager->markStack() + template<typename F, typename Engine = EngineBase> + static void markCustom(Engine *engine, F &&markFunction) { + if (engine->isGCOngoing) + (std::forward<F>(markFunction))(engine->memoryManager->markStack()); + } }; -enum NewValueType { - Primitive, - Object, - Unknown -}; - -// ### this needs to be filled with a real memory fence once marking is concurrent + // ### this needs to be filled with a real memory fence once marking is concurrent Q_ALWAYS_INLINE void fence() {} -#if WRITEBARRIER(none) - -template <NewValueType type> -static constexpr inline bool isRequired() { - return false; -} - -inline void write(EngineBase *engine, Heap::Base *base, ReturnedValue *slot, ReturnedValue value) -{ - Q_UNUSED(engine); - Q_UNUSED(base); - *slot = value; -} - -inline void write(EngineBase *engine, Heap::Base *base, Heap::Base **slot, Heap::Base *value) -{ - Q_UNUSED(engine); - Q_UNUSED(base); - *slot = value; -} - -#endif - -} - } QT_END_NAMESPACE |