// Copyright 2016 The Chromium 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_

#include "base/bind.h"
#include "base/location.h"
#include "third_party/blink/renderer/platform/bindings/buildflags.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/impl/persistent_node.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"

namespace blink {

template <typename T>
class CrossThreadWeakPersistent;

// Wrapping type to force callers to go through macros that expand or drop
// base::Location. This is needed to avoid adding the strings when not needed.
// The type can be dropped once http://crbug.com/760702 is resolved and
// ENABLE_LOCATION_SOURCE is disabled for release builds.
class PersistentLocation final {
 public:
  PersistentLocation() = default;
  explicit PersistentLocation(const base::Location& location)
      : location_(location) {}
  PersistentLocation(const PersistentLocation& other) = default;

  const base::Location& get() const { return location_; }

 private:
  base::Location location_;
};

#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
#define PERSISTENT_FROM_HERE PersistentLocation(base::Location::Current())
#else  // !RAW_HEAP_SNAPSHOTS
#define PERSISTENT_FROM_HERE PersistentLocation()
#endif  // !RAW_HEAP_SNAPSHOTS

template <typename T,
          WeaknessPersistentConfiguration weaknessConfiguration,
          CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
class PersistentBase {
  USING_FAST_MALLOC(PersistentBase);

 public:
  bool IsHashTableDeletedValue() const {
    return raw_ == reinterpret_cast<T*>(-1);
  }

  T* Release() {
    T* result = raw_;
    AssignSafe(nullptr);
    return result;
  }

  void Clear() {
    // Note that this also frees up related data in the backend.
    AssignSafe(nullptr);
  }

  T* Get() const {
    CheckPointer();
    return raw_;
  }

  explicit operator bool() const { return Get(); }
  T& operator*() const { return *Get(); }
  operator T*() const { return Get(); }
  T* operator->() const { return Get(); }

  NO_SANITIZE_ADDRESS
  void ClearWithLockHeld() {
    static_assert(
        crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
        "This Persistent does not require the cross-thread lock.");
    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
    raw_ = nullptr;
    persistent_node_.ClearWithLockHeld();
  }

  void UpdateLocation(const PersistentLocation& other) {
#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
    location_ = other;
#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
  }

 protected:
  ~PersistentBase() {
    UninitializeSafe();
    // Not resetting raw_ as it is not observable.
  }

  PersistentBase() : raw_(nullptr) {
    SaveCreationThreadHeap();
    // No initialization needed for empty handle.
  }
  PersistentBase(const PersistentLocation& location) : PersistentBase() {
    UpdateLocation(location);
  }

  PersistentBase(std::nullptr_t) : raw_(nullptr) {
    SaveCreationThreadHeap();
    // No initialization needed for empty handle.
  }
  PersistentBase(const PersistentLocation& location, std::nullptr_t)
      : PersistentBase(nullptr) {
    UpdateLocation(location);
  }

  PersistentBase(T* raw) : raw_(raw) {
    SaveCreationThreadHeap();
    InitializeSafe();
    CheckPointer();
  }
  PersistentBase(const PersistentLocation& location, T* raw)
      : PersistentBase(raw) {
    UpdateLocation(location);
  }

  PersistentBase(T& raw) : raw_(&raw) {
    SaveCreationThreadHeap();
    InitializeSafe();
    CheckPointer();
  }
  PersistentBase(const PersistentLocation& location, T& raw)
      : PersistentBase(raw) {
    UpdateLocation(location);
  }

  PersistentBase(const PersistentBase& other) : raw_(other) {
    SaveCreationThreadHeap();
    InitializeSafe();
    CheckPointer();
  }
  PersistentBase(const PersistentLocation& location, PersistentBase& other)
      : PersistentBase(other) {
    UpdateLocation(location);
  }

  template <typename U>
  PersistentBase(const PersistentBase<U,
                                      weaknessConfiguration,
                                      crossThreadnessConfiguration>& other)
      : raw_(other) {
    SaveCreationThreadHeap();
    InitializeSafe();
    CheckPointer();
  }
  template <typename U>
  PersistentBase(const PersistentLocation& location,
                 const PersistentBase<U,
                                      weaknessConfiguration,
                                      crossThreadnessConfiguration>& other)
      : PersistentBase(other) {
    UpdateLocation(location);
  }

