1 // Copyright 2020 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ 6 #define INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ 7 8 #include <cstdint> 9 #include <type_traits> 10 11 #include "cppgc/internal/write-barrier.h" 12 #include "cppgc/source-location.h" 13 #include "v8config.h" // NOLINT(build/include_directory) 14 15 namespace cppgc { 16 namespace internal { 17 18 class PersistentRegion; 19 20 // Tags to distinguish between strong and weak member types. 21 class StrongMemberTag; 22 class WeakMemberTag; 23 class UntracedMemberTag; 24 25 struct DijkstraWriteBarrierPolicy { InitializingBarrierDijkstraWriteBarrierPolicy26 static void InitializingBarrier(const void*, const void*) { 27 // Since in initializing writes the source object is always white, having no 28 // barrier doesn't break the tri-color invariant. 29 } AssigningBarrierDijkstraWriteBarrierPolicy30 static void AssigningBarrier(const void* slot, const void* value) { 31 WriteBarrier::MarkingBarrier(slot, value); 32 } 33 }; 34 35 struct NoWriteBarrierPolicy { InitializingBarrierNoWriteBarrierPolicy36 static void InitializingBarrier(const void*, const void*) {} AssigningBarrierNoWriteBarrierPolicy37 static void AssigningBarrier(const void*, const void*) {} 38 }; 39 40 class V8_EXPORT EnabledCheckingPolicy { 41 protected: 42 EnabledCheckingPolicy(); 43 void CheckPointer(const void* ptr); 44 45 private: 46 void* impl_; 47 }; 48 49 class DisabledCheckingPolicy { 50 protected: CheckPointer(const void * raw)51 void CheckPointer(const void* raw) {} 52 }; 53 54 #if V8_ENABLE_CHECKS 55 using DefaultCheckingPolicy = EnabledCheckingPolicy; 56 #else 57 using DefaultCheckingPolicy = DisabledCheckingPolicy; 58 #endif 59 60 class KeepLocationPolicy { 61 public: Location()62 constexpr const SourceLocation& Location() const { return location_; } 63 64 protected: 65 constexpr KeepLocationPolicy() = default; KeepLocationPolicy(const SourceLocation & location)66 constexpr explicit KeepLocationPolicy(const SourceLocation& location) 67 : location_(location) {} 68 69 // KeepLocationPolicy must not copy underlying source locations. 70 KeepLocationPolicy(const KeepLocationPolicy&) = delete; 71 KeepLocationPolicy& operator=(const KeepLocationPolicy&) = delete; 72 73 // Location of the original moved from object should be preserved. 74 KeepLocationPolicy(KeepLocationPolicy&&) = default; 75 KeepLocationPolicy& operator=(KeepLocationPolicy&&) = default; 76 77 private: 78 SourceLocation location_; 79 }; 80 81 class IgnoreLocationPolicy { 82 public: Location()83 constexpr SourceLocation Location() const { return {}; } 84 85 protected: 86 constexpr IgnoreLocationPolicy() = default; IgnoreLocationPolicy(const SourceLocation &)87 constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {} 88 }; 89 90 #if CPPGC_SUPPORTS_OBJECT_NAMES 91 using DefaultLocationPolicy = KeepLocationPolicy; 92 #else 93 using DefaultLocationPolicy = IgnoreLocationPolicy; 94 #endif 95 96 struct StrongPersistentPolicy { 97 using IsStrongPersistent = std::true_type; 98 static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); 99 }; 100 101 struct WeakPersistentPolicy { 102 using IsStrongPersistent = std::false_type; 103 static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); 104 }; 105 106 struct StrongCrossThreadPersistentPolicy { 107 using IsStrongPersistent = std::true_type; 108 static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); 109 }; 110 111 struct WeakCrossThreadPersistentPolicy { 112 using IsStrongPersistent = std::false_type; 113 static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); 114 }; 115 116 // Forward declarations setting up the default policies. 117 template <typename T, typename WeaknessPolicy, 118 typename LocationPolicy = DefaultLocationPolicy, 119 typename CheckingPolicy = DisabledCheckingPolicy> 120 class BasicCrossThreadPersistent; 121 template <typename T, typename WeaknessPolicy, 122 typename LocationPolicy = DefaultLocationPolicy, 123 typename CheckingPolicy = DefaultCheckingPolicy> 124 class BasicPersistent; 125 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, 126 typename CheckingPolicy = DefaultCheckingPolicy> 127 class BasicMember; 128 129 // Special tag type used to denote some sentinel member. The semantics of the 130 // sentinel is defined by the embedder. 131 struct SentinelPointer { 132 template <typename T> 133 operator T*() const { // NOLINT 134 static constexpr intptr_t kSentinelValue = 1; 135 return reinterpret_cast<T*>(kSentinelValue); 136 } 137 // Hidden friends. 138 friend bool operator==(SentinelPointer, SentinelPointer) { return true; } 139 friend bool operator!=(SentinelPointer, SentinelPointer) { return false; } 140 }; 141 142 } // namespace internal 143 144 constexpr internal::SentinelPointer kSentinelPointer; 145 146 } // namespace cppgc 147 148 #endif // INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ 149