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 "cppgc/internal/api-constants.h"
9#include "cppgc/platform.h"
10#include "cppgc/trace-trait.h"
11#include "cppgc/type-traits.h"
12
13namespace cppgc {
14
15class Visitor;
16
17/**
18 * Base class for managed objects. Only descendent types of `GarbageCollected`
19 * can be constructed using `MakeGarbageCollected()`. Must be inherited from as
20 * left-most base class.
21 *
22 * Types inheriting from GarbageCollected must provide a method of
23 * signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
24 * pointers to the visitor and delegates to garbage-collected base classes.
25 * The method must be virtual if the type is not directly a child of
26 * GarbageCollected and marked as final.
27 *
28 * \code
29 * // Example using final class.
30 * class FinalType final : public GarbageCollected<FinalType> {
31 *  public:
32 *   void Trace(cppgc::Visitor* visitor) const {
33 *     // Dispatch using visitor->Trace(...);
34 *   }
35 * };
36 *
37 * // Example using non-final base class.
38 * class NonFinalBase : public GarbageCollected<NonFinalBase> {
39 *  public:
40 *   virtual void Trace(cppgc::Visitor*) const {}
41 * };
42 *
43 * class FinalChild final : public NonFinalBase {
44 *  public:
45 *   void Trace(cppgc::Visitor* visitor) const final {
46 *     // Dispatch using visitor->Trace(...);
47 *     NonFinalBase::Trace(visitor);
48 *   }
49 * };
50 * \endcode
51 */
52template <typename T>
53class GarbageCollected {
54 public:
55  using IsGarbageCollectedTypeMarker = void;
56  using ParentMostGarbageCollectedType = T;
57
58  // Must use MakeGarbageCollected.
59  void* operator new(size_t) = delete;
60  void* operator new[](size_t) = delete;
61  // The garbage collector is taking care of reclaiming the object. Also,
62  // virtual destructor requires an unambiguous, accessible 'operator delete'.
63  void operator delete(void*) {
64#ifdef V8_ENABLE_CHECKS
65    internal::Fatal(
66        "Manually deleting a garbage collected object is not allowed");
67#endif  // V8_ENABLE_CHECKS
68  }
69  void operator delete[](void*) = delete;
70
71 protected:
72  GarbageCollected() = default;
73};
74
75/**
76 * Base class for managed mixin objects. Such objects cannot be constructed
77 * directly but must be mixed into the inheritance hierarchy of a
78 * GarbageCollected object.
79 *
80 * Types inheriting from GarbageCollectedMixin must override a virtual method
81 * of signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
82 * pointers to the visitor and delegates to base classes.
83 *
84 * \code
85 * class Mixin : public GarbageCollectedMixin {
86 *  public:
87 *   void Trace(cppgc::Visitor* visitor) const override {
88 *     // Dispatch using visitor->Trace(...);
89 *   }
90 * };
91 * \endcode
92 */
93class GarbageCollectedMixin {
94 public:
95  using IsGarbageCollectedMixinTypeMarker = void;
96
97  /**
98   * This Trace method must be overriden by objects inheriting from
99   * GarbageCollectedMixin.
100   */
101  virtual void Trace(cppgc::Visitor*) const {}
102};
103
104}  // namespace cppgc
105
106#endif  // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
107