OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef TOOLS_BLINK_GC_PLUGIN_EDGE_H_ | 5 #ifndef TOOLS_BLINK_GC_PLUGIN_EDGE_H_ |
6 #define TOOLS_BLINK_GC_PLUGIN_EDGE_H_ | 6 #define TOOLS_BLINK_GC_PLUGIN_EDGE_H_ |
7 | 7 |
8 #include <cassert> | 8 #include <cassert> |
9 #include <deque> | 9 #include <deque> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "TracingStatus.h" | 12 #include "TracingStatus.h" |
13 | 13 |
14 class RecordInfo; | 14 class RecordInfo; |
15 | 15 |
16 class Edge; | 16 class Edge; |
17 class Value; | 17 class Collection; |
| 18 class CrossThreadPersistent; |
| 19 class Member; |
| 20 class OwnPtr; |
| 21 class Persistent; |
18 class RawPtr; | 22 class RawPtr; |
19 class RefPtr; | 23 class RefPtr; |
20 class OwnPtr; | 24 class UniquePtr; |
21 class Member; | 25 class Value; |
22 class WeakMember; | 26 class WeakMember; |
23 class Persistent; | |
24 class Collection; | |
25 | 27 |
26 // Bare-bones visitor. | 28 // Bare-bones visitor. |
27 class EdgeVisitor { | 29 class EdgeVisitor { |
28 public: | 30 public: |
29 virtual ~EdgeVisitor() {} | 31 virtual ~EdgeVisitor() {} |
30 virtual void VisitValue(Value*) {} | 32 virtual void VisitValue(Value*) {} |
31 virtual void VisitRawPtr(RawPtr*) {} | 33 virtual void VisitRawPtr(RawPtr*) {} |
32 virtual void VisitRefPtr(RefPtr*) {} | 34 virtual void VisitRefPtr(RefPtr*) {} |
33 virtual void VisitOwnPtr(OwnPtr*) {} | 35 virtual void VisitOwnPtr(OwnPtr*) {} |
| 36 virtual void VisitUniquePtr(UniquePtr*) {} |
34 virtual void VisitMember(Member*) {} | 37 virtual void VisitMember(Member*) {} |
35 virtual void VisitWeakMember(WeakMember*) {} | 38 virtual void VisitWeakMember(WeakMember*) {} |
36 virtual void VisitPersistent(Persistent*) {} | 39 virtual void VisitPersistent(Persistent*) {} |
| 40 virtual void VisitCrossThreadPersistent(CrossThreadPersistent*) {} |
37 virtual void VisitCollection(Collection*) {} | 41 virtual void VisitCollection(Collection*) {} |
38 }; | 42 }; |
39 | 43 |
40 // Recursive edge visitor. The traversed path is accessible in context. | 44 // Recursive edge visitor. The traversed path is accessible in context. |
41 class RecursiveEdgeVisitor : public EdgeVisitor { | 45 class RecursiveEdgeVisitor : public EdgeVisitor { |
42 public: | 46 public: |
43 // Overrides that recursively walk the edges and record the path. | 47 // Overrides that recursively walk the edges and record the path. |
44 void VisitValue(Value*) override; | 48 void VisitValue(Value*) override; |
45 void VisitRawPtr(RawPtr*) override; | 49 void VisitRawPtr(RawPtr*) override; |
46 void VisitRefPtr(RefPtr*) override; | 50 void VisitRefPtr(RefPtr*) override; |
47 void VisitOwnPtr(OwnPtr*) override; | 51 void VisitOwnPtr(OwnPtr*) override; |
| 52 void VisitUniquePtr(UniquePtr*) override; |
48 void VisitMember(Member*) override; | 53 void VisitMember(Member*) override; |
49 void VisitWeakMember(WeakMember*) override; | 54 void VisitWeakMember(WeakMember*) override; |
50 void VisitPersistent(Persistent*) override; | 55 void VisitPersistent(Persistent*) override; |
| 56 void VisitCrossThreadPersistent(CrossThreadPersistent*) override; |
51 void VisitCollection(Collection*) override; | 57 void VisitCollection(Collection*) override; |
52 | 58 |
53 protected: | 59 protected: |
54 typedef std::deque<Edge*> Context; | 60 typedef std::deque<Edge*> Context; |
55 Context& context() { return context_; } | 61 Context& context() { return context_; } |
56 Edge* Parent() { return context_.empty() ? 0 : context_.front(); } | 62 Edge* Parent() { return context_.empty() ? 0 : context_.front(); } |
57 void Enter(Edge* e) { return context_.push_front(e); } | 63 void Enter(Edge* e) { return context_.push_front(e); } |
58 void Leave() { context_.pop_front(); } | 64 void Leave() { context_.pop_front(); } |
59 | 65 |
60 // Default callback to overwrite in visitor subclass. | 66 // Default callback to overwrite in visitor subclass. |
61 virtual void AtValue(Value*); | 67 virtual void AtValue(Value*); |
62 virtual void AtRawPtr(RawPtr*); | 68 virtual void AtRawPtr(RawPtr*); |
63 virtual void AtRefPtr(RefPtr*); | 69 virtual void AtRefPtr(RefPtr*); |
64 virtual void AtOwnPtr(OwnPtr*); | 70 virtual void AtOwnPtr(OwnPtr*); |
| 71 virtual void AtUniquePtr(UniquePtr*); |
65 virtual void AtMember(Member*); | 72 virtual void AtMember(Member*); |
66 virtual void AtWeakMember(WeakMember*); | 73 virtual void AtWeakMember(WeakMember*); |
67 virtual void AtPersistent(Persistent*); | 74 virtual void AtPersistent(Persistent*); |
| 75 virtual void AtCrossThreadPersistent(CrossThreadPersistent*); |
68 virtual void AtCollection(Collection*); | 76 virtual void AtCollection(Collection*); |
69 | 77 |
70 private: | 78 private: |
71 Context context_; | 79 Context context_; |
72 }; | 80 }; |
73 | 81 |
74 // Base class for all edges. | 82 // Base class for all edges. |
75 class Edge { | 83 class Edge { |
76 public: | 84 public: |
77 enum NeedsTracingOption { kRecursive, kNonRecursive }; | 85 enum NeedsTracingOption { kRecursive, kNonRecursive }; |
78 enum LivenessKind { kWeak, kStrong, kRoot }; | 86 enum LivenessKind { kWeak, kStrong, kRoot }; |
79 | 87 |
80 virtual ~Edge() {} | 88 virtual ~Edge() {} |
81 virtual LivenessKind Kind() = 0; | 89 virtual LivenessKind Kind() = 0; |
82 virtual void Accept(EdgeVisitor*) = 0; | 90 virtual void Accept(EdgeVisitor*) = 0; |
83 virtual bool NeedsFinalization() = 0; | 91 virtual bool NeedsFinalization() = 0; |
84 virtual TracingStatus NeedsTracing(NeedsTracingOption) { | 92 virtual TracingStatus NeedsTracing(NeedsTracingOption) { |
85 return TracingStatus::Unknown(); | 93 return TracingStatus::Unknown(); |
86 } | 94 } |
87 | 95 |
88 virtual bool IsValue() { return false; } | 96 virtual bool IsValue() { return false; } |
89 virtual bool IsRawPtr() { return false; } | 97 virtual bool IsRawPtr() { return false; } |
90 virtual bool IsRefPtr() { return false; } | 98 virtual bool IsRefPtr() { return false; } |
91 virtual bool IsOwnPtr() { return false; } | 99 virtual bool IsOwnPtr() { return false; } |
| 100 virtual bool IsUniquePtr() { return false; } |
92 virtual bool IsMember() { return false; } | 101 virtual bool IsMember() { return false; } |
93 virtual bool IsWeakMember() { return false; } | 102 virtual bool IsWeakMember() { return false; } |
94 virtual bool IsPersistent() { return false; } | |
95 virtual bool IsCollection() { return false; } | 103 virtual bool IsCollection() { return false; } |
96 }; | 104 }; |
97 | 105 |
98 // A value edge is a direct edge to some type, eg, part-object edges. | 106 // A value edge is a direct edge to some type, eg, part-object edges. |
99 class Value : public Edge { | 107 class Value : public Edge { |
100 public: | 108 public: |
101 explicit Value(RecordInfo* value) : value_(value) {}; | 109 explicit Value(RecordInfo* value) : value_(value) {}; |
102 bool IsValue() override { return true; } | 110 bool IsValue() override { return true; } |
103 LivenessKind Kind() override { return kStrong; } | 111 LivenessKind Kind() override { return kStrong; } |
104 bool NeedsFinalization() override; | 112 bool NeedsFinalization() override; |
(...skipping 23 matching lines...) Expand all Loading... |
128 RawPtr(Edge* ptr, bool is_ref_type) | 136 RawPtr(Edge* ptr, bool is_ref_type) |
129 : PtrEdge(ptr) | 137 : PtrEdge(ptr) |
130 , is_ref_type_(is_ref_type) | 138 , is_ref_type_(is_ref_type) |
131 { | 139 { |
132 } | 140 } |
133 | 141 |
134 bool IsRawPtr() { return true; } | 142 bool IsRawPtr() { return true; } |
135 LivenessKind Kind() { return kWeak; } | 143 LivenessKind Kind() { return kWeak; } |
136 bool NeedsFinalization() { return false; } | 144 bool NeedsFinalization() { return false; } |
137 TracingStatus NeedsTracing(NeedsTracingOption) { | 145 TracingStatus NeedsTracing(NeedsTracingOption) { |
138 return TracingStatus::Unneeded(); | 146 return TracingStatus::Illegal(); |
139 } | 147 } |
140 void Accept(EdgeVisitor* visitor) { visitor->VisitRawPtr(this); } | 148 void Accept(EdgeVisitor* visitor) { visitor->VisitRawPtr(this); } |
141 | 149 |
142 bool HasReferenceType() { return is_ref_type_; } | 150 bool HasReferenceType() { return is_ref_type_; } |
143 private: | 151 private: |
144 bool is_ref_type_; | 152 bool is_ref_type_; |
145 }; | 153 }; |
146 | 154 |
147 class RefPtr : public PtrEdge { | 155 class RefPtr : public PtrEdge { |
148 public: | 156 public: |
149 explicit RefPtr(Edge* ptr) : PtrEdge(ptr) { } | 157 explicit RefPtr(Edge* ptr) : PtrEdge(ptr) { } |
150 bool IsRefPtr() { return true; } | 158 bool IsRefPtr() { return true; } |
151 LivenessKind Kind() { return kStrong; } | 159 LivenessKind Kind() { return kStrong; } |
152 bool NeedsFinalization() { return true; } | 160 bool NeedsFinalization() { return true; } |
153 TracingStatus NeedsTracing(NeedsTracingOption) { | 161 TracingStatus NeedsTracing(NeedsTracingOption) { |
154 return TracingStatus::Unneeded(); | 162 return TracingStatus::Illegal(); |
155 } | 163 } |
156 void Accept(EdgeVisitor* visitor) { visitor->VisitRefPtr(this); } | 164 void Accept(EdgeVisitor* visitor) { visitor->VisitRefPtr(this); } |
157 }; | 165 }; |
158 | 166 |
159 class OwnPtr : public PtrEdge { | 167 class OwnPtr : public PtrEdge { |
160 public: | 168 public: |
161 explicit OwnPtr(Edge* ptr) : PtrEdge(ptr) { } | 169 explicit OwnPtr(Edge* ptr) : PtrEdge(ptr) { } |
162 bool IsOwnPtr() { return true; } | 170 bool IsOwnPtr() { return true; } |
163 LivenessKind Kind() { return kStrong; } | 171 LivenessKind Kind() { return kStrong; } |
164 bool NeedsFinalization() { return true; } | 172 bool NeedsFinalization() { return true; } |
165 TracingStatus NeedsTracing(NeedsTracingOption) { | 173 TracingStatus NeedsTracing(NeedsTracingOption) { |
166 return TracingStatus::Unneeded(); | 174 return TracingStatus::Illegal(); |
167 } | 175 } |
168 void Accept(EdgeVisitor* visitor) { visitor->VisitOwnPtr(this); } | 176 void Accept(EdgeVisitor* visitor) { visitor->VisitOwnPtr(this); } |
169 }; | 177 }; |
170 | 178 |
| 179 class UniquePtr : public PtrEdge { |
| 180 public: |
| 181 explicit UniquePtr(Edge* ptr) : PtrEdge(ptr) { } |
| 182 bool IsUniquePtr() { return true; } |
| 183 LivenessKind Kind() { return kStrong; } |
| 184 bool NeedsFinalization() { return true; } |
| 185 TracingStatus NeedsTracing(NeedsTracingOption) { |
| 186 return TracingStatus::Illegal(); |
| 187 } |
| 188 void Accept(EdgeVisitor* visitor) { visitor->VisitUniquePtr(this); } |
| 189 }; |
| 190 |
171 class Member : public PtrEdge { | 191 class Member : public PtrEdge { |
172 public: | 192 public: |
173 explicit Member(Edge* ptr) : PtrEdge(ptr) { } | 193 explicit Member(Edge* ptr) : PtrEdge(ptr) { } |
174 bool IsMember() { return true; } | 194 bool IsMember() { return true; } |
175 LivenessKind Kind() { return kStrong; } | 195 LivenessKind Kind() { return kStrong; } |
176 bool NeedsFinalization() { return false; } | 196 bool NeedsFinalization() { return false; } |
177 TracingStatus NeedsTracing(NeedsTracingOption) { | 197 TracingStatus NeedsTracing(NeedsTracingOption) { |
178 return TracingStatus::Needed(); | 198 return TracingStatus::Needed(); |
179 } | 199 } |
180 void Accept(EdgeVisitor* visitor) { visitor->VisitMember(this); } | 200 void Accept(EdgeVisitor* visitor) { visitor->VisitMember(this); } |
181 }; | 201 }; |
182 | 202 |
183 class WeakMember : public PtrEdge { | 203 class WeakMember : public PtrEdge { |
184 public: | 204 public: |
185 explicit WeakMember(Edge* ptr) : PtrEdge(ptr) { } | 205 explicit WeakMember(Edge* ptr) : PtrEdge(ptr) { } |
186 bool IsWeakMember() { return true; } | 206 bool IsWeakMember() { return true; } |
187 LivenessKind Kind() { return kWeak; } | 207 LivenessKind Kind() { return kWeak; } |
188 bool NeedsFinalization() { return false; } | 208 bool NeedsFinalization() { return false; } |
189 TracingStatus NeedsTracing(NeedsTracingOption) { | 209 TracingStatus NeedsTracing(NeedsTracingOption) { |
190 return TracingStatus::Needed(); | 210 return TracingStatus::Needed(); |
191 } | 211 } |
192 void Accept(EdgeVisitor* visitor) { visitor->VisitWeakMember(this); } | 212 void Accept(EdgeVisitor* visitor) { visitor->VisitWeakMember(this); } |
193 }; | 213 }; |
194 | 214 |
195 class Persistent : public PtrEdge { | 215 class Persistent : public PtrEdge { |
196 public: | 216 public: |
197 explicit Persistent(Edge* ptr) : PtrEdge(ptr) { } | 217 explicit Persistent(Edge* ptr) : PtrEdge(ptr) { } |
198 bool IsPersistent() { return true; } | |
199 LivenessKind Kind() { return kRoot; } | 218 LivenessKind Kind() { return kRoot; } |
200 bool NeedsFinalization() { return true; } | 219 bool NeedsFinalization() { return true; } |
201 TracingStatus NeedsTracing(NeedsTracingOption) { | 220 TracingStatus NeedsTracing(NeedsTracingOption) { |
202 return TracingStatus::Unneeded(); | 221 return TracingStatus::Unneeded(); |
203 } | 222 } |
204 void Accept(EdgeVisitor* visitor) { visitor->VisitPersistent(this); } | 223 void Accept(EdgeVisitor* visitor) { visitor->VisitPersistent(this); } |
205 }; | 224 }; |
206 | 225 |
| 226 class CrossThreadPersistent : public PtrEdge { |
| 227 public: |
| 228 explicit CrossThreadPersistent(Edge* ptr) : PtrEdge(ptr) { } |
| 229 LivenessKind Kind() { return kRoot; } |
| 230 bool NeedsFinalization() { return true; } |
| 231 TracingStatus NeedsTracing(NeedsTracingOption) { |
| 232 return TracingStatus::Illegal(); |
| 233 } |
| 234 void Accept(EdgeVisitor* visitor) { |
| 235 visitor->VisitCrossThreadPersistent(this); |
| 236 } |
| 237 }; |
| 238 |
207 class Collection : public Edge { | 239 class Collection : public Edge { |
208 public: | 240 public: |
209 typedef std::vector<Edge*> Members; | 241 typedef std::vector<Edge*> Members; |
210 Collection(RecordInfo* info, bool on_heap, bool is_root) | 242 Collection(RecordInfo* info, bool on_heap, bool is_root) |
211 : info_(info), | 243 : info_(info), |
212 on_heap_(on_heap), | 244 on_heap_(on_heap), |
213 is_root_(is_root) {} | 245 is_root_(is_root) {} |
214 ~Collection() { | 246 ~Collection() { |
215 for (Members::iterator it = members_.begin(); it != members_.end(); ++it) { | 247 for (Members::iterator it = members_.begin(); it != members_.end(); ++it) { |
216 assert(*it && "Collection-edge members must be non-null"); | 248 assert(*it && "Collection-edge members must be non-null"); |
(...skipping 26 matching lines...) Expand all Loading... |
243 } | 275 } |
244 | 276 |
245 private: | 277 private: |
246 RecordInfo* info_; | 278 RecordInfo* info_; |
247 Members members_; | 279 Members members_; |
248 bool on_heap_; | 280 bool on_heap_; |
249 bool is_root_; | 281 bool is_root_; |
250 }; | 282 }; |
251 | 283 |
252 #endif // TOOLS_BLINK_GC_PLUGIN_EDGE_H_ | 284 #endif // TOOLS_BLINK_GC_PLUGIN_EDGE_H_ |
OLD | NEW |