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/persistent.h')
-rw-r--r--deps/v8/include/cppgc/persistent.h304
1 files changed, 304 insertions, 0 deletions
diff --git a/deps/v8/include/cppgc/persistent.h b/deps/v8/include/cppgc/persistent.h
new file mode 100644
index 00000000000..fc6b0b9d92e
--- /dev/null
+++ b/deps/v8/include/cppgc/persistent.h
@@ -0,0 +1,304 @@
+// 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_PERSISTENT_H_
+#define INCLUDE_CPPGC_PERSISTENT_H_
+
+#include <type_traits>
+
+#include "cppgc/internal/persistent-node.h"
+#include "cppgc/internal/pointer-policies.h"
+#include "cppgc/source-location.h"
+#include "cppgc/type-traits.h"
+#include "cppgc/visitor.h"
+#include "v8config.h" // NOLINT(build/include_directory)
+
+namespace cppgc {
+namespace internal {
+
+// The basic class from which all Persistent classes are generated.
+template <typename T, typename WeaknessPolicy, typename LocationPolicy,
+ typename CheckingPolicy>
+class BasicPersistent : public LocationPolicy,
+ private WeaknessPolicy,
+ private CheckingPolicy {
+ public:
+ using typename WeaknessPolicy::IsStrongPersistent;
+ using PointeeType = T;
+
+ // Null-state/sentinel constructors.
+ BasicPersistent( // NOLINT
+ const SourceLocation& loc = SourceLocation::Current())
+ : LocationPolicy(loc) {}
+
+ BasicPersistent(std::nullptr_t, // NOLINT
+ const SourceLocation& loc = SourceLocation::Current())
+ : LocationPolicy(loc) {}
+
+ BasicPersistent( // NOLINT
+ SentinelPointer s, const SourceLocation& loc = SourceLocation::Current())
+ : LocationPolicy(loc), raw_(s) {}
+
+ // Raw value contstructors.
+ BasicPersistent(T* raw, // NOLINT
+ const SourceLocation& loc = SourceLocation::Current())
+ : LocationPolicy(loc), raw_(raw) {
+ if (!IsValid()) return;
+ node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode(
+ this, &BasicPersistent::Trace);
+ this->CheckPointer(Get());
+ }
+
+ BasicPersistent(T& raw, // NOLINT
+ const SourceLocation& loc = SourceLocation::Current())
+ : BasicPersistent(&raw, loc) {}
+
+ // Copy ctor.
+ BasicPersistent(const BasicPersistent& other,
+ const SourceLocation& loc = SourceLocation::Current())
+ : BasicPersistent(other.Get(), loc) {}
+
+ // Heterogeneous ctor.
+ template <typename U, typename OtherWeaknessPolicy,
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
+ BasicPersistent( // NOLINT
+ const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
+ OtherCheckingPolicy>& other,
+ const SourceLocation& loc = SourceLocation::Current())
+ : BasicPersistent(other.Get(), loc) {}
+
+ // Move ctor. The heterogeneous move ctor is not supported since e.g.
+ // persistent can't reuse persistent node from weak persistent.
+ BasicPersistent(
+ BasicPersistent&& other,
+ const SourceLocation& loc = SourceLocation::Current()) noexcept
+ : LocationPolicy(std::move(other)),
+ raw_(std::move(other.raw_)),
+ node_(std::move(other.node_)) {
+ if (!IsValid()) return;
+ node_->UpdateOwner(this);
+ other.raw_ = nullptr;
+ other.node_ = nullptr;
+ this->CheckPointer(Get());
+ }
+
+ // Constructor from member.
+ template <typename U, typename MemberBarrierPolicy,
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
+ BasicPersistent(internal::BasicMember<U, MemberBarrierPolicy, // NOLINT
+ MemberWeaknessTag, MemberCheckingPolicy>
+ member,
+ const SourceLocation& loc = SourceLocation::Current())
+ : BasicPersistent(member.Get(), loc) {}
+
+ ~BasicPersistent() { Clear(); }
+
+ // Copy assignment.
+ BasicPersistent& operator=(const BasicPersistent& other) {
+ return operator=(other.Get());
+ }
+
+ template <typename U, typename OtherWeaknessPolicy,
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
+ BasicPersistent& operator=(
+ const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
+ OtherCheckingPolicy>& other) {
+ return operator=(other.Get());
+ }
+
+ // Move assignment.
+ BasicPersistent& operator=(BasicPersistent&& other) {
+ if (this == &other) return *this;
+ Clear();
+ LocationPolicy::operator=(std::move(other));
+ raw_ = std::move(other.raw_);
+ node_ = std::move(other.node_);
+ if (!IsValid()) return *this;
+ node_->UpdateOwner(this);
+ other.raw_ = nullptr;
+ other.node_ = nullptr;
+ this->CheckPointer(Get());
+ return *this;
+ }
+
+ // Assignment from member.
+ template <typename U, typename MemberBarrierPolicy,
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
+ BasicPersistent& operator=(
+ internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
+ MemberCheckingPolicy>
+ member) {
+ return operator=(member.Get());
+ }
+
+ BasicPersistent& operator=(T* other) {
+ Assign(other);
+ return *this;
+ }
+
+ BasicPersistent& operator=(std::nullptr_t) {
+ Clear();
+ return *this;
+ }
+
+ BasicPersistent& operator=(SentinelPointer s) {
+ Assign(s);
+ return *this;
+ }
+
+ explicit operator bool() const { return Get(); }
+ operator T*() const { return Get(); }
+ T* operator->() const { return Get(); }
+ T& operator*() const { return *Get(); }
+
+ T* Get() const { return raw_; }
+
+ void Clear() { Assign(nullptr); }
+
+ T* Release() {
+ T* result = Get();
+ Clear();
+ return result;
+ }
+
+ private:
+ static void Trace(Visitor* v, const void* ptr) {
+ const auto* persistent = static_cast<const BasicPersistent*>(ptr);
+ v->TraceRoot(*persistent, persistent->Location());
+ }
+
+ bool IsValid() const {
+ // Ideally, handling kSentinelPointer would be done by the embedder. On the
+ // other hand, having Persistent aware of it is beneficial since no node
+ // gets wasted.
+ return raw_ != nullptr && raw_ != kSentinelPointer;
+ }
+
+ void Assign(T* ptr) {
+ if (IsValid()) {
+ if (ptr && ptr != kSentinelPointer) {
+ // Simply assign the pointer reusing the existing node.
+ raw_ = ptr;
+ this->CheckPointer(ptr);
+ return;
+ }
+ WeaknessPolicy::GetPersistentRegion(raw_).FreeNode(node_);
+ node_ = nullptr;
+ }
+ raw_ = ptr;
+ if (!IsValid()) return;
+ node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode(
+ this, &BasicPersistent::Trace);
+ this->CheckPointer(Get());
+ }
+
+ T* raw_ = nullptr;
+ PersistentNode* node_ = nullptr;
+};
+
+template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
+ typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
+ typename LocationPolicy2, typename CheckingPolicy2>
+bool operator==(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
+ CheckingPolicy1>& p1,
+ const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
+ CheckingPolicy2>& p2) {
+ return p1.Get() == p2.Get();
+}
+
+template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
+ typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
+ typename LocationPolicy2, typename CheckingPolicy2>
+bool operator!=(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
+ CheckingPolicy1>& p1,
+ const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
+ CheckingPolicy2>& p2) {
+ return !(p1 == p2);
+}
+
+template <typename T1, typename PersistentWeaknessPolicy,
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
+ typename T2, typename MemberWriteBarrierPolicy,
+ typename MemberWeaknessTag, typename MemberCheckingPolicy>
+bool operator==(const BasicPersistent<T1, PersistentWeaknessPolicy,
+ PersistentLocationPolicy,
+ PersistentCheckingPolicy>& p,
+ BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
+ MemberCheckingPolicy>
+ m) {
+ return p.Get() == m.Get();
+}
+
+template <typename T1, typename PersistentWeaknessPolicy,
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
+ typename T2, typename MemberWriteBarrierPolicy,
+ typename MemberWeaknessTag, typename MemberCheckingPolicy>
+bool operator!=(const BasicPersistent<T1, PersistentWeaknessPolicy,
+ PersistentLocationPolicy,
+ PersistentCheckingPolicy>& p,
+ BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
+ MemberCheckingPolicy>
+ m) {
+ return !(p == m);
+}
+
+template <typename T1, typename MemberWriteBarrierPolicy,
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
+ typename T2, typename PersistentWeaknessPolicy,
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
+bool operator==(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
+ MemberCheckingPolicy>
+ m,
+ const BasicPersistent<T1, PersistentWeaknessPolicy,
+ PersistentLocationPolicy,
+ PersistentCheckingPolicy>& p) {
+ return m.Get() == p.Get();
+}
+
+template <typename T1, typename MemberWriteBarrierPolicy,
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
+ typename T2, typename PersistentWeaknessPolicy,
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
+bool operator!=(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
+ MemberCheckingPolicy>
+ m,
+ const BasicPersistent<T1, PersistentWeaknessPolicy,
+ PersistentLocationPolicy,
+ PersistentCheckingPolicy>& p) {
+ return !(m == p);
+}
+
+template <typename T, typename LocationPolicy, typename CheckingPolicy>
+struct IsWeak<BasicPersistent<T, internal::WeakPersistentPolicy, LocationPolicy,
+ CheckingPolicy>> : std::true_type {};
+} // namespace internal
+
+/**
+ * Persistent is a way to create a strong pointer from an off-heap object to
+ * another on-heap object. As long as the Persistent handle is alive the GC will
+ * keep the object pointed to alive. The Persistent handle is always a GC root
+ * from the point of view of the GC. Persistent must be constructed and
+ * destructed in the same thread.
+ */
+template <typename T>
+using Persistent =
+ internal::BasicPersistent<T, internal::StrongPersistentPolicy>;
+
+/**
+ * WeakPersistent is a way to create a weak pointer from an off-heap object to
+ * an on-heap object. The pointer is automatically cleared when the pointee gets
+ * collected. WeakPersistent must be constructed and destructed in the same
+ * thread.
+ */
+template <typename T>
+using WeakPersistent =
+ internal::BasicPersistent<T, internal::WeakPersistentPolicy>;
+
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_PERSISTENT_H_