chromium/v8/src/objects/managed.h

// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_MANAGED_H_
#define V8_OBJECTS_MANAGED_H_

#include <memory>

#include "src/execution/isolate.h"
#include "src/handles/handles.h"
#include "src/heap/factory.h"
#include "src/objects/foreign.h"
#include "src/sandbox/external-pointer-table.h"

namespace v8::internal {

// Mechanism for associating an ExternalPointerTag with a C++ type that is
// referenced via a Managed. Every such C++ type must have a unique
// ExternalPointerTag to ensure type-safe access to the external object.
//
// This mechanism supports two ways of associating tags with types:
//
// 1. By adding a 'static constexpr ExternalPointerTag kManagedTag` field to
//    the C++ class (preferred for C++ types defined in V8 code):
//
//      class MyCppClass {
//       public:
//        static constexpr ExternalPointerTag kManagedTag = kMyCppClassTag;
//        ...;
//
// 2. Through the ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED macro, which uses
//    template specialization (necessary for C++ types defined outside of V8):
//
//      ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(MyCppClass, kMyCppClassTag)
//
//    Note that the struct created by this macro must be visible when the
//    Managed<CppType> is used. In particular, there may be issues if the
//    CppType is only forward declared and the respective header isn't included.
//    Note also that this macro must be used inside the v8::internal namespace.
//
template <typename CppType>
struct TagForManaged {};

#define ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(CppType, Tag)

// Implements a doubly-linked lists of destructors for the isolate.
struct ManagedPtrDestructor
#ifdef V8_ENABLE_SANDBOX
    : public ExternalPointerTable::ManagedResource {};

// The GC finalizer of a managed object, which does not depend on
// the template parameter.
V8_EXPORT_PRIVATE void ManagedObjectFinalizer(
    const v8::WeakCallbackInfo<void>& data);

// {Managed<T>} is essentially a {std::shared_ptr<T>} allocated on the heap
// that can be used to manage the lifetime of C++ objects that are shared
// across multiple isolates.
// When a {Managed<T>} object is garbage collected (or an isolate which
// contains {Managed<T>} is torn down), the {Managed<T>} deletes its underlying
// {std::shared_ptr<T>}, thereby decrementing its internal reference count,
// which will delete the C++ object when the reference count drops to 0.
template <class CppType>
class Managed : public Foreign {};

// {TrustedManaged<T>} is semantically equivalent to {Managed<T>}, but lives in
// the trusted space. It is thus based on {TrustedForeign} instead of {Foreign}
// and does not need any tagging.
template <class CppType>
class TrustedManaged : public TrustedForeign {};

}  // namespace v8::internal

#endif  // V8_OBJECTS_MANAGED_H_