  template <typename U>
  PersistentBase(const Member<U>& other) : raw_(other) {
    SaveCreationThreadHeap();
    InitializeSafe();
    CheckPointer();
  }
  template <typename U>
  PersistentBase(const PersistentLocation& location, const Member<U>& other)
      : PersistentBase(other) {
    UpdateLocation(location);
  }

  PersistentBase(WTF::HashTableDeletedValueType)
      : raw_(reinterpret_cast<T*>(-1)) {
    SaveCreationThreadHeap();
    // No initialization needed for empty handle.
  }
  PersistentBase(const PersistentLocation& location,
                 WTF::HashTableDeletedValueType)
      : PersistentBase(WTF::kHashTableDeletedValue) {
    UpdateLocation(location);
  }

  template <typename U>
  PersistentBase& operator=(U* other) {
    AssignSafe(other);
    return *this;
  }

  PersistentBase& operator=(std::nullptr_t) {
    AssignSafe(nullptr);
    return *this;
  }

  template <typename U>
  PersistentBase& operator=(const Member<U>& other) {
    AssignSafe(other);
    return *this;
  }

  // Using unsafe operations and assuming that caller acquires the lock for
  // kCrossThreadPersistentConfiguration configuration.
  PersistentBase& operator=(const PersistentBase& other) {
    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
    AssignUnsafe(other);
    return *this;
  }

  // Using unsafe operations and assuming that caller acquires the lock for
  // kCrossThreadPersistentConfiguration configuration.
  template <typename U>
  PersistentBase& operator=(
      const PersistentBase<U,
                           weaknessConfiguration,
                           crossThreadnessConfiguration>& other) {
    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
    AssignUnsafe(static_cast<T*>(other.Get()));
    return *this;
  }

  // Using unsafe operations and assuming that caller acquires the lock for
  // kCrossThreadPersistentConfiguration configuration.
  template <typename U>
  PersistentBase& operator=(
      PersistentBase<U, weaknessConfiguration, crossThreadnessConfiguration>&&
          other) {
    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
    if (persistent_node_.IsInitialized()) {
      // Drop persistent node if present as it's always possible to reuse the
      // node (if present) from |other|.
      persistent_node_.Uninitialize();
    }
    // Explicit cast enabling downcasting.
    raw_ = static_cast<T*>(other.raw_);
    other.raw_ = nullptr;
    // Efficiently move by just rewiring the node pointer.
    persistent_node_ = std::move(other.persistent_node_);
    DCHECK(!other.persistent_node_.Get());
    if (persistent_node_.IsInitialized()) {
      // If |raw_| points to a non-null or deleted value, just reuse the node.
      TraceCallback trace_callback =
          TraceMethodDelegate<PersistentBase,
                              &PersistentBase::TracePersistent>::Trampoline;
      persistent_node_.Get()->Reinitialize(this, trace_callback);
    }
    CheckPointer();
    return *this;
  }

  NO_SANITIZE_ADDRESS
  bool IsNotNull() const { return raw_; }

  NO_SANITIZE_ADDRESS
  void AssignSafe(T* ptr) {
    typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
    AssignUnsafe(ptr);
  }

  NO_SANITIZE_ADDRESS
  void AssignUnsafe(T* ptr) {
    raw_ = ptr;
    CheckPointer();
    if (raw_ && !IsHashTableDeletedValue()) {
      if (!persistent_node_.IsInitialized())
        InitializeUnsafe();
      return;
    }
    UninitializeUnsafe();
  }

  void TracePersistent(Visitor* visitor) const {
    static_assert(sizeof(T), "T must be fully defined");
    static_assert(IsGarbageCollectedType<T>::value,
                  "T needs to be a garbage collected object");
    DCHECK(!IsHashTableDeletedValue());
    if (weaknessConfiguration == kWeakPersistentConfiguration) {
      visitor->RegisterWeakCallback(HandleWeakPersistent, this);
    } else {
#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
      visitor->TraceRoot(raw_, location_.get());
#else
      visitor->TraceRoot(raw_, base::Location());
#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
    }
  }

  NO_SANITIZE_ADDRESS
  void InitializeSafe() {
    DCHECK(!persistent_node_.IsInitialized());
    if (!raw_ || IsHashTableDeletedValue())
      return;

    TraceCallback trace_callback =
        TraceMethodDelegate<PersistentBase,
                            &PersistentBase::TracePersistent>::Trampoline;
    typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
    persistent_node_.Initialize(this, trace_callback);
  }

