// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_CLASS_TABLE_H_
#define RUNTIME_VM_CLASS_TABLE_H_

#include <memory>
#include <tuple>
#include <utility>

#include "platform/allocation.h"
#include "platform/assert.h"
#include "platform/atomic.h"
#include "platform/utils.h"

#include "vm/bitfield.h"
#include "vm/class_id.h"
#include "vm/flags.h"
#include "vm/globals.h"
#include "vm/tagged_pointer.h"

namespace dart {

class Class;
class ClassTable;
class Isolate;
class IsolateGroup;
class JSONArray;
class JSONObject;
class JSONStream;
template <typename T>
class MallocGrowableArray;
class ObjectPointerVisitor;
class PersistentHandle;

// A 64-bit bitmap describing unboxed fields in a class.
//
// There is a bit for each word in an instance of the class.
//
// Words corresponding to set bits must be ignored by the GC because they
// don't contain pointers. All words beyond the first 64 words of an object
// are expected to contain pointers.
class UnboxedFieldBitmap {
 public:
  UnboxedFieldBitmap() : bitmap_(0) {}
  explicit UnboxedFieldBitmap(uint64_t bitmap) : bitmap_(bitmap) {}
  UnboxedFieldBitmap(const UnboxedFieldBitmap&) = default;
  UnboxedFieldBitmap& operator=(const UnboxedFieldBitmap&) = default;

  DART_FORCE_INLINE bool Get(intptr_t position) const {
    if (position >= Length()) return false;
    return Utils::TestBit(bitmap_, position);
  }
  DART_FORCE_INLINE void Set(intptr_t position) {
    ASSERT(position < Length());
    bitmap_ |= Utils::Bit<decltype(bitmap_)>(position);
  }
  DART_FORCE_INLINE void Clear(intptr_t position) {
    ASSERT(position < Length());
    bitmap_ &= ~Utils::Bit<decltype(bitmap_)>(position);
  }
  DART_FORCE_INLINE uint64_t Value() const { return bitmap_; }
  DART_FORCE_INLINE bool IsEmpty() const { return bitmap_ == 0; }
  DART_FORCE_INLINE void Reset() { bitmap_ = 0; }

  DART_FORCE_INLINE static constexpr intptr_t Length() {
    return sizeof(decltype(bitmap_)) * kBitsPerByte;
  }

 private:
  uint64_t bitmap_;
};

// Allocator used to manage memory for ClassTable arrays and ClassTable
// objects themselves.
//
// This allocator provides delayed free functionality: normally class tables
// can't be freed unless all mutator and helper threads are stopped because
// some of these threads might be holding a pointer to a table which we
// want to free. Instead of stopping the world whenever we need to free
// a table (e.g. freeing old table after growing) we delay freeing until an
// occasional GC which will need to stop the world anyway.
class ClassTableAllocator : public ValueObject {
 public:
  ClassTableAllocator();
  ~ClassTableAllocator();

  // Allocate an array of T with |len| elements.
  //
  // Does *not* initialize the memory.
  template <class T>
  inline T* Alloc(intptr_t len) {
    return reinterpret_cast<T*>(dart::malloc(len * sizeof(T)));
  }

  // Allocate a zero initialized array of T with |len| elements.
  template <class T>
  inline T* AllocZeroInitialized(intptr_t len) {
    return reinterpret_cast<T*>(dart::calloc(len, sizeof(T)));
  }

  // Clone the given |array| with |size| elements.
  template <class T>
  inline T* Clone(T* array, intptr_t size) {
    if (array == nullptr) {
      ASSERT(size == 0);
      return nullptr;
    }
    auto result = Alloc<T>(size);
    memmove(result, array, size * sizeof(T));
    return result;
  }

  // Copy |size| elements from the given |array| into a new
  // array with space for |new_size| elements. Then |Free|
  // the original |array|.
  //
  // |new_size| is expected to be larger than |size|.
  template <class T>
  inline T* Realloc(T* array, intptr_t size, intptr_t new_size) {
    ASSERT(size < new_size);
    auto result = AllocZeroInitialized<T>(new_size);
    if (size != 0) {
      ASSERT(result != nullptr);
      memmove(result, array, size * sizeof(T));
    }
    Free(array);
    return result;
  }

