// Copyright 2015 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 PersistentNode_h
#define PersistentNode_h

#include "platform/PlatformExport.h"
#include "platform/heap/ThreadState.h"
#include "wtf/Allocator.h"
#include "wtf/Assertions.h"
#include "wtf/PtrUtil.h"
#include "wtf/ThreadingPrimitives.h"
#include <memory>

namespace blink {

class CrossThreadPersistentRegion;

class PersistentNode final {
  DISALLOW_NEW();

 public:
  PersistentNode() : m_self(nullptr), m_trace(nullptr) { ASSERT(isUnused()); }

#if ENABLE(ASSERT)
  ~PersistentNode() {
    // If you hit this assert, it means that the thread finished
    // without clearing persistent handles that the thread created.
    // We don't enable the assert for the main thread because the
    // main thread finishes without clearing all persistent handles.
    ASSERT(isMainThread() || isUnused());
  }
#endif

  // It is dangerous to copy the PersistentNode because it breaks the
  // free list.
  PersistentNode& operator=(const PersistentNode& otherref) = delete;

  // Ideally the trace method should be virtual and automatically dispatch
  // to the most specific implementation. However having a virtual method
  // on PersistentNode leads to too eager template instantiation with MSVC
  // which leads to include cycles.
  // Instead we call the constructor with a TraceCallback which knows the
  // type of the most specific child and calls trace directly. See
  // TraceMethodDelegate in Visitor.h for how this is done.
  void tracePersistentNode(Visitor* visitor) {
    ASSERT(!isUnused());
    ASSERT(m_trace);
    m_trace(visitor, m_self);
  }

  void initialize(void* self, TraceCallback trace) {
    ASSERT(isUnused());
    m_self = self;
    m_trace = trace;
  }

  void setFreeListNext(PersistentNode* node) {
    ASSERT(!node || node->isUnused());
    m_self = node;
    m_trace = nullptr;
    ASSERT(isUnused());
  }

  PersistentNode* freeListNext() {
    ASSERT(isUnused());
    PersistentNode* node = reinterpret_cast<PersistentNode*>(m_self);
    ASSERT(!node || node->isUnused());
    return node;
  }

  bool isUnused() const { return !m_trace; }

  void* self() const { return m_self; }

 private:
  // If this PersistentNode is in use:
  //   - m_self points to the corresponding Persistent handle.
  //   - m_trace points to the trace method.
  // If this PersistentNode is freed:
  //   - m_self points to the next freed PersistentNode.
  //   - m_trace is nullptr.
  void* m_self;
  TraceCallback m_trace;
};

struct PersistentNodeSlots final {
  USING_FAST_MALLOC(PersistentNodeSlots);

 private:
  static const int slotCount = 256;
  PersistentNodeSlots* m_next;
  PersistentNode m_slot[slotCount];
  friend class PersistentRegion;
  friend class CrossThreadPersistentRegion;
};

// PersistentRegion provides a region of PersistentNodes. PersistentRegion
// holds a linked list of PersistentNodeSlots, each of which stores
// a predefined number of PersistentNodes. You can call allocatePersistentNode/
// freePersistentNode to allocate/free a PersistentNode on the region.
class PLATFORM_EXPORT PersistentRegion final {
  USING_FAST_MALLOC(PersistentRegion);

 public:
  PersistentRegion()
      : m_freeListHead(nullptr),
        m_slots(nullptr)
#if ENABLE(ASSERT)
        ,
        m_persistentCount(0)
#endif
  {
  }
  ~PersistentRegion();

  PersistentNode* allocatePersistentNode(void* self, TraceCallback trace) {
#if ENABLE(ASSERT)
    ++m_persistentCount;
#endif
    if (UNLIKELY(!m_freeListHead))
      ensurePersistentNodeSlots(self, trace);
    ASSERT(m_freeListHead);
    PersistentNode* node = m_freeListHead;
    m_freeListHead = m_freeListHead->freeListNext();
    node->initialize(self, trace);
    ASSERT(!node->isUnused());
    return node;
  }

