Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/include/cppgc/visitor.h')
-rw-r--r--deps/v8/include/cppgc/visitor.h138
1 files changed, 138 insertions, 0 deletions
diff --git a/deps/v8/include/cppgc/visitor.h b/deps/v8/include/cppgc/visitor.h
new file mode 100644
index 00000000000..a73a4abb2bd
--- /dev/null
+++ b/deps/v8/include/cppgc/visitor.h
@@ -0,0 +1,138 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef INCLUDE_CPPGC_VISITOR_H_
+#define INCLUDE_CPPGC_VISITOR_H_
+
+#include "cppgc/garbage-collected.h"
+#include "cppgc/internal/logging.h"
+#include "cppgc/internal/pointer-policies.h"
+#include "cppgc/liveness-broker.h"
+#include "cppgc/member.h"
+#include "cppgc/source-location.h"
+#include "cppgc/trace-trait.h"
+
+namespace cppgc {
+namespace internal {
+class VisitorBase;
+} // namespace internal
+
+using WeakCallback = void (*)(const LivenessBroker&, const void*);
+
+/**
+ * Visitor passed to trace methods. All managed pointers must have called the
+ * visitor's trace method on them.
+ */
+class Visitor {
+ public:
+ template <typename T>
+ void Trace(const Member<T>& member) {
+ const T* value = member.GetRawAtomic();
+ CPPGC_DCHECK(value != kSentinelPointer);
+ Trace(value);
+ }
+
+ template <typename T>
+ void Trace(const WeakMember<T>& weak_member) {
+ static_assert(sizeof(T), "T must be fully defined");
+ static_assert(internal::IsGarbageCollectedType<T>::value,
+ "T must be GarabgeCollected or GarbageCollectedMixin type");
+
+ const T* value = weak_member.GetRawAtomic();
+
+ // Bailout assumes that WeakMember emits write barrier.
+ if (!value) {
+ return;
+ }
+
+ // TODO(chromium:1056170): DCHECK (or similar) for deleted values as they
+ // should come in at a different path.
+ VisitWeak(value, TraceTrait<T>::GetTraceDescriptor(value),
+ &HandleWeak<WeakMember<T>>, &weak_member);
+ }
+
+ template <typename Persistent,
+ std::enable_if_t<Persistent::IsStrongPersistent::value>* = nullptr>
+ void TraceRoot(const Persistent& p, const SourceLocation& loc) {
+ using PointeeType = typename Persistent::PointeeType;
+ static_assert(sizeof(PointeeType),
+ "Persistent's pointee type must be fully defined");
+ static_assert(internal::IsGarbageCollectedType<PointeeType>::value,
+ "Persisent's pointee type must be GarabgeCollected or "
+ "GarbageCollectedMixin");
+ if (!p.Get()) {
+ return;
+ }
+ VisitRoot(p.Get(), TraceTrait<PointeeType>::GetTraceDescriptor(p.Get()));
+ }
+
+ template <
+ typename WeakPersistent,
+ std::enable_if_t<!WeakPersistent::IsStrongPersistent::value>* = nullptr>
+ void TraceRoot(const WeakPersistent& p, const SourceLocation& loc) {
+ using PointeeType = typename WeakPersistent::PointeeType;
+ static_assert(sizeof(PointeeType),
+ "Persistent's pointee type must be fully defined");
+ static_assert(internal::IsGarbageCollectedType<PointeeType>::value,
+ "Persisent's pointee type must be GarabgeCollected or "
+ "GarbageCollectedMixin");
+ VisitWeakRoot(p.Get(), TraceTrait<PointeeType>::GetTraceDescriptor(p.Get()),
+ &HandleWeak<WeakPersistent>, &p);
+ }
+
+ template <typename T, void (T::*method)(const LivenessBroker&)>
+ void RegisterWeakCallbackMethod(const T* obj) {
+ RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>, obj);
+ }
+
+ virtual void RegisterWeakCallback(WeakCallback, const void*) {}
+
+ protected:
+ virtual void Visit(const void* self, TraceDescriptor) {}
+ virtual void VisitWeak(const void* self, TraceDescriptor, WeakCallback,
+ const void* weak_member) {}
+ virtual void VisitRoot(const void*, TraceDescriptor) {}
+ virtual void VisitWeakRoot(const void* self, TraceDescriptor, WeakCallback,
+ const void* weak_root) {}
+
+ private:
+ template <typename T, void (T::*method)(const LivenessBroker&)>
+ static void WeakCallbackMethodDelegate(const LivenessBroker& info,
+ const void* self) {
+ // Callback is registered through a potential const Trace method but needs
+ // to be able to modify fields. See HandleWeak.
+ (const_cast<T*>(static_cast<const T*>(self))->*method)(info);
+ }
+
+ template <typename PointerType>
+ static void HandleWeak(const LivenessBroker& info, const void* object) {
+ const PointerType* weak = static_cast<const PointerType*>(object);
+ const auto* raw = weak->Get();
+ if (raw && !info.IsHeapObjectAlive(raw)) {
+ // Object is passed down through the marker as const. Alternatives are
+ // - non-const Trace method;
+ // - mutable pointer in MemberBase;
+ const_cast<PointerType*>(weak)->Clear();
+ }
+ }
+
+ Visitor() = default;
+
+ template <typename T>
+ void Trace(const T* t) {
+ static_assert(sizeof(T), "T must be fully defined");
+ static_assert(internal::IsGarbageCollectedType<T>::value,
+ "T must be GarabgeCollected or GarbageCollectedMixin type");
+ if (!t) {
+ return;
+ }
+ Visit(t, TraceTrait<T>::GetTraceDescriptor(t));
+ }
+
+ friend class internal::VisitorBase;
+};
+
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_VISITOR_H_