1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef INCLUDE_CPPGC_CUSTOM_SPACE_H_
6#define INCLUDE_CPPGC_CUSTOM_SPACE_H_
7
8#include <stddef.h>
9
10namespace cppgc {
11
12/**
13 * Index identifying a custom space.
14 */
15struct CustomSpaceIndex {
16  constexpr CustomSpaceIndex(size_t value) : value(value) {}  // NOLINT
17  size_t value;
18};
19
20/**
21 * Top-level base class for custom spaces. Users must inherit from CustomSpace
22 * below.
23 */
24class CustomSpaceBase {
25 public:
26  virtual ~CustomSpaceBase() = default;
27  virtual CustomSpaceIndex GetCustomSpaceIndex() const = 0;
28  virtual bool IsCompactable() const = 0;
29};
30
31/**
32 * Base class custom spaces should directly inherit from. The class inheriting
33 * from `CustomSpace` must define `kSpaceIndex` as unique space index. These
34 * indices need for form a sequence starting at 0.
35 *
36 * Example:
37 * \code
38 * class CustomSpace1 : public CustomSpace<CustomSpace1> {
39 *  public:
40 *   static constexpr CustomSpaceIndex kSpaceIndex = 0;
41 * };
42 * class CustomSpace2 : public CustomSpace<CustomSpace2> {
43 *  public:
44 *   static constexpr CustomSpaceIndex kSpaceIndex = 1;
45 * };
46 * \endcode
47 */
48template <typename ConcreteCustomSpace>
49class CustomSpace : public CustomSpaceBase {
50 public:
51  /**
52   * Compaction is only supported on spaces that manually manage slots
53   * recording.
54   */
55  static constexpr bool kSupportsCompaction = false;
56
57  CustomSpaceIndex GetCustomSpaceIndex() const final {
58    return ConcreteCustomSpace::kSpaceIndex;
59  }
60  bool IsCompactable() const final {
61    return ConcreteCustomSpace::kSupportsCompaction;
62  }
63};
64
65/**
66 * User-overridable trait that allows pinning types to custom spaces.
67 */
68template <typename T, typename = void>
69struct SpaceTrait {
70  using Space = void;
71};
72
73namespace internal {
74
75template <typename CustomSpace>
76struct IsAllocatedOnCompactableSpaceImpl {
77  static constexpr bool value = CustomSpace::kSupportsCompaction;
78};
79
80template <>
81struct IsAllocatedOnCompactableSpaceImpl<void> {
82  // Non-custom spaces are by default not compactable.
83  static constexpr bool value = false;
84};
85
86template <typename T>
87struct IsAllocatedOnCompactableSpace {
88 public:
89  static constexpr bool value =
90      IsAllocatedOnCompactableSpaceImpl<typename SpaceTrait<T>::Space>::value;
91};
92
93}  // namespace internal
94
95}  // namespace cppgc
96
97#endif  // INCLUDE_CPPGC_CUSTOM_SPACE_H_
98