  // Schedule deletion of the given ClassTable.
  void Free(ClassTable* table);

  // Schedule freeing of the given pointer.
  void Free(void* ptr);

  // Free all objects which were scheduled by |Free|. Expected to only be
  // called on |IsolateGroup| shutdown or when the world is stopped and no
  // thread can be using a stale class table pointer.
  void FreePending();

 private:
  typedef void (*Deleter)(void*);
  MallocGrowableArray<std::pair<void*, Deleter>>* pending_freed_;
};

// A table with the given |Columns| indexed by class id.
//
// Each column is a continuous array of a the given type. All columns have
// the same number of used elements (|num_cids()|) and the same capacity.
template <typename CidType, typename... Columns>
class CidIndexedTable {
 public:
  explicit CidIndexedTable(ClassTableAllocator* allocator)
      : allocator_(allocator) {}

  ~CidIndexedTable() {
    std::apply([&](auto&... column) { (allocator_->Free(column.load()), ...); },
               columns_);
  }

  CidIndexedTable(const CidIndexedTable& other) = delete;

  void SetNumCidsAndCapacity(intptr_t new_num_cids, intptr_t new_capacity) {
    columns_ = std::apply(
        [&](auto&... column) {
          return std::make_tuple(
              allocator_->Realloc(column.load(), num_cids_, new_capacity)...);
        },
        columns_);
    capacity_ = new_capacity;
    SetNumCids(new_num_cids);
  }

  void AllocateIndex(intptr_t index, bool* did_grow) {
    *did_grow = EnsureCapacity(index);
    SetNumCids(Utils::Maximum(num_cids_, index + 1));
  }

  intptr_t AddRow(bool* did_grow) {
    *did_grow = EnsureCapacity(num_cids_);
    intptr_t id = num_cids_;
    SetNumCids(num_cids_ + 1);
    return id;
  }

  void ShrinkTo(intptr_t new_num_cids) {
    ASSERT(new_num_cids <= num_cids_);
    num_cids_ = new_num_cids;
  }

  bool IsValidIndex(intptr_t index) const {
    return 0 <= index && index < num_cids_;
  }

  void CopyFrom(const CidIndexedTable& other) {
    ASSERT(allocator_ == other.allocator_);

    std::apply([&](auto&... column) { (allocator_->Free(column.load()), ...); },
               columns_);

    columns_ = std::apply(
        [&](auto&... column) {
          return std::make_tuple(
              allocator_->Clone(column.load(), other.num_cids_)...);
        },
        other.columns_);
    capacity_ = num_cids_ = other.num_cids_;
  }

  void Remap(intptr_t* old_to_new_cid) {
    CidIndexedTable clone(allocator_);
    clone.CopyFrom(*this);
    RemapAllColumns(clone, old_to_new_cid,
                    std::index_sequence_for<Columns...>{});
  }

  template <
      intptr_t kColumnIndex,
      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
  T* GetColumn() {
    return std::get<kColumnIndex>(columns_).load();
  }

  template <
      intptr_t kColumnIndex,
      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
  const T* GetColumn() const {
    return std::get<kColumnIndex>(columns_).load();
  }

  template <
      intptr_t kColumnIndex,
      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
  T& At(intptr_t index) {
    ASSERT(IsValidIndex(index));
    return GetColumn<kColumnIndex>()[index];
  }

  template <
      intptr_t kColumnIndex,
      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
  const T& At(intptr_t index) const {
    ASSERT(IsValidIndex(index));
    return GetColumn<kColumnIndex>()[index];
  }

  intptr_t num_cids() const { return num_cids_; }
  intptr_t capacity() const { return capacity_; }

 private:
  friend class ClassTable;