  NO_SANITIZE_ADDRESS
  void InitializeUnsafe() {
    DCHECK(!persistent_node_.IsInitialized());
    if (!raw_ || IsHashTableDeletedValue())
      return;

    TraceCallback trace_callback =
        TraceMethodDelegate<PersistentBase,
                            &PersistentBase::TracePersistent>::Trampoline;
    persistent_node_.Initialize(this, trace_callback);
  }

  void UninitializeSafe() {
    if (persistent_node_.IsInitialized()) {
      typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
      persistent_node_.Uninitialize();
    }
  }

  void UninitializeUnsafe() {
    if (persistent_node_.IsInitialized())
      persistent_node_.Uninitialize();
  }

  void CheckPointer() const {
#if DCHECK_IS_ON()
    if (!raw_ || IsHashTableDeletedValue())
      return;

    if (crossThreadnessConfiguration != kCrossThreadPersistentConfiguration) {
      ThreadState* current = ThreadState::Current();
      DCHECK(current);
      // m_creationThreadState may be null when this is used in a heap
      // collection which initialized the Persistent with memset and the
      // constructor wasn't called.
      if (creation_thread_state_) {
        // Member should point to objects that belong in the same ThreadHeap.
        DCHECK_EQ(&ThreadState::FromObject(raw_)->Heap(),
                  &creation_thread_state_->Heap());
        // Member should point to objects that belong in the same ThreadHeap.
        DCHECK_EQ(&current->Heap(), &creation_thread_state_->Heap());
      }
    }
#endif
  }

  void SaveCreationThreadHeap() {
#if DCHECK_IS_ON()
    if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) {
      creation_thread_state_ = nullptr;
    } else {
      creation_thread_state_ = ThreadState::Current();
      DCHECK(creation_thread_state_);
    }
#endif
  }

  static void HandleWeakPersistent(const LivenessBroker& broker,
                                   const void* persistent_pointer) {
    using Base =
        PersistentBase<typename std::remove_const<T>::type,
                       weaknessConfiguration, crossThreadnessConfiguration>;
    Base* persistent =
        reinterpret_cast<Base*>(const_cast<void*>(persistent_pointer));
    T* object = persistent->Get();
    if (object && !broker.IsHeapObjectAlive(object))
      ClearWeakPersistent(persistent);
  }

  static void ClearWeakPersistent(
      PersistentBase<std::remove_const_t<T>,
                     kWeakPersistentConfiguration,
                     kCrossThreadPersistentConfiguration>* persistent) {
    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
    persistent->ClearWithLockHeld();
  }

  static void ClearWeakPersistent(
      PersistentBase<std::remove_const_t<T>,
                     kWeakPersistentConfiguration,
                     kSingleThreadPersistentConfiguration>* persistent) {
    persistent->Clear();
  }

  template <typename BadPersistent>
  static void ClearWeakPersistent(BadPersistent* non_weak_persistent) {
    NOTREACHED();
  }

  // raw_ is accessed most, so put it at the first field.
  T* raw_;

  // The pointer to the underlying persistent node.
  //
  // Since accesses are atomics in the cross-thread case, a different type is
  // needed to prevent the compiler producing an error when it encounters
  // operations that are legal on raw pointers but not on atomics, or
  // vice-versa.
  std::conditional_t<
      crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
      CrossThreadPersistentNodePtr<weaknessConfiguration>,
      PersistentNodePtr<ThreadingTrait<T>::kAffinity, weaknessConfiguration>>
      persistent_node_;

#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
  PersistentLocation location_;
#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)

#if DCHECK_IS_ON()
  const ThreadState* creation_thread_state_;
#endif

  template <typename F,
            WeaknessPersistentConfiguration,
            CrossThreadnessPersistentConfiguration>
  friend class PersistentBase;
};

