File indexing completed on 2025-02-22 10:42:25
0001
0002
0003
0004
0005 #ifndef INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_
0006 #define INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_
0007
0008 #include <cstdint>
0009 #include <type_traits>
0010
0011 #include "cppgc/internal/member-storage.h"
0012 #include "cppgc/internal/write-barrier.h"
0013 #include "cppgc/sentinel-pointer.h"
0014 #include "cppgc/source-location.h"
0015 #include "cppgc/type-traits.h"
0016 #include "v8config.h" // NOLINT(build/include_directory)
0017
0018 namespace cppgc {
0019 namespace internal {
0020
0021 class HeapBase;
0022 class PersistentRegion;
0023 class CrossThreadPersistentRegion;
0024
0025
0026 class StrongMemberTag;
0027 class WeakMemberTag;
0028 class UntracedMemberTag;
0029
0030 struct DijkstraWriteBarrierPolicy {
0031 V8_INLINE static void InitializingBarrier(const void*, const void*) {
0032
0033
0034 }
0035
0036 template <WriteBarrierSlotType SlotType>
0037 V8_INLINE static void AssigningBarrier(const void* slot, const void* value) {
0038 #ifdef CPPGC_SLIM_WRITE_BARRIER
0039 if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
0040 WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
0041 #else
0042 WriteBarrier::Params params;
0043 const WriteBarrier::Type type =
0044 WriteBarrier::GetWriteBarrierType(slot, value, params);
0045 WriteBarrier(type, params, slot, value);
0046 #endif
0047 }
0048
0049 template <WriteBarrierSlotType SlotType>
0050 V8_INLINE static void AssigningBarrier(const void* slot, RawPointer storage) {
0051 static_assert(
0052 SlotType == WriteBarrierSlotType::kUncompressed,
0053 "Assigning storages of Member and UncompressedMember is not supported");
0054 #ifdef CPPGC_SLIM_WRITE_BARRIER
0055 if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
0056 WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
0057 #else
0058 WriteBarrier::Params params;
0059 const WriteBarrier::Type type =
0060 WriteBarrier::GetWriteBarrierType(slot, storage, params);
0061 WriteBarrier(type, params, slot, storage.Load());
0062 #endif
0063 }
0064
0065 #if defined(CPPGC_POINTER_COMPRESSION)
0066 template <WriteBarrierSlotType SlotType>
0067 V8_INLINE static void AssigningBarrier(const void* slot,
0068 CompressedPointer storage) {
0069 static_assert(
0070 SlotType == WriteBarrierSlotType::kCompressed,
0071 "Assigning storages of Member and UncompressedMember is not supported");
0072 #ifdef CPPGC_SLIM_WRITE_BARRIER
0073 if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
0074 WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
0075 #else
0076 WriteBarrier::Params params;
0077 const WriteBarrier::Type type =
0078 WriteBarrier::GetWriteBarrierType(slot, storage, params);
0079 WriteBarrier(type, params, slot, storage.Load());
0080 #endif
0081 }
0082 #endif
0083
0084 private:
0085 V8_INLINE static void WriteBarrier(WriteBarrier::Type type,
0086 const WriteBarrier::Params& params,
0087 const void* slot, const void* value) {
0088 switch (type) {
0089 case WriteBarrier::Type::kGenerational:
0090 WriteBarrier::GenerationalBarrier<
0091 WriteBarrier::GenerationalBarrierType::kPreciseSlot>(params, slot);
0092 break;
0093 case WriteBarrier::Type::kMarking:
0094 WriteBarrier::DijkstraMarkingBarrier(params, value);
0095 break;
0096 case WriteBarrier::Type::kNone:
0097 break;
0098 }
0099 }
0100 };
0101
0102 struct NoWriteBarrierPolicy {
0103 V8_INLINE static void InitializingBarrier(const void*, const void*) {}
0104 template <WriteBarrierSlotType>
0105 V8_INLINE static void AssigningBarrier(const void*, const void*) {}
0106 template <WriteBarrierSlotType, typename MemberStorage>
0107 V8_INLINE static void AssigningBarrier(const void*, MemberStorage) {}
0108 };
0109
0110 class V8_EXPORT SameThreadEnabledCheckingPolicyBase {
0111 protected:
0112 void CheckPointerImpl(const void* ptr, bool points_to_payload,
0113 bool check_off_heap_assignments);
0114
0115 const HeapBase* heap_ = nullptr;
0116 };
0117
0118 template <bool kCheckOffHeapAssignments>
0119 class V8_EXPORT SameThreadEnabledCheckingPolicy
0120 : private SameThreadEnabledCheckingPolicyBase {
0121 protected:
0122 template <typename T>
0123 void CheckPointer(const T* ptr) {
0124 if (!ptr || (kSentinelPointer == ptr)) return;
0125
0126 CheckPointersImplTrampoline<T>::Call(this, ptr);
0127 }
0128
0129 private:
0130 template <typename T, bool = IsCompleteV<T>>
0131 struct CheckPointersImplTrampoline {
0132 static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
0133 policy->CheckPointerImpl(ptr, false, kCheckOffHeapAssignments);
0134 }
0135 };
0136
0137 template <typename T>
0138 struct CheckPointersImplTrampoline<T, true> {
0139 static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
0140 policy->CheckPointerImpl(ptr, IsGarbageCollectedTypeV<T>,
0141 kCheckOffHeapAssignments);
0142 }
0143 };
0144 };
0145
0146 class DisabledCheckingPolicy {
0147 protected:
0148 V8_INLINE void CheckPointer(const void*) {}
0149 };
0150
0151 #ifdef DEBUG
0152
0153
0154 using DefaultMemberCheckingPolicy =
0155 SameThreadEnabledCheckingPolicy<false >;
0156 using DefaultPersistentCheckingPolicy =
0157 SameThreadEnabledCheckingPolicy<true >;
0158 #else
0159 using DefaultMemberCheckingPolicy = DisabledCheckingPolicy;
0160 using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
0161 #endif
0162
0163
0164
0165 using DefaultCrossThreadPersistentCheckingPolicy = DisabledCheckingPolicy;
0166
0167 class KeepLocationPolicy {
0168 public:
0169 constexpr const SourceLocation& Location() const { return location_; }
0170
0171 protected:
0172 constexpr KeepLocationPolicy() = default;
0173 constexpr explicit KeepLocationPolicy(const SourceLocation& location)
0174 : location_(location) {}
0175
0176
0177 KeepLocationPolicy(const KeepLocationPolicy&) = delete;
0178 KeepLocationPolicy& operator=(const KeepLocationPolicy&) = delete;
0179
0180
0181 KeepLocationPolicy(KeepLocationPolicy&&) = default;
0182 KeepLocationPolicy& operator=(KeepLocationPolicy&&) = default;
0183
0184 private:
0185 SourceLocation location_;
0186 };
0187
0188 class IgnoreLocationPolicy {
0189 public:
0190 constexpr SourceLocation Location() const { return {}; }
0191
0192 protected:
0193 constexpr IgnoreLocationPolicy() = default;
0194 constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {}
0195 };
0196
0197 #if CPPGC_SUPPORTS_OBJECT_NAMES
0198 using DefaultLocationPolicy = KeepLocationPolicy;
0199 #else
0200 using DefaultLocationPolicy = IgnoreLocationPolicy;
0201 #endif
0202
0203 struct StrongPersistentPolicy {
0204 using IsStrongPersistent = std::true_type;
0205 static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
0206 };
0207
0208 struct WeakPersistentPolicy {
0209 using IsStrongPersistent = std::false_type;
0210 static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
0211 };
0212
0213 struct StrongCrossThreadPersistentPolicy {
0214 using IsStrongPersistent = std::true_type;
0215 static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
0216 const void* object);
0217 };
0218
0219 struct WeakCrossThreadPersistentPolicy {
0220 using IsStrongPersistent = std::false_type;
0221 static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
0222 const void* object);
0223 };
0224
0225
0226 template <typename T, typename WeaknessPolicy,
0227 typename LocationPolicy = DefaultLocationPolicy,
0228 typename CheckingPolicy = DefaultCrossThreadPersistentCheckingPolicy>
0229 class BasicCrossThreadPersistent;
0230 template <typename T, typename WeaknessPolicy,
0231 typename LocationPolicy = DefaultLocationPolicy,
0232 typename CheckingPolicy = DefaultPersistentCheckingPolicy>
0233 class BasicPersistent;
0234 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0235 typename CheckingPolicy = DefaultMemberCheckingPolicy,
0236 typename StorageType = DefaultMemberStorage>
0237 class BasicMember;
0238
0239 }
0240
0241 }
0242
0243 #endif