// 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 V8_HEAP_CPPGC_GC_INFO_TABLE_H_
#define V8_HEAP_CPPGC_GC_INFO_TABLE_H_

#include <stdint.h>

#include "include/cppgc/internal/gc-info.h"
#include "include/cppgc/platform.h"
#include "include/v8config.h"
#include "src/base/logging.h"
#include "src/base/macros.h"
#include "src/base/platform/mutex.h"
#include "src/base/platform/platform.h"

namespace cppgc {
namespace internal {

// GCInfo contains metadata for objects that are instantiated from classes that
// inherit from GarbageCollected.
struct GCInfo final {
  FinalizationCallback finalize;
  TraceCallback trace;
  NameCallback name;
  bool has_v_table;
};

class V8_EXPORT GCInfoTable final {
 public:
  // At maximum |kMaxIndex - 1| indices are supported.
  //
  // We assume that 14 bits are enough to represent all possible types.
  //
  // For Blink during telemetry runs, we see about 1,000 different types;
  // looking at the output of the Oilpan GC clang plugin, there appear to be at
  // most about 6,000 types. Thus 14 bits should be more than twice as many bits
  // as we will ever need. Different contexts may require adjusting this limit.
  static constexpr GCInfoIndex kMaxIndex = 1 << 14;

  // Minimum index returned. Values smaller |kMinIndex| may be used as
  // sentinels.
  static constexpr GCInfoIndex kMinIndex = 1;

  // (Light) experimentation suggests that Blink doesn't need more than this
  // while handling content on popular web properties.
  static constexpr GCInfoIndex kInitialWantedLimit = 512;

  // Refer through GlobalGCInfoTable for retrieving the global table outside
  // of testing code.
  explicit GCInfoTable(PageAllocator* page_allocator);
  ~GCInfoTable();

  GCInfoIndex RegisterNewGCInfo(const GCInfo& info);

  const GCInfo& GCInfoFromIndex(GCInfoIndex index) const {
    DCHECK_GE(index, kMinIndex);
    DCHECK_LT(index, kMaxIndex);
    DCHECK(table_);
    return table_[index];
  }

  GCInfoIndex NumberOfGCInfosForTesting() const { return current_index_; }
  GCInfoIndex LimitForTesting() const { return limit_; }
  GCInfo& TableSlotForTesting(GCInfoIndex index) { return table_[index]; }

 private:
  void Resize();

  GCInfoIndex InitialTableLimit() const;
  size_t MaxTableSize() const;

  void CheckMemoryIsZeroed(uintptr_t* base, size_t len);

  PageAllocator* page_allocator_;
  // Holds the per-class GCInfo descriptors; each HeapObjectHeader keeps an
  // index into this table.
  GCInfo* table_;
  uint8_t* read_only_table_end_;
  // Current index used when requiring a new GCInfo object.
  GCInfoIndex current_index_ = kMinIndex;
  // The limit (exclusive) of the currently allocated table.
  GCInfoIndex limit_ = 0;

  v8::base::Mutex table_mutex_;

  DISALLOW_COPY_AND_ASSIGN(GCInfoTable);
};

class V8_EXPORT GlobalGCInfoTable final {
 public:
  // Sets up a singleton table that can be acquired using Get().
  static void Create(PageAllocator* page_allocator);

  // Accessors for the singleton table.
  static GCInfoTable& GetMutable() { return *global_table_; }
  static const GCInfoTable& Get() { return *global_table_; }

  static const GCInfo& GCInfoFromIndex(GCInfoIndex index) {
    return Get().GCInfoFromIndex(index);
  }

 private:
  // Singleton for each process. Retrieved through Get().
  static GCInfoTable* global_table_;

  DISALLOW_NEW_AND_DELETE()
  DISALLOW_COPY_AND_ASSIGN(GlobalGCInfoTable);
};

}  // namespace internal
}  // namespace cppgc

#endif  // V8_HEAP_CPPGC_GC_INFO_TABLE_H_
