// 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_INTERNAL_PERSISTENT_NODE_H_
#define INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_

#include <array>
#include <memory>
#include <vector>

#include "cppgc/internal/logging.h"
#include "cppgc/trace-trait.h"
#include "v8config.h"  // NOLINT(build/include_directory)

namespace cppgc {

class Visitor;

namespace internal {

// PersistentNode represents a variant of two states:
// 1) traceable node with a back pointer to the Persistent object;
// 2) freelist entry.
class PersistentNode final {
 public:
  PersistentNode() = default;

  PersistentNode(const PersistentNode&) = delete;
  PersistentNode& operator=(const PersistentNode&) = delete;

  void InitializeAsUsedNode(void* owner, TraceCallback trace) {
    owner_ = owner;
    trace_ = trace;
  }

  void InitializeAsFreeNode(PersistentNode* next) {
    next_ = next;
    trace_ = nullptr;
  }

  void UpdateOwner(void* owner) {
    CPPGC_DCHECK(IsUsed());
    owner_ = owner;
  }

  PersistentNode* FreeListNext() const {
    CPPGC_DCHECK(!IsUsed());
    return next_;
  }

  void Trace(Visitor* visitor) const {
    CPPGC_DCHECK(IsUsed());
    trace_(visitor, owner_);
  }

  bool IsUsed() const { return trace_; }

  void* owner() const {
    CPPGC_DCHECK(IsUsed());
    return owner_;
  }

 private:
  // PersistentNode acts as a designated union:
  // If trace_ != nullptr, owner_ points to the corresponding Persistent handle.
  // Otherwise, next_ points to the next freed PersistentNode.
  union {
    void* owner_ = nullptr;
    PersistentNode* next_;
  };
  TraceCallback trace_ = nullptr;
};

class V8_EXPORT PersistentRegion final {
  using PersistentNodeSlots = std::array<PersistentNode, 256u>;

 public:
  PersistentRegion() = default;
  // Clears Persistent fields to avoid stale pointers after heap teardown.
  ~PersistentRegion();

  PersistentRegion(const PersistentRegion&) = delete;
  PersistentRegion& operator=(const PersistentRegion&) = delete;

  PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
    if (!free_list_head_) {
      EnsureNodeSlots();
    }
    PersistentNode* node = free_list_head_;
    free_list_head_ = free_list_head_->FreeListNext();
    node->InitializeAsUsedNode(owner, trace);
    return node;
  }

  void FreeNode(PersistentNode* node) {
    node->InitializeAsFreeNode(free_list_head_);
    free_list_head_ = node;
  }

  void Trace(Visitor*);

  size_t NodesInUse() const;

 private:
  void EnsureNodeSlots();

  std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_;
  PersistentNode* free_list_head_ = nullptr;
};

// CrossThreadPersistent uses PersistentRegion but protects it using this lock
// when needed.
class V8_EXPORT PersistentRegionLock final {
 public:
  PersistentRegionLock();
  ~PersistentRegionLock();
};

}  // namespace internal

}  // namespace cppgc

#endif  // INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
