v8  8.4.371 (node 14.15.5)
V8 is Google's open source JavaScript engine
garbage-collected.h
Go to the documentation of this file.
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_GARBAGE_COLLECTED_H_
6 #define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
7 
8 #include <type_traits>
9 
10 #include "cppgc/internal/api-constants.h"
11 #include "cppgc/macros.h"
12 #include "cppgc/platform.h"
13 #include "cppgc/trace-trait.h"
14 #include "cppgc/type-traits.h"
15 
16 namespace cppgc {
17 
18 class Visitor;
19 
20 namespace internal {
21 
23  public:
24  // Must use MakeGarbageCollected.
25  void* operator new(size_t) = delete;
26  void* operator new[](size_t) = delete;
27  // The garbage collector is taking care of reclaiming the object. Also,
28  // virtual destructor requires an unambiguous, accessible 'operator delete'.
29  void operator delete(void*) {
30 #ifdef V8_ENABLE_CHECKS
31  internal::Abort();
32 #endif // V8_ENABLE_CHECKS
33  }
34  void operator delete[](void*) = delete;
35 
36  protected:
37  GarbageCollectedBase() = default;
38 };
39 
40 } // namespace internal
41 
42 /**
43  * Base class for managed objects. Only descendent types of GarbageCollected
44  * can be constructed using MakeGarbageCollected. Must be inherited from as
45  * left-most base class.
46  *
47  * Types inheriting from GarbageCollected must provide a method of
48  * signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
49  * pointers to the visitor and delegates to garbage-collected base classes.
50  * The method must be virtual if the type is not directly a child of
51  * GarbageCollected and marked as final.
52  *
53  * \code
54  * // Example using final class.
55  * class FinalType final : public GarbageCollected<FinalType> {
56  * public:
57  * void Trace(cppgc::Visitor* visitor) const {
58  * // Dispatch using visitor->Trace(...);
59  * }
60  * };
61  *
62  * // Example using non-final base class.
63  * class NonFinalBase : public GarbageCollected<NonFinalBase> {
64  * public:
65  * virtual void Trace(cppgc::Visitor*) const {}
66  * };
67  *
68  * class FinalChild final : public NonFinalBase {
69  * public:
70  * void Trace(cppgc::Visitor* visitor) const final {
71  * // Dispatch using visitor->Trace(...);
72  * NonFinalBase::Trace(visitor);
73  * }
74  * };
75  * \endcode
76  */
77 template <typename>
79  public:
80  using IsGarbageCollectedTypeMarker = void;
81 
82  protected:
83  GarbageCollected() = default;
84 };
85 
86 /**
87  * Base class for managed mixin objects. Such objects cannot be constructed
88  * directly but must be mixed into the inheritance hierarchy of a
89  * GarbageCollected object.
90  *
91  * Types inheriting from GarbageCollectedMixin must override a virtual method
92  * of signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
93  * pointers to the visitor and delegates to base classes.
94  *
95  * \code
96  * class Mixin : public GarbageCollectedMixin {
97  * public:
98  * void Trace(cppgc::Visitor* visitor) const override {
99  * // Dispatch using visitor->Trace(...);
100  * }
101  * };
102  * \endcode
103  */
105  public:
106  using IsGarbageCollectedMixinTypeMarker = void;
107 
108  // Sentinel used to mark not-fully-constructed mixins.
109  static constexpr void* kNotFullyConstructedObject = nullptr;
110 
111  // Provide default implementation that indicate that the vtable is not yet
112  // set up properly. This is used to to get GCInfo objects for mixins so that
113  // these objects can be processed later on.
115  return {kNotFullyConstructedObject, nullptr};
116  }
117 
118  /**
119  * This Trace method must be overriden by objects inheriting from
120  * GarbageCollectedMixin.
121  */
122  virtual void Trace(cppgc::Visitor*) const {}
123 };
124 
125 /**
126  * Macro defines all methods and markers needed for handling mixins. Must be
127  * used on the type that is inheriting from GarbageCollected *and*
128  * GarbageCollectedMixin.
129  *
130  * \code
131  * class Mixin : public GarbageCollectedMixin {
132  * public:
133  * void Trace(cppgc::Visitor* visitor) const override {
134  * // Dispatch using visitor->Trace(...);
135  * }
136  * };
137  *
138  * class Foo : public GarbageCollected<Foo>, public Mixin {
139  * USING_GARBAGE_COLLECTED_MIXIN();
140  * public:
141  * void Trace(cppgc::Visitor* visitor) const override {
142  * // Dispatch using visitor->Trace(...);
143  * Mixin::Trace(visitor);
144  * }
145  * };
146  * \endcode
147  */
148 #define USING_GARBAGE_COLLECTED_MIXIN()
149  public:
150  /* Marker is used by clang to check for proper usages of the macro. */
151  typedef int HasUsingGarbageCollectedMixinMacro;
152 
153  TraceDescriptor GetTraceDescriptor() const override {
154  static_assert(
155  internal::IsSubclassOfTemplate<
156  std::remove_const_t<std::remove_pointer_t<decltype(this)>>,
157  cppgc::GarbageCollected>::value,
158  "Only garbage collected objects can have garbage collected mixins");
159  return {this, TraceTrait<std::remove_const_t<
160  std::remove_pointer_t<decltype(this)>>>::Trace};
161  }
162 
163  private:
164  friend class internal::__thisIsHereToForceASemicolonAfterThisMacro
165 
166 /**
167  * Merge two or more Mixins into one.
168  *
169  * \code
170  * class A : public GarbageCollectedMixin {};
171  * class B : public GarbageCollectedMixin {};
172  * class C : public A, public B {
173  * MERGE_GARBAGE_COLLECTED_MIXINS();
174  * public:
175  * };
176  * \endcode
177  */
178 #define MERGE_GARBAGE_COLLECTED_MIXINS()
179  public:
180  /* When using multiple mixins the methods become */
181  /* ambigous. Providing additional implementations */
182  /* disambiguate them again. */
183  TraceDescriptor GetTraceDescriptor() const override {
184  return {kNotFullyConstructedObject, nullptr};
185  }
186 
187  private:
188  friend class internal::__thisIsHereToForceASemicolonAfterThisMacro
189 
190 } // namespace cppgc
191 
192 #endif // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_