// 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.
//
// We have to construct and destruct Persistent in the same thread.
template <typename T>
class Persistent : public PersistentBase<T,
                                         kNonWeakPersistentConfiguration,
                                         kSingleThreadPersistentConfiguration> {
  using Parent = PersistentBase<T,
                                kNonWeakPersistentConfiguration,
                                kSingleThreadPersistentConfiguration>;

 public:
  Persistent() : Parent() {}
  Persistent(const PersistentLocation& location) : Parent(location) {}
  Persistent(std::nullptr_t) : Parent(nullptr) {}
  Persistent(const PersistentLocation& location, std::nullptr_t)
      : Parent(location, nullptr) {}
  Persistent(T* raw) : Parent(raw) {}
  Persistent(const PersistentLocation& location, T* raw)
      : Parent(location, raw) {}
  Persistent(T& raw) : Parent(raw) {}
  Persistent(const PersistentLocation& location, T& raw)
      : Parent(location, raw) {}
  Persistent(const Persistent& other) : Parent(other) {}
  Persistent(const PersistentLocation& location, const Persistent& other)
      : Parent(location, other) {}
  template <typename U>
  Persistent(const Persistent<U>& other) : Parent(other) {}
  template <typename U>
  Persistent(const PersistentLocation& location, const Persistent<U>& other)
      : Parent(location, other) {}
  template <typename U>
  Persistent(const Member<U>& other) : Parent(other) {}
  template <typename U>
  Persistent(const PersistentLocation& location, const Member<U>& other)
      : Parent(location, other) {}
  Persistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
  Persistent(const PersistentLocation& location,
             WTF::HashTableDeletedValueType x)
      : Parent(location, x) {}

  template <typename U>
  Persistent& operator=(U* other) {
    Parent::operator=(other);
    return *this;
  }

  Persistent& operator=(std::nullptr_t) {
    Parent::operator=(nullptr);
    return *this;
  }

  Persistent& operator=(const Persistent& other) {
    Parent::operator=(other);
    return *this;
  }

  template <typename U>
  Persistent& operator=(const Persistent<U>& other) {
    Parent::operator=(other);
    return *this;
  }

  template <typename U>
  Persistent& operator=(const Member<U>& other) {
    Parent::operator=(other);
    return *this;
  }
};

// WeakPersistent is a way to create a weak pointer from an off-heap object
// to an on-heap object. The m_raw is automatically cleared when the pointee
// gets collected.
//
// We have to construct and destruct WeakPersistent in the same thread.
//
// Note that collections of WeakPersistents are not supported. Use a collection
// of WeakMembers instead.
//
//   HashSet<WeakPersistent<T>> m_set; // wrong
//   Persistent<HeapHashSet<WeakMember<T>>> m_set; // correct
template <typename T>
class WeakPersistent
    : public PersistentBase<T,
                            kWeakPersistentConfiguration,
                            kSingleThreadPersistentConfiguration> {
  using Parent = PersistentBase<T,
                                kWeakPersistentConfiguration,
                                kSingleThreadPersistentConfiguration>;

 public:
  WeakPersistent() : Parent() {}
  WeakPersistent(std::nullptr_t) : Parent(nullptr) {}
  WeakPersistent(T* raw) : Parent(raw) {}
  WeakPersistent(T& raw) : Parent(raw) {}
  WeakPersistent(const WeakPersistent& other) : Parent(other) {}
  template <typename U>
  WeakPersistent(const WeakPersistent<U>& other) : Parent(other) {}
  template <typename U>
  WeakPersistent(const Member<U>& other) : Parent(other) {}

  template <typename U>
  WeakPersistent& operator=(U* other) {
    Parent::operator=(other);
    return *this;
  }

  WeakPersistent& operator=(std::nullptr_t) {
    Parent::operator=(nullptr);
    return *this;
  }

  WeakPersistent& operator=(const WeakPersistent& other) {
    Parent::operator=(other);
    return *this;
  }

  template <typename U>
  WeakPersistent& operator=(const WeakPersistent<U>& other) {
    Parent::operator=(other);
    return *this;
  }

  template <typename U>
  WeakPersistent& operator=(const Member<U>& other) {
    Parent::operator=(other);
    return *this;
  }
};

