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 
10 namespace cppgc {
11 
12 /**
13  * Index identifying a custom space.
14  */
15 struct CustomSpaceIndex {
CustomSpaceIndexcppgc::CustomSpaceIndex16   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  */
24 class 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  */
48 template <typename ConcreteCustomSpace>
49 class 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  */
68 template <typename T, typename = void>
69 struct SpaceTrait {
70   using Space = void;
71 };
72 
73 namespace internal {
74 
75 template <typename CustomSpace>
76 struct IsAllocatedOnCompactableSpaceImpl {
77   static constexpr bool value = CustomSpace::kSupportsCompaction;
78 };
79 
80 template <>
81 struct IsAllocatedOnCompactableSpaceImpl<void> {
82   // Non-custom spaces are by default not compactable.
83   static constexpr bool value = false;
84 };
85 
86 template <typename T>
87 struct 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