chromium/v8/include/cppgc/member.h

// Copyright 2020 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 INCLUDE_CPPGC_MEMBER_H_
#define INCLUDE_CPPGC_MEMBER_H_

#include <atomic>
#include <cstddef>
#include <type_traits>

#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/member-storage.h"
#include "cppgc/internal/pointer-policies.h"
#include "cppgc/sentinel-pointer.h"
#include "cppgc/type-traits.h"
#include "v8config.h"  // NOLINT(build/include_directory)

namespace cppgc {

namespace subtle {
class HeapConsistency;
}  // namespace subtle

class Visitor;

namespace internal {

// MemberBase always refers to the object as const object and defers to
// BasicMember on casting to the right type as needed.
template <typename StorageType>
class V8_TRIVIAL_ABI MemberBase {};

// The basic class from which all Member classes are 'generated'.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
                                         private CheckingPolicy {};

// Member equality operators.
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessTag2,
          typename WriteBarrierPolicy2, typename CheckingPolicy2,
          typename StorageType>
V8_INLINE bool operator==(
    const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
                      StorageType>& member1,
    const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
                      StorageType>& member2) {}

template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessTag2,
          typename WriteBarrierPolicy2, typename CheckingPolicy2,
          typename StorageType>
V8_INLINE bool operator!=(
    const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
                      StorageType>& member1,
    const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
                      StorageType>& member2) {}

// Equality with raw pointers.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType, typename U>
V8_INLINE bool operator==(
    const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
                      StorageType>& member,
    U* raw) {}

template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType, typename U>
V8_INLINE bool operator!=(
    const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
                      StorageType>& member,
    U* raw) {}

template <typename T, typename U, typename WeaknessTag,
          typename WriteBarrierPolicy, typename CheckingPolicy,
          typename StorageType>
V8_INLINE bool operator==(
    T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
                              CheckingPolicy, StorageType>& member) {}

template <typename T, typename U, typename WeaknessTag,
          typename WriteBarrierPolicy, typename CheckingPolicy,
          typename StorageType>
V8_INLINE bool operator!=(
    T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
                              CheckingPolicy, StorageType>& member) {}

// Equality with sentinel.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(
    const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
                      StorageType>& member,
    SentinelPointer) {}

template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(
    const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
                      StorageType>& member,
    SentinelPointer s) {}

template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(
    SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
                                         CheckingPolicy, StorageType>& member) {}

template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(
    SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
                                         CheckingPolicy, StorageType>& member) {}

// Equality with nullptr.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(
    const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
                      StorageType>& member,
    std::nullptr_t) {}

template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(
    const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
                      StorageType>& member,
    std::nullptr_t n) {}

template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(
    std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
                                        CheckingPolicy, StorageType>& member) {}

template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(
    std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
                                        CheckingPolicy, StorageType>& member) {}

// Relational operators.
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessTag2,
          typename WriteBarrierPolicy2, typename CheckingPolicy2,
          typename StorageType>
V8_INLINE bool operator<(
    const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
                      StorageType>& member1,
    const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
                      StorageType>& member2) {}

template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessTag2,
          typename WriteBarrierPolicy2, typename CheckingPolicy2,
          typename StorageType>
V8_INLINE bool operator<=(
    const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
                      StorageType>& member1,
    const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
                      StorageType>& member2) {}

template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessTag2,
          typename WriteBarrierPolicy2, typename CheckingPolicy2,
          typename StorageType>
V8_INLINE bool operator>(
    const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
                      StorageType>& member1,
    const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
                      StorageType>& member2) {}

template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
          typename CheckingPolicy1, typename T2, typename WeaknessTag2,
          typename WriteBarrierPolicy2, typename CheckingPolicy2,
          typename StorageType>
V8_INLINE bool operator>=(
    const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
                      StorageType>& member1,
    const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
                      StorageType>& member2) {}

IsWeak<internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy, StorageType>>;

}  // namespace internal

/**
 * Members are used in classes to contain strong pointers to other garbage
 * collected objects. All Member fields of a class must be traced in the class'
 * trace method.
 */
Member;

/**
 * WeakMember is similar to Member in that it is used to point to other garbage
 * collected objects. However instead of creating a strong pointer to the
 * object, the WeakMember creates a weak pointer, which does not keep the
 * pointee alive. Hence if all pointers to to a heap allocated object are weak
 * the object will be garbage collected. At the time of GC the weak pointers
 * will automatically be set to null.
 */
WeakMember;

/**
 * UntracedMember is a pointer to an on-heap object that is not traced for some
 * reason. Do not use this unless you know what you are doing. Keeping raw
 * pointers to on-heap objects is prohibited unless used from stack. Pointee
 * must be kept alive through other means.
 */
UntracedMember;

namespace subtle {

/**
 * UncompressedMember. Use with care in hot paths that would otherwise cause
 * many decompression cycles.
 */
UncompressedMember;

#if defined(CPPGC_POINTER_COMPRESSION)
/**
 * CompressedMember. Default implementation of cppgc::Member on builds with
 * pointer compression.
 */
CompressedMember;
#endif  // defined(CPPGC_POINTER_COMPRESSION)

}  // namespace subtle

namespace internal {

struct Dummy;

static constexpr size_t kSizeOfMember =;
static constexpr size_t kSizeOfUncompressedMember =;
#if defined(CPPGC_POINTER_COMPRESSION)
static constexpr size_t kSizeofCompressedMember =;
#endif  // defined(CPPGC_POINTER_COMPRESSION)

}  // namespace internal

}  // namespace cppgc

#endif  // INCLUDE_CPPGC_MEMBER_H_