• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/sentinel-pointer.h"
13 #include "cppgc/source-location.h"
14 #include "cppgc/type-traits.h"
15 #include "v8config.h"  // NOLINT(build/include_directory)
16 
17 namespace cppgc {
18 namespace internal {
19 
20 class HeapBase;
21 class PersistentRegion;
22 class CrossThreadPersistentRegion;
23 
24 // Tags to distinguish between strong and weak member types.
25 class StrongMemberTag;
26 class WeakMemberTag;
27 class UntracedMemberTag;
28 
29 struct DijkstraWriteBarrierPolicy {
InitializingBarrierDijkstraWriteBarrierPolicy30   static void InitializingBarrier(const void*, const void*) {
31     // Since in initializing writes the source object is always white, having no
32     // barrier doesn't break the tri-color invariant.
33   }
AssigningBarrierDijkstraWriteBarrierPolicy34   static void AssigningBarrier(const void* slot, const void* value) {
35     WriteBarrier::Params params;
36     switch (WriteBarrier::GetWriteBarrierType(slot, value, params)) {
37       case WriteBarrier::Type::kGenerational:
38         WriteBarrier::GenerationalBarrier(params, slot);
39         break;
40       case WriteBarrier::Type::kMarking:
41         WriteBarrier::DijkstraMarkingBarrier(params, value);
42         break;
43       case WriteBarrier::Type::kNone:
44         break;
45     }
46   }
47 };
48 
49 struct NoWriteBarrierPolicy {
InitializingBarrierNoWriteBarrierPolicy50   static void InitializingBarrier(const void*, const void*) {}
AssigningBarrierNoWriteBarrierPolicy51   static void AssigningBarrier(const void*, const void*) {}
52 };
53 
54 class V8_EXPORT SameThreadEnabledCheckingPolicyBase {
55  protected:
56   void CheckPointerImpl(const void* ptr, bool points_to_payload,
57                         bool check_off_heap_assignments);
58 
59   const HeapBase* heap_ = nullptr;
60 };
61 
62 template <bool kCheckOffHeapAssignments>
63 class V8_EXPORT SameThreadEnabledCheckingPolicy
64     : private SameThreadEnabledCheckingPolicyBase {
65  protected:
66   template <typename T>
CheckPointer(const T * ptr)67   void CheckPointer(const T* ptr) {
68     if (!ptr || (kSentinelPointer == ptr)) return;
69 
70     CheckPointersImplTrampoline<T>::Call(this, ptr);
71   }
72 
73  private:
74   template <typename T, bool = IsCompleteV<T>>
75   struct CheckPointersImplTrampoline {
CallCheckPointersImplTrampoline76     static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
77       policy->CheckPointerImpl(ptr, false, kCheckOffHeapAssignments);
78     }
79   };
80 
81   template <typename T>
82   struct CheckPointersImplTrampoline<T, true> {
83     static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
84       policy->CheckPointerImpl(ptr, IsGarbageCollectedTypeV<T>,
85                                kCheckOffHeapAssignments);
86     }
87   };
88 };
89 
90 class DisabledCheckingPolicy {
91  protected:
92   void CheckPointer(const void*) {}
93 };
94 
95 #ifdef DEBUG
96 // Off heap members are not connected to object graph and thus cannot ressurect
97 // dead objects.
98 using DefaultMemberCheckingPolicy =
99     SameThreadEnabledCheckingPolicy<false /* kCheckOffHeapAssignments*/>;
100 using DefaultPersistentCheckingPolicy =
101     SameThreadEnabledCheckingPolicy<true /* kCheckOffHeapAssignments*/>;
102 #else   // !DEBUG
103 using DefaultMemberCheckingPolicy = DisabledCheckingPolicy;
104 using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
105 #endif  // !DEBUG
106 // For CT(W)P neither marking information (for value), nor objectstart bitmap
107 // (for slot) are guaranteed to be present because there's no synchronization
108 // between heaps after marking.
109 using DefaultCrossThreadPersistentCheckingPolicy = DisabledCheckingPolicy;
110 
111 class KeepLocationPolicy {
112  public:
113   constexpr const SourceLocation& Location() const { return location_; }
114 
115  protected:
116   constexpr KeepLocationPolicy() = default;
117   constexpr explicit KeepLocationPolicy(const SourceLocation& location)
118       : location_(location) {}
119 
120   // KeepLocationPolicy must not copy underlying source locations.
121   KeepLocationPolicy(const KeepLocationPolicy&) = delete;
122   KeepLocationPolicy& operator=(const KeepLocationPolicy&) = delete;
123 
124   // Location of the original moved from object should be preserved.
125   KeepLocationPolicy(KeepLocationPolicy&&) = default;
126   KeepLocationPolicy& operator=(KeepLocationPolicy&&) = default;
127 
128  private:
129   SourceLocation location_;
130 };
131 
132 class IgnoreLocationPolicy {
133  public:
134   constexpr SourceLocation Location() const { return {}; }
135 
136  protected:
137   constexpr IgnoreLocationPolicy() = default;
138   constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {}
139 };
140 
141 #if CPPGC_SUPPORTS_OBJECT_NAMES
142 using DefaultLocationPolicy = KeepLocationPolicy;
143 #else
144 using DefaultLocationPolicy = IgnoreLocationPolicy;
145 #endif
146 
147 struct StrongPersistentPolicy {
148   using IsStrongPersistent = std::true_type;
149   static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
150 };
151 
152 struct WeakPersistentPolicy {
153   using IsStrongPersistent = std::false_type;
154   static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
155 };
156 
157 struct StrongCrossThreadPersistentPolicy {
158   using IsStrongPersistent = std::true_type;
159   static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
160       const void* object);
161 };
162 
163 struct WeakCrossThreadPersistentPolicy {
164   using IsStrongPersistent = std::false_type;
165   static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
166       const void* object);
167 };
168 
169 // Forward declarations setting up the default policies.
170 template <typename T, typename WeaknessPolicy,
171           typename LocationPolicy = DefaultLocationPolicy,
172           typename CheckingPolicy = DefaultCrossThreadPersistentCheckingPolicy>
173 class BasicCrossThreadPersistent;
174 template <typename T, typename WeaknessPolicy,
175           typename LocationPolicy = DefaultLocationPolicy,
176           typename CheckingPolicy = DefaultPersistentCheckingPolicy>
177 class BasicPersistent;
178 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
179           typename CheckingPolicy = DefaultMemberCheckingPolicy>
180 class BasicMember;
181 
182 }  // namespace internal
183 
184 }  // namespace cppgc
185 
186 #endif  // INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_
187