// CrossThreadPersistent allows for holding onto an object strongly on a
// different thread.
//
// Thread-safe operations:
// - Construction
// - Destruction
// - Copy and move construction and assignment
// - Clearing
// - Deref if treated as immutable reference or if externally synchronized (e.g.
//   mutex, task). The current implementation of Get() uses a raw load (on
//   purpose) which prohibits mutation while accessing the reference on a
//   different thread.
template <typename T>
class CrossThreadPersistent
    : public PersistentBase<T,
                            kNonWeakPersistentConfiguration,
                            kCrossThreadPersistentConfiguration> {
  using Parent = PersistentBase<T,
                                kNonWeakPersistentConfiguration,
                                kCrossThreadPersistentConfiguration>;

 public:
  CrossThreadPersistent() : Parent() {}
  CrossThreadPersistent(const PersistentLocation& location)
      : Parent(location) {}
  CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) {}
  CrossThreadPersistent(const PersistentLocation& location, std::nullptr_t)
      : Parent(location, nullptr) {}
  explicit CrossThreadPersistent(T* raw) : Parent(raw) {}
  CrossThreadPersistent(const PersistentLocation& location, T* raw)
      : Parent(location, raw) {}
  explicit CrossThreadPersistent(T& raw) : Parent(raw) {}
  CrossThreadPersistent(const PersistentLocation& location, T& raw)
      : Parent(location, raw) {}
  CrossThreadPersistent(const CrossThreadPersistent& other) { *this = other; }
  CrossThreadPersistent(const PersistentLocation& location,
                        const CrossThreadPersistent& other) {
    *this = other;
  }
  template <typename U>
  CrossThreadPersistent(const CrossThreadPersistent<U>& other) {
    *this = other;
  }
  template <typename U>
  CrossThreadPersistent(const PersistentLocation& location,
                        const CrossThreadPersistent<U>& other) {
    *this = other;
  }
  template <typename U>
  CrossThreadPersistent(const Member<U>& other) : Parent(other) {}
  template <typename U>
  CrossThreadPersistent(const PersistentLocation& location,
                        const Member<U>& other)
      : Parent(location, other) {}
  CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
  CrossThreadPersistent(const PersistentLocation& location,
                        WTF::HashTableDeletedValueType x)
      : Parent(location, x) {}
  template <typename U>
  CrossThreadPersistent(const CrossThreadWeakPersistent<U>& other) {
    *this = other;
  }

  // Instead of using release(), assign then clear() instead.
  // Using release() with per thread heap enabled can cause the object to be
  // destroyed before assigning it to a new handle.
  T* Release() = delete;

  template <typename U>
  CrossThreadPersistent& operator=(U* other) {
    Parent::operator=(other);
    return *this;
  }

  CrossThreadPersistent& operator=(std::nullptr_t) {
    Parent::operator=(nullptr);
    return *this;
  }

  CrossThreadPersistent& operator=(const CrossThreadPersistent& other) {
    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
    Parent::operator=(other);
    return *this;
  }

  template <typename U>
  CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other) {
    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
    Parent::operator=(other);
    return *this;
  }

  template <typename U>
  CrossThreadPersistent& operator=(const CrossThreadWeakPersistent<U>&);
};

// CrossThreadWeakPersistent combines behavior of CrossThreadPersistent and
// WeakPersistent, i.e., it allows holding onto an object weakly on a different
// thread.
//
// Thread-safe operations:
// - Construction
// - Destruction
// - Copy and move construction and assignment
// - Clearing
//
// Note that this does not include dereferencing and using the raw pointer as
// there is no guarantee that the object will be alive at the time it is used.
template <typename T>
class CrossThreadWeakPersistent
    : public PersistentBase<T,
                            kWeakPersistentConfiguration,
                            kCrossThreadPersistentConfiguration> {
  using Parent = PersistentBase<T,
                                kWeakPersistentConfiguration,
                                kCrossThreadPersistentConfiguration>;

 public:
  CrossThreadWeakPersistent() : Parent() {}
  explicit CrossThreadWeakPersistent(T* raw) : Parent(raw) {}
  explicit CrossThreadWeakPersistent(T& raw) : Parent(raw) {}
  CrossThreadWeakPersistent(const CrossThreadWeakPersistent& other) {
    *this = other;
  }
  template <typename U>
  CrossThreadWeakPersistent(const CrossThreadWeakPersistent<U>& other) {
    *this = other;
  }
  CrossThreadWeakPersistent(CrossThreadWeakPersistent&& other) {
    *this = std::move(other);
  }
  template <typename U>
  CrossThreadWeakPersistent(CrossThreadWeakPersistent<U>&& other) {
    *this = std::move(other);
  }

  CrossThreadWeakPersistent& operator=(const CrossThreadWeakPersistent& other) {
    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
    Parent::operator=(other);
    return *this;
  }

  template <typename U>
  CrossThreadWeakPersistent& operator=(
      const CrossThreadWeakPersistent<U>& other) {
    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
    Parent::operator=(other);
    return *this;
  }

  CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent&& other) {
    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
    Parent::operator=(std::move(other));
    return *this;
  }

  template <typename U>
  CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent<U>&& other) {
    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
    Parent::operator=(std::move(other));
    return *this;
  }

  template <typename U>
  CrossThreadWeakPersistent& operator=(U* other) {
    Parent::operator=(other);
    return *this;
  }

  // Create a CrossThreadPersistent that keeps the underlying object alive if
  // there is still on set. Can be used to work with an object on a different
  // thread than it was allocated. Note that CTP does not block threads from
  // terminating, in which case the reference would still be invalid.
  const CrossThreadPersistent<T> Lock() const {
    return CrossThreadPersistent<T>(*this);
  }

  // Disallow directly using CrossThreadWeakPersistent. Users must go through
  // CrossThreadPersistent to access the pointee. Note that this does not
  // guarantee that the object is still alive at that point. Users must check
  // the state of CTP manually before invoking any calls.
  T* operator->() const = delete;
  T& operator*() const = delete;
  operator T*() const = delete;
  T* Get() const = delete;

 private:
  template <typename U>
  friend class CrossThreadPersistent;
};

