// 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_PERSISTENT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_

#include "base/bind.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/persistent_node.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/atomics.h"

namespace blink {

// Marker used to annotate persistent objects and collections with,
// so as to enable reliable testing for persistent references via
// a type trait (see TypeTraits.h's IsPersistentReferenceType<>.)
#define IS_PERSISTENT_REFERENCE_TYPE()         \
 public:                                       \
  using IsPersistentReferenceTypeMarker = int; \
                                               \
 private:

enum WeaknessPersistentConfiguration {
  kNonWeakPersistentConfiguration,
  kWeakPersistentConfiguration
};

enum CrossThreadnessPersistentConfiguration {
  kSingleThreadPersistentConfiguration,
  kCrossThreadPersistentConfiguration
};

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

 public:
  PersistentBase() : raw_(nullptr) {
    SaveCreationThreadHeap();
    Initialize();
  }

  PersistentBase(std::nullptr_t) : raw_(nullptr) {
    SaveCreationThreadHeap();
    Initialize();
  }

  PersistentBase(T* raw) : raw_(raw) {
    SaveCreationThreadHeap();
    Initialize();
    CheckPointer();
  }

  PersistentBase(T& raw) : raw_(&raw) {
    SaveCreationThreadHeap();
    Initialize();
    CheckPointer();
  }

  PersistentBase(const PersistentBase& other) : raw_(other) {
    SaveCreationThreadHeap();
    Initialize();
    CheckPointer();
  }

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

  template <typename U>
  PersistentBase(const Member<U>& other) : raw_(other) {
    SaveCreationThreadHeap();
    Initialize();
    CheckPointer();
  }

  PersistentBase(WTF::HashTableDeletedValueType)
      : raw_(reinterpret_cast<T*>(-1)) {
    SaveCreationThreadHeap();
    Initialize();
    CheckPointer();
  }

  ~PersistentBase() {
    Uninitialize();
    raw_ = nullptr;
  }

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

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

  void Clear() { Assign(nullptr); }
  T& operator*() const {
    CheckPointer();
    return *raw_;
  }
  explicit operator bool() const { return raw_; }
  operator T*() const {
    CheckPointer();
    return raw_;
  }
  T* operator->() const { return *this; }

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

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

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

  PersistentBase& operator=(const PersistentBase& other) {
    Assign(other);
    return *this;
  }

  template <typename U>
  PersistentBase& operator=(
      const PersistentBase<U,
                           weaknessConfiguration,
                           crossThreadnessConfiguration>& other) {
    Assign(other);
    return *this;
  }

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

  // Register the persistent node as a 'static reference',
  // belonging to the current thread and a persistent that must
  // be cleared when the ThreadState itself is cleared out and
  // destructed.
  //
  // Static singletons arrange for this to happen, either to ensure
  // clean LSan leak reports or to register a thread-local persistent
  // needing to be cleared out before the thread is terminated.
  PersistentBase* RegisterAsStaticReference() {
    CHECK_EQ(weaknessConfiguration, kNonWeakPersistentConfiguration);
    if (persistent_node_) {
      DCHECK(ThreadState::Current());
      ThreadState::Current()->RegisterStaticPersistentNode(persistent_node_,
                                                           nullptr);
      LEAK_SANITIZER_IGNORE_OBJECT(this);
    }
    return this;
  }

  NO_SANITIZE_ADDRESS
  void ClearWithLockHeld() {
    static_assert(
        crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
        "This Persistent does not require the cross-thread lock.");
#if DCHECK_IS_ON()
    DCHECK(ProcessHeap::CrossThreadPersistentMutex().Locked());
#endif
    raw_ = nullptr;
    CrossThreadPersistentRegion& region =
        weaknessConfiguration == kWeakPersistentConfiguration
            ? ProcessHeap::GetCrossThreadWeakPersistentRegion()
            : ProcessHeap::GetCrossThreadPersistentRegion();
    region.FreePersistentNode(persistent_node_);
  }

 protected:
  NO_SANITIZE_ADDRESS
  T* AtomicGet() {
    return reinterpret_cast<T*>(AcquireLoad(reinterpret_cast<void* volatile*>(
        const_cast<typename std::remove_const<T>::type**>(&raw_))));
  }

