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_GARBAGE_COLLECTED_H_
61cb0ef41Sopenharmony_ci#define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "cppgc/internal/api-constants.h"
91cb0ef41Sopenharmony_ci#include "cppgc/platform.h"
101cb0ef41Sopenharmony_ci#include "cppgc/trace-trait.h"
111cb0ef41Sopenharmony_ci#include "cppgc/type-traits.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace cppgc {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciclass Visitor;
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci/**
181cb0ef41Sopenharmony_ci * Base class for managed objects. Only descendent types of `GarbageCollected`
191cb0ef41Sopenharmony_ci * can be constructed using `MakeGarbageCollected()`. Must be inherited from as
201cb0ef41Sopenharmony_ci * left-most base class.
211cb0ef41Sopenharmony_ci *
221cb0ef41Sopenharmony_ci * Types inheriting from GarbageCollected must provide a method of
231cb0ef41Sopenharmony_ci * signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
241cb0ef41Sopenharmony_ci * pointers to the visitor and delegates to garbage-collected base classes.
251cb0ef41Sopenharmony_ci * The method must be virtual if the type is not directly a child of
261cb0ef41Sopenharmony_ci * GarbageCollected and marked as final.
271cb0ef41Sopenharmony_ci *
281cb0ef41Sopenharmony_ci * \code
291cb0ef41Sopenharmony_ci * // Example using final class.
301cb0ef41Sopenharmony_ci * class FinalType final : public GarbageCollected<FinalType> {
311cb0ef41Sopenharmony_ci *  public:
321cb0ef41Sopenharmony_ci *   void Trace(cppgc::Visitor* visitor) const {
331cb0ef41Sopenharmony_ci *     // Dispatch using visitor->Trace(...);
341cb0ef41Sopenharmony_ci *   }
351cb0ef41Sopenharmony_ci * };
361cb0ef41Sopenharmony_ci *
371cb0ef41Sopenharmony_ci * // Example using non-final base class.
381cb0ef41Sopenharmony_ci * class NonFinalBase : public GarbageCollected<NonFinalBase> {
391cb0ef41Sopenharmony_ci *  public:
401cb0ef41Sopenharmony_ci *   virtual void Trace(cppgc::Visitor*) const {}
411cb0ef41Sopenharmony_ci * };
421cb0ef41Sopenharmony_ci *
431cb0ef41Sopenharmony_ci * class FinalChild final : public NonFinalBase {
441cb0ef41Sopenharmony_ci *  public:
451cb0ef41Sopenharmony_ci *   void Trace(cppgc::Visitor* visitor) const final {
461cb0ef41Sopenharmony_ci *     // Dispatch using visitor->Trace(...);
471cb0ef41Sopenharmony_ci *     NonFinalBase::Trace(visitor);
481cb0ef41Sopenharmony_ci *   }
491cb0ef41Sopenharmony_ci * };
501cb0ef41Sopenharmony_ci * \endcode
511cb0ef41Sopenharmony_ci */
521cb0ef41Sopenharmony_citemplate <typename T>
531cb0ef41Sopenharmony_ciclass GarbageCollected {
541cb0ef41Sopenharmony_ci public:
551cb0ef41Sopenharmony_ci  using IsGarbageCollectedTypeMarker = void;
561cb0ef41Sopenharmony_ci  using ParentMostGarbageCollectedType = T;
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  // Must use MakeGarbageCollected.
591cb0ef41Sopenharmony_ci  void* operator new(size_t) = delete;
601cb0ef41Sopenharmony_ci  void* operator new[](size_t) = delete;
611cb0ef41Sopenharmony_ci  // The garbage collector is taking care of reclaiming the object. Also,
621cb0ef41Sopenharmony_ci  // virtual destructor requires an unambiguous, accessible 'operator delete'.
631cb0ef41Sopenharmony_ci  void operator delete(void*) {
641cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_CHECKS
651cb0ef41Sopenharmony_ci    internal::Fatal(
661cb0ef41Sopenharmony_ci        "Manually deleting a garbage collected object is not allowed");
671cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_CHECKS
681cb0ef41Sopenharmony_ci  }
691cb0ef41Sopenharmony_ci  void operator delete[](void*) = delete;
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci protected:
721cb0ef41Sopenharmony_ci  GarbageCollected() = default;
731cb0ef41Sopenharmony_ci};
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci/**
761cb0ef41Sopenharmony_ci * Base class for managed mixin objects. Such objects cannot be constructed
771cb0ef41Sopenharmony_ci * directly but must be mixed into the inheritance hierarchy of a
781cb0ef41Sopenharmony_ci * GarbageCollected object.
791cb0ef41Sopenharmony_ci *
801cb0ef41Sopenharmony_ci * Types inheriting from GarbageCollectedMixin must override a virtual method
811cb0ef41Sopenharmony_ci * of signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
821cb0ef41Sopenharmony_ci * pointers to the visitor and delegates to base classes.
831cb0ef41Sopenharmony_ci *
841cb0ef41Sopenharmony_ci * \code
851cb0ef41Sopenharmony_ci * class Mixin : public GarbageCollectedMixin {
861cb0ef41Sopenharmony_ci *  public:
871cb0ef41Sopenharmony_ci *   void Trace(cppgc::Visitor* visitor) const override {
881cb0ef41Sopenharmony_ci *     // Dispatch using visitor->Trace(...);
891cb0ef41Sopenharmony_ci *   }
901cb0ef41Sopenharmony_ci * };
911cb0ef41Sopenharmony_ci * \endcode
921cb0ef41Sopenharmony_ci */
931cb0ef41Sopenharmony_ciclass GarbageCollectedMixin {
941cb0ef41Sopenharmony_ci public:
951cb0ef41Sopenharmony_ci  using IsGarbageCollectedMixinTypeMarker = void;
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  /**
981cb0ef41Sopenharmony_ci   * This Trace method must be overriden by objects inheriting from
991cb0ef41Sopenharmony_ci   * GarbageCollectedMixin.
1001cb0ef41Sopenharmony_ci   */
1011cb0ef41Sopenharmony_ci  virtual void Trace(cppgc::Visitor*) const {}
1021cb0ef41Sopenharmony_ci};
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci}  // namespace cppgc
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci#endif  // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
107