chromium/third_party/blink/renderer/platform/heap/trace_traits.h

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_TRACE_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_TRACE_TRAITS_H_

#include <tuple>

#include "base/notreached.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/hash_table.h"
#include "third_party/blink/renderer/platform/wtf/key_value_pair.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
#include "v8/include/cppgc/trace-trait.h"

namespace blink {

template <typename T>
struct TraceIfNeeded {};

// `WTF::IsWeak<typename Traits::TraitType>::value` is always false when used
// from vectors (on and off the GCed heap).
template <WTF::WeakHandlingFlag weakness,
          typename T,
          typename Traits,
          bool = WTF::IsTraceable<typename Traits::TraitType>::value &&
                 !WTF::IsWeak<typename Traits::TraitType>::value,
          WTF::WeakHandlingFlag = WTF::kWeakHandlingTrait<T>>
struct TraceCollectionIfEnabled;

TraceCollectionIfEnabled<weakness, T, Traits, false, WTF::kNoWeakHandling>;

TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits, false, WTF::kWeakHandling>;

template <WTF::WeakHandlingFlag weakness,
          typename T,
          typename Traits,
          bool,
          WTF::WeakHandlingFlag>
struct TraceCollectionIfEnabled {};

namespace internal {

// Helper for processing ephemerons represented as KeyValuePair. Reorders
// parameters if needed so that KeyType is always weak.
template <typename _KeyType,
          typename _ValueType,
          typename _KeyTraits,
          typename _ValueTraits,
          bool = WTF::IsWeak<_ValueType>::value>
struct EphemeronKeyValuePair {};

EphemeronKeyValuePair<_KeyType, _ValueType, _KeyTraits, _ValueTraits, true>;

template <WTF::WeakHandlingFlag WeakHandling,
          typename Key,
          typename Value,
          typename Traits>
struct KeyValuePairInCollectionTrait {};

}  // namespace internal

}  // namespace blink

namespace WTF {

// Trait for strong treatment of KeyValuePair. This is used to handle regular
// KVP but also for strongification of otherwise weakly handled KVPs.
TraceInCollectionTrait<kNoWeakHandling, KeyValuePair<Key, Value>, Traits>;

TraceInCollectionTrait<kWeakHandling, KeyValuePair<Key, Value>, Traits>;

// Catch-all for types that have a way to trace that don't have special
// handling for weakness in collections.  This means that if this type
// contains WeakMember fields, they will simply be zeroed, but the entry
// will not be removed from the collection.  This always happens for
// things in vectors, which don't currently support special handling of
// weak elements.
TraceInCollectionTrait<kNoWeakHandling, T, Traits>;

TraceInCollectionTrait<kNoWeakHandling, blink::WeakMember<T>, Traits>;

// Catch-all for types that have HashTrait support for tracing with weakness.
// Empty to enforce specialization.
TraceInCollectionTrait<kWeakHandling, T, Traits>;

TraceInCollectionTrait<kWeakHandling, blink::WeakMember<T>, Traits>;

}  // namespace WTF

namespace cppgc {

// This trace trait for std::pair will clear WeakMember if their referent is
// collected. If you have a collection that contain weakness it does not remove
// entries from the collection that contain nulled WeakMember.
TraceTrait<std::pair<T, U>>;

}  // namespace cppgc

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_TRACE_TRAITS_H_