  // Wrapper around AcqRelAtomic<T*> which makes it assignable and copyable
  // so that we could put it inside an std::tuple.
  template <typename T>
  struct Ptr {
    Ptr() : ptr(nullptr) {}
    Ptr(T* ptr) : ptr(ptr) {}  // NOLINT

    Ptr(const Ptr& other) { ptr.store(other.ptr.load()); }

    Ptr& operator=(const Ptr& other) {
      ptr.store(other.load());
      return *this;
    }

    T* load() const { return ptr.load(); }

    AcqRelAtomic<T*> ptr = {nullptr};
  };

  void SetNumCids(intptr_t new_num_cids) {
    if (new_num_cids > kClassIdTagMax) {
      FATAL("Too many classes");
    }
    num_cids_ = new_num_cids;
  }

  bool EnsureCapacity(intptr_t index) {
    if (index >= capacity_) {
      SetNumCidsAndCapacity(num_cids_, index + kCapacityIncrement);
      return true;
    }
    return false;
  }

  template <intptr_t kColumnIndex>
  void RemapColumn(const CidIndexedTable& old, intptr_t* old_to_new_cid) {
    auto new_column = GetColumn<kColumnIndex>();
    auto old_column = old.GetColumn<kColumnIndex>();
    for (intptr_t i = 0; i < num_cids_; i++) {
      new_column[old_to_new_cid[i]] = old_column[i];
    }
  }

  template <std::size_t... Is>
  void RemapAllColumns(const CidIndexedTable& old,
                       intptr_t* old_to_new_cid,
                       std::index_sequence<Is...>) {
    (RemapColumn<Is>(old, old_to_new_cid), ...);
  }

  static constexpr intptr_t kCapacityIncrement = 256;

  ClassTableAllocator* allocator_;
  intptr_t num_cids_ = 0;
  intptr_t capacity_ = 0;
  std::tuple<Ptr<Columns>...> columns_;
};

// Registry of all known classes.
//
// The GC will only use information about instance size and unboxed field maps
// to scan instances and will not access class objects themselves. This
// information is stored in separate columns of the |classes_| table.
//
// # Concurrency & atomicity
//
// This table is read concurrently without locking (e.g. by GC threads) so
// there are some invariants that need to be observed when working with it.
//
// * When table is updated (e.g. when the table is grown or a new class is
// registered in a table) there must be a release barrier after the update.
// Such barrier will ensure that stores which populate the table are not
// reordered past the store which exposes the new grown table or exposes
// a new class id;
// * Old versions of the table can only be freed when the world is stopped:
// no mutator and no helper threads are running. To avoid freeing a table
// which some other thread is reading from.
//
// Note that torn reads are not a concern (e.g. it is fine to use
// memmove to copy class table contents) as long as an appropriate
// barrier is issued before the copy of the table can be observed.
//
// # Hot reload
//
// Each IsolateGroup contains two ClassTable fields: |class_table| and
// |heap_walk_class_table|. GC visitors use the second field to get ClassTable
// instance which they will use for visiting pointers inside instances in
// the heap. Usually these two fields will be pointing to the same table,
// except when IsolateGroup is in the middle of reload.
//
// When reloading |class_table| will be pointing to a copy of the original
// table. Kernel loading will be modifying this table, while GC
// workers can continue using original table still available through
// |heap_walk_class_table|. If hot reload succeeds, |heap_walk_class_table|
// will be dropped and |class_table| will become the source of truth. Otherwise,
// original table will be restored from |heap_walk_class_table|.
//
// See IsolateGroup methods CloneClassTableForReload, RestoreOriginalClassTable,
// DropOriginalClassTable.
class ClassTable : public MallocAllocated {
 public:
  explicit ClassTable(ClassTableAllocator* allocator);

  ~ClassTable();

  ClassTable* Clone() const { return new ClassTable(*this); }

  ClassPtr At(intptr_t cid) const {
    if (IsTopLevelCid(cid)) {
      return top_level_classes_.At<kClassIndex>(IndexFromTopLevelCid(cid));
    }
    return classes_.At<kClassIndex>(cid);
  }