 private:
  NO_SANITIZE_ADDRESS
  void Assign(T* ptr) {
    if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) {
      MutexLocker persistent_lock(ProcessHeap::CrossThreadPersistentMutex());
      raw_ = ptr;
    } else {
      raw_ = ptr;
    }
    CheckPointer();
    if (raw_) {
      if (!persistent_node_)
        Initialize();
      return;
    }
    Uninitialize();
  }

  template <typename VisitorDispatcher>
  void TracePersistent(VisitorDispatcher visitor) {
    static_assert(sizeof(T), "T must be fully defined");
    static_assert(IsGarbageCollectedType<T>::value,
                  "T needs to be a garbage collected object");
    if (weaknessConfiguration == kWeakPersistentConfiguration) {
      visitor->RegisterWeakCallback(this, HandleWeakPersistent);
    } else {
      visitor->Trace(raw_);
    }
  }

  NO_SANITIZE_ADDRESS
  void Initialize() {
    DCHECK(!persistent_node_);
    if (!raw_ || IsHashTableDeletedValue())
      return;

    TraceCallback trace_callback =
        TraceMethodDelegate<PersistentBase,
                            &PersistentBase::TracePersistent>::Trampoline;
    if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) {
      CrossThreadPersistentRegion& region =
          weaknessConfiguration == kWeakPersistentConfiguration
              ? ProcessHeap::GetCrossThreadWeakPersistentRegion()
              : ProcessHeap::GetCrossThreadPersistentRegion();
      MutexLocker lock(ProcessHeap::CrossThreadPersistentMutex());
      region.AllocatePersistentNode(persistent_node_, this, trace_callback);
      return;
    }
    ThreadState* state =
        ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
    DCHECK(state->CheckThread());
    PersistentRegion* region =
        weaknessConfiguration == kWeakPersistentConfiguration
            ? state->GetWeakPersistentRegion()
            : state->GetPersistentRegion();
    persistent_node_ = region->AllocatePersistentNode(this, trace_callback);
#if DCHECK_IS_ON()
    state_ = state;
#endif
  }

  void Uninitialize() {
    if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) {
      if (AcquireLoad(reinterpret_cast<void* volatile*>(&persistent_node_))) {
        CrossThreadPersistentRegion& region =
            weaknessConfiguration == kWeakPersistentConfiguration
                ? ProcessHeap::GetCrossThreadWeakPersistentRegion()
                : ProcessHeap::GetCrossThreadPersistentRegion();
        MutexLocker lock(ProcessHeap::CrossThreadPersistentMutex());
        region.FreePersistentNode(persistent_node_);
      }
      return;
    }

    if (!persistent_node_)
      return;
    ThreadState* state =
        ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
    DCHECK(state->CheckThread());
    // Persistent handle must be created and destructed in the same thread.
#if DCHECK_IS_ON()
    DCHECK_EQ(state_, state);
#endif
    PersistentRegion* region =
        weaknessConfiguration == kWeakPersistentConfiguration
            ? state->GetWeakPersistentRegion()
            : state->GetPersistentRegion();
    state->FreePersistentNode(region, persistent_node_);
    persistent_node_ = nullptr;
  }

  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(Visitor* self, void* persistent_pointer) {
    using Base =
        PersistentBase<typename std::remove_const<T>::type,
                       weaknessConfiguration, crossThreadnessConfiguration>;
    Base* persistent = reinterpret_cast<Base*>(persistent_pointer);
    T* object = persistent->Get();
    if (object && !ObjectAliveTrait<T>::IsHeapObjectAlive(object))
      ClearWeakPersistent(persistent);
  }

  static void ClearWeakPersistent(
      PersistentBase<std::remove_const_t<T>,
                     kWeakPersistentConfiguration,
                     kCrossThreadPersistentConfiguration>* persistent) {
#if DCHECK_IS_ON()
    DCHECK(ProcessHeap::CrossThreadPersistentMutex().Locked());
#endif
    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();
  }

  // m_raw is accessed most, so put it at the first field.
  T* raw_;
  PersistentNode* persistent_node_ = nullptr;
#if DCHECK_IS_ON()
  ThreadState* state_ = nullptr;
  const ThreadState* creation_thread_state_;
#endif
};

// 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> {
  typedef PersistentBase<T,
                         kNonWeakPersistentConfiguration,
                         kSingleThreadPersistentConfiguration>
      Parent;

 public:
  Persistent() : Parent() {}
  Persistent(std::nullptr_t) : Parent(nullptr) {}
  Persistent(T* raw) : Parent(raw) {}
  Persistent(T& raw) : Parent(raw) {}
  Persistent(const Persistent& other) : Parent(other) {}
  template <typename U>
  Persistent(const Persistent<U>& other) : Parent(other) {}
  template <typename U>
  Persistent(const Member<U>& other) : Parent(other) {}
  Persistent(WTF::HashTableDeletedValueType x) : Parent(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 persistent
// collection of WeakMembers instead.
//
//   HashSet<WeakPersistent<T>> m_set; // wrong
//   PersistentHeapHashSet<WeakMember<T>> m_set; // correct
template <typename T>
class WeakPersistent
    : public PersistentBase<T,
                            kWeakPersistentConfiguration,
                            kSingleThreadPersistentConfiguration> {
  typedef PersistentBase<T,
                         kWeakPersistentConfiguration,
                         kSingleThreadPersistentConfiguration>
      Parent;

 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;
  }
};

// Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
// different from the construction thread.
template <typename T>
class CrossThreadPersistent
    : public PersistentBase<T,
                            kNonWeakPersistentConfiguration,
                            kCrossThreadPersistentConfiguration> {
  typedef PersistentBase<T,
                         kNonWeakPersistentConfiguration,
                         kCrossThreadPersistentConfiguration>
      Parent;

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

  T* AtomicGet() { return Parent::AtomicGet(); }

  // 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) {
    Parent::operator=(other);
    return *this;
  }

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

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

// Combines the behavior of CrossThreadPersistent and WeakPersistent.
template <typename T>
class CrossThreadWeakPersistent
    : public PersistentBase<T,
                            kWeakPersistentConfiguration,
                            kCrossThreadPersistentConfiguration> {
  typedef PersistentBase<T,
                         kWeakPersistentConfiguration,
                         kCrossThreadPersistentConfiguration>
      Parent;

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

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

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

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

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

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

template <typename Collection>
class PersistentHeapCollectionBase : public Collection {
  // We overload the various new and delete operators with using the WTF
  // PartitionAllocator to ensure persistent heap collections are always
  // allocated off-heap. This allows persistent collections to be used in
  // DEFINE_STATIC_LOCAL et. al.
  USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::PartitionAllocator);
  IS_PERSISTENT_REFERENCE_TYPE();

 public:
  PersistentHeapCollectionBase() { Initialize(); }

  PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other)
      : Collection(other) {
    Initialize();
  }

  template <typename OtherCollection>
  PersistentHeapCollectionBase(const OtherCollection& other)
      : Collection(other) {
    Initialize();
  }

  ~PersistentHeapCollectionBase() { Uninitialize(); }

  // Override so we don't copy persistent_node_.
  PersistentHeapCollectionBase& operator=(
      const PersistentHeapCollectionBase& other) {
    Collection::operator=(other);
    return *this;
  }

  // See PersistentBase::registerAsStaticReference() comment.
  PersistentHeapCollectionBase* RegisterAsStaticReference() {
    if (persistent_node_) {
      DCHECK(ThreadState::Current());
      ThreadState::Current()->RegisterStaticPersistentNode(
          persistent_node_,
          &PersistentHeapCollectionBase<Collection>::ClearPersistentNode);
      LEAK_SANITIZER_IGNORE_OBJECT(this);
    }
    return this;
  }

 private:
  template <typename VisitorDispatcher>
  void TracePersistent(VisitorDispatcher visitor) {
    static_assert(sizeof(Collection), "Collection must be fully defined");
    visitor->Trace(*static_cast<Collection*>(this));
  }

  // Used when the registered PersistentNode of this object is
  // released during ThreadState shutdown, clearing the association.
  static void ClearPersistentNode(void* self) {
    PersistentHeapCollectionBase<Collection>* collection =
        (reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self));
    collection->Uninitialize();
    collection->clear();
  }

  NO_SANITIZE_ADDRESS
  void Initialize() {
    CHECK(IsMainThread()) << "Persistent heap collections are disabled on "
                             "non-main threads. Put the heap collection in a "
                             "Persistent instead.";
    // FIXME: Derive affinity based on the collection.
    ThreadState* state = ThreadState::Current();
    DCHECK(state->CheckThread());
    persistent_node_ = state->GetPersistentRegion()->AllocatePersistentNode(
        this,
        TraceMethodDelegate<PersistentHeapCollectionBase<Collection>,
                            &PersistentHeapCollectionBase<
                                Collection>::TracePersistent>::Trampoline);
#if DCHECK_IS_ON()
    state_ = state;
#endif
  }

  void Uninitialize() {
    if (!persistent_node_)
      return;
    ThreadState* state = ThreadState::Current();
    DCHECK(state->CheckThread());
    // Persistent handle must be created and destructed in the same thread.
#if DCHECK_IS_ON()
    DCHECK_EQ(state_, state);
#endif
    state->FreePersistentNode(state->GetPersistentRegion(), persistent_node_);
    persistent_node_ = nullptr;
  }

  PersistentNode* persistent_node_;
#if DCHECK_IS_ON()
  ThreadState* state_;
#endif
};

template <typename KeyArg,
          typename MappedArg,
          typename HashArg = typename DefaultHash<KeyArg>::Hash,
          typename KeyTraitsArg = HashTraits<KeyArg>,
          typename MappedTraitsArg = HashTraits<MappedArg>>