  void freePersistentNode(PersistentNode* persistentNode) {
    ASSERT(m_persistentCount > 0);
    persistentNode->setFreeListNext(m_freeListHead);
    m_freeListHead = persistentNode;
#if ENABLE(ASSERT)
    --m_persistentCount;
#endif
  }

  static bool shouldTracePersistentNode(Visitor*, PersistentNode*) {
    return true;
  }

  void releasePersistentNode(PersistentNode*,
                             ThreadState::PersistentClearCallback);
  using ShouldTraceCallback = bool (*)(Visitor*, PersistentNode*);
  void tracePersistentNodes(
      Visitor*,
      ShouldTraceCallback = PersistentRegion::shouldTracePersistentNode);
  int numberOfPersistents();

 private:
  friend CrossThreadPersistentRegion;

  void ensurePersistentNodeSlots(void*, TraceCallback);

  PersistentNode* m_freeListHead;
  PersistentNodeSlots* m_slots;
#if ENABLE(ASSERT)
  int m_persistentCount;
#endif
};

class CrossThreadPersistentRegion final {
  USING_FAST_MALLOC(CrossThreadPersistentRegion);

 public:
  CrossThreadPersistentRegion()
      : m_persistentRegion(wrapUnique(new PersistentRegion)) {}

  void allocatePersistentNode(PersistentNode*& persistentNode,
                              void* self,
                              TraceCallback trace) {
    MutexLocker lock(m_mutex);
    PersistentNode* node =
        m_persistentRegion->allocatePersistentNode(self, trace);
    releaseStore(reinterpret_cast<void* volatile*>(&persistentNode), node);
  }

  void freePersistentNode(PersistentNode*& persistentNode) {
    MutexLocker lock(m_mutex);
    // When the thread that holds the heap object that the cross-thread
    // persistent shuts down, prepareForThreadStateTermination() will clear out
    // the associated CrossThreadPersistent<> and PersistentNode so as to avoid
    // unsafe access. This can overlap with a holder of the
    // CrossThreadPersistent<> also clearing the persistent and freeing the
    // PersistentNode.
    //
    // The lock ensures the updating is ordered, but by the time lock has been
    // acquired the PersistentNode reference may have been cleared out already;
    // check for this.
    if (!persistentNode)
      return;
    m_persistentRegion->freePersistentNode(persistentNode);
    releaseStore(reinterpret_cast<void* volatile*>(&persistentNode), nullptr);
  }

  class LockScope final {
    STACK_ALLOCATED();

   public:
    LockScope(CrossThreadPersistentRegion& persistentRegion)
        : m_persistentRegion(persistentRegion) {
      m_persistentRegion.lock();
    }
    ~LockScope() { m_persistentRegion.unlock(); }

   private:
    CrossThreadPersistentRegion& m_persistentRegion;
  };

  void tracePersistentNodes(Visitor* visitor) {
// If this assert triggers, you're tracing without being in a LockScope.
#if ENABLE(ASSERT)
    DCHECK(m_mutex.locked());
#endif
    m_persistentRegion->tracePersistentNodes(
        visitor, CrossThreadPersistentRegion::shouldTracePersistentNode);
  }

  void prepareForThreadStateTermination(ThreadState*);

  NO_SANITIZE_ADDRESS
  static bool shouldTracePersistentNode(Visitor*, PersistentNode*);

 private:
  friend class LockScope;

  void lock() { m_mutex.lock(); }

  void unlock() { m_mutex.unlock(); }

  // We don't make CrossThreadPersistentRegion inherit from PersistentRegion
  // because we don't want to virtualize performance-sensitive methods
  // such as PersistentRegion::allocate/freePersistentNode.
  std::unique_ptr<PersistentRegion> m_persistentRegion;

  // Recursive as prepareForThreadStateTermination() clears a PersistentNode's
  // associated Persistent<> -- it in turn freeing the PersistentNode. And both
  // CrossThreadPersistentRegion operations need a lock on the region before
  // mutating.
  RecursiveMutex m_mutex;
};

}  // namespace blink

#endif