  int32_t SizeAt(intptr_t index) const {
    if (IsTopLevelCid(index)) {
      return 0;
    }
    return classes_.At<kSizeIndex>(index);
  }

  void SetAt(intptr_t index, ClassPtr raw_cls);
  void UpdateClassSize(intptr_t cid, ClassPtr raw_cls);

  bool IsValidIndex(intptr_t cid) const {
    if (IsTopLevelCid(cid)) {
      return top_level_classes_.IsValidIndex(IndexFromTopLevelCid(cid));
    }
    return classes_.IsValidIndex(cid);
  }

  bool HasValidClassAt(intptr_t cid) const { return At(cid) != nullptr; }

  UnboxedFieldBitmap GetUnboxedFieldsMapAt(intptr_t cid) const {
    ASSERT(IsValidIndex(cid));
    return classes_.At<kUnboxedFieldBitmapIndex>(cid);
  }

  void SetUnboxedFieldsMapAt(intptr_t cid, UnboxedFieldBitmap map) {
    ASSERT(IsValidIndex(cid));
    classes_.At<kUnboxedFieldBitmapIndex>(cid) = map;
  }

#if !defined(PRODUCT)
  bool ShouldTraceAllocationFor(intptr_t cid) {
    return !IsTopLevelCid(cid) &&
           (classes_.At<kAllocationTracingStateIndex>(cid) != kTracingDisabled);
  }

  void SetTraceAllocationFor(intptr_t cid, bool trace) {
    classes_.At<kAllocationTracingStateIndex>(cid) =
        trace ? kTraceAllocationBit : kTracingDisabled;
  }

  void SetCollectInstancesFor(intptr_t cid, bool trace) {
    auto& slot = classes_.At<kAllocationTracingStateIndex>(cid);
    if (trace) {
      slot |= kCollectInstancesBit;
    } else {
      slot &= ~kCollectInstancesBit;
    }
  }

  bool CollectInstancesFor(intptr_t cid) {
    auto& slot = classes_.At<kAllocationTracingStateIndex>(cid);
    return (slot & kCollectInstancesBit) != 0;
  }

  void UpdateCachedAllocationTracingStateTablePointer() {
    cached_allocation_tracing_state_table_.store(
        classes_.GetColumn<kAllocationTracingStateIndex>());
  }
#else
  void UpdateCachedAllocationTracingStateTablePointer() {}
#endif  // !defined(PRODUCT)

#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  void PopulateUserVisibleNames();

  const char* UserVisibleNameFor(intptr_t cid) {
    if (!classes_.IsValidIndex(cid)) {
      return nullptr;
    }
    return classes_.At<kClassNameIndex>(cid);
  }

  void SetUserVisibleNameFor(intptr_t cid, const char* name) {
    ASSERT(classes_.At<kClassNameIndex>(cid) == nullptr);
    classes_.At<kClassNameIndex>(cid) = name;
  }
#endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)

  intptr_t NumCids() const { return classes_.num_cids(); }
  intptr_t Capacity() const { return classes_.capacity(); }

  intptr_t NumTopLevelCids() const { return top_level_classes_.num_cids(); }

  void Register(const Class& cls);
  void AllocateIndex(intptr_t index);

  void RegisterTopLevel(const Class& cls);
  void UnregisterTopLevel(intptr_t index);

  void Remap(intptr_t* old_to_new_cids);

  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // If a snapshot reader has populated the class table then the
  // sizes in the class table are not correct. Iterates through the
  // table, updating the sizes.
  void CopySizesFromClassObjects();

  void Validate();

  void Print();

#if defined(DART_PRECOMPILER)
  void PrintObjectLayout(const char* filename);
#endif

#ifndef PRODUCT
  // Describes layout of heap stats for code generation. See offset_extractor.cc
  struct ArrayTraits {
    static intptr_t elements_start_offset() { return 0; }

    static constexpr intptr_t kElementSize = sizeof(uint8_t);
  };

