11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef INCLUDE_CPPGC_CUSTOM_SPACE_H_
61cb0ef41Sopenharmony_ci#define INCLUDE_CPPGC_CUSTOM_SPACE_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <stddef.h>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cinamespace cppgc {
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci/**
131cb0ef41Sopenharmony_ci * Index identifying a custom space.
141cb0ef41Sopenharmony_ci */
151cb0ef41Sopenharmony_cistruct CustomSpaceIndex {
161cb0ef41Sopenharmony_ci  constexpr CustomSpaceIndex(size_t value) : value(value) {}  // NOLINT
171cb0ef41Sopenharmony_ci  size_t value;
181cb0ef41Sopenharmony_ci};
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci/**
211cb0ef41Sopenharmony_ci * Top-level base class for custom spaces. Users must inherit from CustomSpace
221cb0ef41Sopenharmony_ci * below.
231cb0ef41Sopenharmony_ci */
241cb0ef41Sopenharmony_ciclass CustomSpaceBase {
251cb0ef41Sopenharmony_ci public:
261cb0ef41Sopenharmony_ci  virtual ~CustomSpaceBase() = default;
271cb0ef41Sopenharmony_ci  virtual CustomSpaceIndex GetCustomSpaceIndex() const = 0;
281cb0ef41Sopenharmony_ci  virtual bool IsCompactable() const = 0;
291cb0ef41Sopenharmony_ci};
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci/**
321cb0ef41Sopenharmony_ci * Base class custom spaces should directly inherit from. The class inheriting
331cb0ef41Sopenharmony_ci * from `CustomSpace` must define `kSpaceIndex` as unique space index. These
341cb0ef41Sopenharmony_ci * indices need for form a sequence starting at 0.
351cb0ef41Sopenharmony_ci *
361cb0ef41Sopenharmony_ci * Example:
371cb0ef41Sopenharmony_ci * \code
381cb0ef41Sopenharmony_ci * class CustomSpace1 : public CustomSpace<CustomSpace1> {
391cb0ef41Sopenharmony_ci *  public:
401cb0ef41Sopenharmony_ci *   static constexpr CustomSpaceIndex kSpaceIndex = 0;
411cb0ef41Sopenharmony_ci * };
421cb0ef41Sopenharmony_ci * class CustomSpace2 : public CustomSpace<CustomSpace2> {
431cb0ef41Sopenharmony_ci *  public:
441cb0ef41Sopenharmony_ci *   static constexpr CustomSpaceIndex kSpaceIndex = 1;
451cb0ef41Sopenharmony_ci * };
461cb0ef41Sopenharmony_ci * \endcode
471cb0ef41Sopenharmony_ci */
481cb0ef41Sopenharmony_citemplate <typename ConcreteCustomSpace>
491cb0ef41Sopenharmony_ciclass CustomSpace : public CustomSpaceBase {
501cb0ef41Sopenharmony_ci public:
511cb0ef41Sopenharmony_ci  /**
521cb0ef41Sopenharmony_ci   * Compaction is only supported on spaces that manually manage slots
531cb0ef41Sopenharmony_ci   * recording.
541cb0ef41Sopenharmony_ci   */
551cb0ef41Sopenharmony_ci  static constexpr bool kSupportsCompaction = false;
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  CustomSpaceIndex GetCustomSpaceIndex() const final {
581cb0ef41Sopenharmony_ci    return ConcreteCustomSpace::kSpaceIndex;
591cb0ef41Sopenharmony_ci  }
601cb0ef41Sopenharmony_ci  bool IsCompactable() const final {
611cb0ef41Sopenharmony_ci    return ConcreteCustomSpace::kSupportsCompaction;
621cb0ef41Sopenharmony_ci  }
631cb0ef41Sopenharmony_ci};
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci/**
661cb0ef41Sopenharmony_ci * User-overridable trait that allows pinning types to custom spaces.
671cb0ef41Sopenharmony_ci */
681cb0ef41Sopenharmony_citemplate <typename T, typename = void>
691cb0ef41Sopenharmony_cistruct SpaceTrait {
701cb0ef41Sopenharmony_ci  using Space = void;
711cb0ef41Sopenharmony_ci};
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_cinamespace internal {
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_citemplate <typename CustomSpace>
761cb0ef41Sopenharmony_cistruct IsAllocatedOnCompactableSpaceImpl {
771cb0ef41Sopenharmony_ci  static constexpr bool value = CustomSpace::kSupportsCompaction;
781cb0ef41Sopenharmony_ci};
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_citemplate <>
811cb0ef41Sopenharmony_cistruct IsAllocatedOnCompactableSpaceImpl<void> {
821cb0ef41Sopenharmony_ci  // Non-custom spaces are by default not compactable.
831cb0ef41Sopenharmony_ci  static constexpr bool value = false;
841cb0ef41Sopenharmony_ci};
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_citemplate <typename T>
871cb0ef41Sopenharmony_cistruct IsAllocatedOnCompactableSpace {
881cb0ef41Sopenharmony_ci public:
891cb0ef41Sopenharmony_ci  static constexpr bool value =
901cb0ef41Sopenharmony_ci      IsAllocatedOnCompactableSpaceImpl<typename SpaceTrait<T>::Space>::value;
911cb0ef41Sopenharmony_ci};
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci}  // namespace internal
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci}  // namespace cppgc
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci#endif  // INCLUDE_CPPGC_CUSTOM_SPACE_H_
98