class PersistentHeapHashMap
    : public PersistentHeapCollectionBase<HeapHashMap<KeyArg,
                                                      MappedArg,
                                                      HashArg,
                                                      KeyTraitsArg,
                                                      MappedTraitsArg>> {};

template <typename ValueArg,
          typename HashArg = typename DefaultHash<ValueArg>::Hash,
          typename TraitsArg = HashTraits<ValueArg>>
class PersistentHeapHashSet : public PersistentHeapCollectionBase<
                                  HeapHashSet<ValueArg, HashArg, TraitsArg>> {};

template <typename ValueArg,
          typename HashArg = typename DefaultHash<ValueArg>::Hash,
          typename TraitsArg = HashTraits<ValueArg>>
class PersistentHeapLinkedHashSet
    : public PersistentHeapCollectionBase<
          HeapLinkedHashSet<ValueArg, HashArg, TraitsArg>> {};

template <typename ValueArg,
          size_t inlineCapacity = 0,
          typename HashArg = typename DefaultHash<ValueArg>::Hash>
class PersistentHeapListHashSet
    : public PersistentHeapCollectionBase<
          HeapListHashSet<ValueArg, inlineCapacity, HashArg>> {};

template <typename ValueArg,
          typename HashFunctions = typename DefaultHash<ValueArg>::Hash,
          typename Traits = HashTraits<ValueArg>>
class PersistentHeapHashCountedSet
    : public PersistentHeapCollectionBase<
          HeapHashCountedSet<ValueArg, HashFunctions, Traits>> {};

template <typename T, size_t inlineCapacity = 0>
class PersistentHeapVector
    : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity>> {
 public:
  PersistentHeapVector() { InitializeUnusedSlots(); }

  explicit PersistentHeapVector(size_t size)
      : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity>>(size) {
    InitializeUnusedSlots();
  }

  PersistentHeapVector(const PersistentHeapVector& other)
      : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity>>(other) {
    InitializeUnusedSlots();
  }

  template <size_t otherCapacity>
  PersistentHeapVector(const HeapVector<T, otherCapacity>& other)
      : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity>>(other) {
    InitializeUnusedSlots();
  }

 private:
  void InitializeUnusedSlots() {
    // The PersistentHeapVector is allocated off heap along with its
    // inline buffer (if any.) Maintain the invariant that unused
    // slots are cleared for the off-heap inline buffer also.
    size_t unused_slots = this->capacity() - this->size();
    if (unused_slots)
      this->ClearUnusedSlots(this->end(), this->end() + unused_slots);
  }
};

template <typename T, size_t inlineCapacity = 0>
class PersistentHeapDeque
    : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>> {
 public:
  PersistentHeapDeque() = default;

  template <size_t otherCapacity>
  PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other)
      : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) {}
};

template <typename T>
Persistent<T> WrapPersistent(T* value) {
  // There is no technical need to require a complete type here. However, types
  // that support wrapper-tracing are not suitable with WrapPersistent because
  // Persistent<T> does not perform wrapper-tracing. We'd like to delete such
  // overloads for sure. Thus, we require a complete type here so that it makes
  // sure that an appropriate header is included and such an overload is
  // deleted.
  static_assert(sizeof(T), "T must be fully defined");

  return Persistent<T>(value);
}

template <typename T,
          typename = std::enable_if_t<WTF::IsGarbageCollectedType<T>::value>>
Persistent<T> WrapPersistentIfNeeded(T* value) {
  return Persistent<T>(value);
}

template <typename T>
T& WrapPersistentIfNeeded(T& value) {
  return value;
}

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

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

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();
}

}  // namespace blink

namespace WTF {

template <typename T>
struct DefaultHash<blink::Persistent<T>> {
  STATIC_ONLY(DefaultHash);
  using Hash = MemberHash<T>;
};

template <typename T>
struct DefaultHash<blink::WeakPersistent<T>> {
  STATIC_ONLY(DefaultHash);
  using Hash = MemberHash<T>;
};

template <typename T>
struct DefaultHash<blink::CrossThreadPersistent<T>> {
  STATIC_ONLY(DefaultHash);
  using Hash = MemberHash<T>;
};

template <typename T>
struct DefaultHash<blink::CrossThreadWeakPersistent<T>> {
  STATIC_ONLY(DefaultHash);
  using Hash = MemberHash<T>;
};

}  // namespace WTF

namespace base {

template <typename T>
struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {};

template <typename T>
struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {};

template <typename T>
struct BindUnwrapTraits<blink::CrossThreadWeakPersistent<T>> {
  static blink::CrossThreadPersistent<T> Unwrap(
      const blink::CrossThreadWeakPersistent<T>& wrapped) {
    return blink::CrossThreadPersistent<T>(wrapped.Get());
  }
};
}

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