  static intptr_t allocation_tracing_state_table_offset() {
    static_assert(sizeof(cached_allocation_tracing_state_table_) == kWordSize);
    return OFFSET_OF(ClassTable, cached_allocation_tracing_state_table_);
  }

  void AllocationProfilePrintJSON(JSONStream* stream, bool internal);

  void PrintToJSONObject(JSONObject* object);
#endif  // !PRODUCT

  // Deallocates table copies. Do not call during concurrent access to table.
  void FreeOldTables();

  static bool IsTopLevelCid(intptr_t cid) { return cid >= kTopLevelCidOffset; }

  static intptr_t IndexFromTopLevelCid(intptr_t cid) {
    ASSERT(IsTopLevelCid(cid));
    return cid - kTopLevelCidOffset;
  }

  static intptr_t CidFromTopLevelIndex(intptr_t index) {
    return kTopLevelCidOffset + index;
  }

 private:
  friend class ClassTableAllocator;
  friend class Dart;
  friend Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
                                                   const char* name,
                                                   char** error);
  friend class IsolateGroup;  // for table()
  static constexpr int kInitialCapacity = 512;

  static constexpr intptr_t kTopLevelCidOffset = kClassIdTagMax + 1;

  ClassTable(const ClassTable& original)
      : allocator_(original.allocator_),
        classes_(original.allocator_),
        top_level_classes_(original.allocator_) {
    classes_.CopyFrom(original.classes_);

#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
    // Copying classes_ doesn't perform a deep copy. Ensure we duplicate
    // the class names to avoid double free crashes at shutdown.
    for (intptr_t cid = 1; cid < classes_.num_cids(); ++cid) {
      if (classes_.IsValidIndex(cid)) {
        const char* cls_name = classes_.At<kClassNameIndex>(cid);
        if (cls_name != nullptr) {
          classes_.At<kClassNameIndex>(cid) = Utils::StrDup(cls_name);
        }
      }
    }
#endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)

    top_level_classes_.CopyFrom(original.top_level_classes_);
    UpdateCachedAllocationTracingStateTablePointer();
  }

  void AllocateTopLevelIndex(intptr_t index);

  ClassPtr* table() { return classes_.GetColumn<kClassIndex>(); }

  // Used to drop recently added classes.
  void SetNumCids(intptr_t num_cids, intptr_t num_tlc_cids) {
    classes_.ShrinkTo(num_cids);
    top_level_classes_.ShrinkTo(num_tlc_cids);
  }

  ClassTableAllocator* allocator_;

  // Unfortunately std::tuple used by CidIndexedTable does not have a stable
  // layout so we can't refer to its elements from generated code.
  NOT_IN_PRODUCT(AcqRelAtomic<uint8_t*> cached_allocation_tracing_state_table_ =
                     {nullptr});

  enum {
    kClassIndex = 0,
    kSizeIndex,
    kUnboxedFieldBitmapIndex,
#if !defined(PRODUCT)
    kAllocationTracingStateIndex,
#endif
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
    kClassNameIndex,
#endif
  };

#if !defined(PRODUCT)
  CidIndexedTable<ClassIdTagType,
                  ClassPtr,
                  uint32_t,
                  UnboxedFieldBitmap,
                  uint8_t,
                  const char*>
      classes_;
#elif defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  CidIndexedTable<ClassIdTagType,
                  ClassPtr,
                  uint32_t,
                  UnboxedFieldBitmap,
                  const char*>
      classes_;
#else
  CidIndexedTable<ClassIdTagType, ClassPtr, uint32_t, UnboxedFieldBitmap>
      classes_;
#endif

#ifndef PRODUCT
  enum {
    kTracingDisabled = 0,
    kTraceAllocationBit = (1 << 0),
    kCollectInstancesBit = (1 << 1),
  };
#endif  // !PRODUCT

  CidIndexedTable<classid_t, ClassPtr> top_level_classes_;
};

}  // namespace dart

#endif  // RUNTIME_VM_CLASS_TABLE_H_