template <typename T>
template <typename U>
CrossThreadPersistent<T>& CrossThreadPersistent<T>::operator=(
    const CrossThreadWeakPersistent<U>& other) {
  MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
  using ParentU = PersistentBase<U, kWeakPersistentConfiguration,
                                 kCrossThreadPersistentConfiguration>;
  this->AssignUnsafe(static_cast<const ParentU&>(other).Get());
  return *this;
}

template <typename T>
Persistent<T> WrapPersistentInternal(const PersistentLocation& location,
                                     T* value) {
  return Persistent<T>(location, value);
}

template <typename T>
Persistent<T> WrapPersistentInternal(T* value) {
  return Persistent<T>(value);
}

#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
#define WrapPersistent(value) \
  WrapPersistentInternal(PERSISTENT_FROM_HERE, value)
#else
#define WrapPersistent(value) WrapPersistentInternal(value)
#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)

template <typename T>
WeakPersistent<T> WrapWeakPersistent(T* value) {
  return WeakPersistent<T>(value);
}

template <typename T>
CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(
    const PersistentLocation& location,
    T* value) {
  return CrossThreadPersistent<T>(location, value);
}

template <typename T>
CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(T* value) {
  return CrossThreadPersistent<T>(value);
}

#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
#define WrapCrossThreadPersistent(value) \
  WrapCrossThreadPersistentInternal(PERSISTENT_FROM_HERE, value)
#else
#define WrapCrossThreadPersistent(value) \
  WrapCrossThreadPersistentInternal(value)
#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)

template <typename T>
CrossThreadWeakPersistent<T> WrapCrossThreadWeakPersistent(T* value) {
  return CrossThreadWeakPersistent<T>(value);
}

// Comparison operators between (Weak)Members, Persistents, and UntracedMembers.
template <typename T, typename U>
inline bool operator==(const Member<T>& a, const Member<U>& b) {
  return a.Get() == b.Get();
}
template <typename T, typename U>
inline bool operator!=(const Member<T>& a, const Member<U>& b) {
  return a.Get() != b.Get();
}
template <typename T, typename U>
inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) {
  return a.Get() == b.Get();
}
template <typename T, typename U>
inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) {
  return a.Get() != b.Get();
}

template <typename T, typename U>
inline bool operator==(const Member<T>& a, const Persistent<U>& b) {
  return a.Get() == b.Get();
}
template <typename T, typename U>
inline bool operator!=(const Member<T>& a, const Persistent<U>& b) {
  return a.Get() != b.Get();
}
template <typename T, typename U>
inline bool operator==(const Persistent<T>& a, const Member<U>& b) {
  return a.Get() == b.Get();
}
template <typename T, typename U>
inline bool operator!=(const Persistent<T>& a, const Member<U>& b) {
  return a.Get() != b.Get();
}

template <typename U, typename T>
Persistent<U> DownCast(const Persistent<T>& p) {
  return Persistent<U>(p);
}

template <typename U, typename T>
WeakPersistent<U> DownCast(const WeakPersistent<T>& p) {
  return WeakPersistent<U>(p);
}

template <typename U, typename T>
CrossThreadPersistent<U> DownCast(const CrossThreadPersistent<T>& p) {
  return CrossThreadPersistent<U>(p);
}

template <typename U, typename T>
CrossThreadWeakPersistent<U> DownCast(const CrossThreadWeakPersistent<T>& p) {
  return CrossThreadWeakPersistent<U>(p);
}

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_
