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