Roll src/third_party/WebKit d10c917:a1123a1 (svn 198729:198730)
[chromium-blink-merge.git] / tools / clang / blink_gc_plugin / Edge.h
blob2ea8e544e8e6905ada5f967321683fde0ed8a89a
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
3 // found in the LICENSE file.
5 #ifndef TOOLS_BLINK_GC_PLUGIN_EDGE_H_
6 #define TOOLS_BLINK_GC_PLUGIN_EDGE_H_
8 #include <deque>
10 #include "TracingStatus.h"
12 class RecordInfo;
14 class Edge;
15 class Value;
16 class RawPtr;
17 class RefPtr;
18 class OwnPtr;
19 class Member;
20 class WeakMember;
21 class Persistent;
22 class Collection;
24 // Bare-bones visitor.
25 class EdgeVisitor {
26 public:
27 virtual ~EdgeVisitor() {}
28 virtual void VisitValue(Value*) {}
29 virtual void VisitRawPtr(RawPtr*) {}
30 virtual void VisitRefPtr(RefPtr*) {}
31 virtual void VisitOwnPtr(OwnPtr*) {}
32 virtual void VisitMember(Member*) {}
33 virtual void VisitWeakMember(WeakMember*) {}
34 virtual void VisitPersistent(Persistent*) {}
35 virtual void VisitCollection(Collection*) {}
38 // Recursive edge visitor. The traversed path is accessible in context.
39 class RecursiveEdgeVisitor : public EdgeVisitor {
40 public:
41 // Overrides that recursively walk the edges and record the path.
42 void VisitValue(Value*) override;
43 void VisitRawPtr(RawPtr*) override;
44 void VisitRefPtr(RefPtr*) override;
45 void VisitOwnPtr(OwnPtr*) override;
46 void VisitMember(Member*) override;
47 void VisitWeakMember(WeakMember*) override;
48 void VisitPersistent(Persistent*) override;
49 void VisitCollection(Collection*) override;
51 protected:
52 typedef std::deque<Edge*> Context;
53 Context& context() { return context_; }
54 Edge* Parent() { return context_.empty() ? 0 : context_.front(); }
55 void Enter(Edge* e) { return context_.push_front(e); }
56 void Leave() { context_.pop_front(); }
58 // Default callback to overwrite in visitor subclass.
59 virtual void AtValue(Value*);
60 virtual void AtRawPtr(RawPtr*);
61 virtual void AtRefPtr(RefPtr*);
62 virtual void AtOwnPtr(OwnPtr*);
63 virtual void AtMember(Member*);
64 virtual void AtWeakMember(WeakMember*);
65 virtual void AtPersistent(Persistent*);
66 virtual void AtCollection(Collection*);
68 private:
69 Context context_;
72 // Base class for all edges.
73 class Edge {
74 public:
75 enum NeedsTracingOption { kRecursive, kNonRecursive };
76 enum LivenessKind { kWeak, kStrong, kRoot };
78 virtual ~Edge() {}
79 virtual LivenessKind Kind() = 0;
80 virtual void Accept(EdgeVisitor*) = 0;
81 virtual bool NeedsFinalization() = 0;
82 virtual TracingStatus NeedsTracing(NeedsTracingOption) {
83 return TracingStatus::Unknown();
86 virtual bool IsValue() { return false; }
87 virtual bool IsRawPtr() { return false; }
88 virtual bool IsRawPtrClass() { return false; }
89 virtual bool IsRefPtr() { return false; }
90 virtual bool IsOwnPtr() { return false; }
91 virtual bool IsMember() { return false; }
92 virtual bool IsWeakMember() { return false; }
93 virtual bool IsPersistent() { return false; }
94 virtual bool IsCollection() { return false; }
97 // A value edge is a direct edge to some type, eg, part-object edges.
98 class Value : public Edge {
99 public:
100 explicit Value(RecordInfo* value) : value_(value) {};
101 bool IsValue() override { return true; }
102 LivenessKind Kind() override { return kStrong; }
103 bool NeedsFinalization() override;
104 TracingStatus NeedsTracing(NeedsTracingOption) override;
105 void Accept(EdgeVisitor* visitor) override { visitor->VisitValue(this); }
106 RecordInfo* value() { return value_; }
108 private:
109 RecordInfo* value_;
112 // Shared base for smart-pointer edges.
113 class PtrEdge : public Edge {
114 public:
115 ~PtrEdge() { delete ptr_; }
116 Edge* ptr() { return ptr_; }
117 protected:
118 PtrEdge(Edge* ptr) : ptr_(ptr) {
119 assert(ptr && "EdgePtr pointer must be non-null");
121 private:
122 Edge* ptr_;
125 class RawPtr : public PtrEdge {
126 public:
127 explicit RawPtr(Edge* ptr, bool is_ptr_class)
128 : PtrEdge(ptr), is_ptr_class_(is_ptr_class) { }
129 bool IsRawPtr() { return true; }
130 bool IsRawPtrClass() { return is_ptr_class_; }
131 LivenessKind Kind() { return kWeak; }
132 bool NeedsFinalization() { return false; }
133 TracingStatus NeedsTracing(NeedsTracingOption) {
134 return TracingStatus::Unneeded();
136 void Accept(EdgeVisitor* visitor) { visitor->VisitRawPtr(this); }
137 private:
138 bool is_ptr_class_;
141 class RefPtr : public PtrEdge {
142 public:
143 explicit RefPtr(Edge* ptr) : PtrEdge(ptr) { }
144 bool IsRefPtr() { return true; }
145 LivenessKind Kind() { return kStrong; }
146 bool NeedsFinalization() { return true; }
147 TracingStatus NeedsTracing(NeedsTracingOption) {
148 return TracingStatus::Unneeded();
150 void Accept(EdgeVisitor* visitor) { visitor->VisitRefPtr(this); }
153 class OwnPtr : public PtrEdge {
154 public:
155 explicit OwnPtr(Edge* ptr) : PtrEdge(ptr) { }
156 bool IsOwnPtr() { return true; }
157 LivenessKind Kind() { return kStrong; }
158 bool NeedsFinalization() { return true; }
159 TracingStatus NeedsTracing(NeedsTracingOption) {
160 return TracingStatus::Unneeded();
162 void Accept(EdgeVisitor* visitor) { visitor->VisitOwnPtr(this); }
165 class Member : public PtrEdge {
166 public:
167 explicit Member(Edge* ptr) : PtrEdge(ptr) { }
168 bool IsMember() { return true; }
169 LivenessKind Kind() { return kStrong; }
170 bool NeedsFinalization() { return false; }
171 TracingStatus NeedsTracing(NeedsTracingOption) {
172 return TracingStatus::Needed();
174 void Accept(EdgeVisitor* visitor) { visitor->VisitMember(this); }
177 class WeakMember : public PtrEdge {
178 public:
179 explicit WeakMember(Edge* ptr) : PtrEdge(ptr) { }
180 bool IsWeakMember() { return true; }
181 LivenessKind Kind() { return kWeak; }
182 bool NeedsFinalization() { return false; }
183 TracingStatus NeedsTracing(NeedsTracingOption) {
184 return TracingStatus::Needed();
186 void Accept(EdgeVisitor* visitor) { visitor->VisitWeakMember(this); }
189 class Persistent : public PtrEdge {
190 public:
191 explicit Persistent(Edge* ptr) : PtrEdge(ptr) { }
192 bool IsPersistent() { return true; }
193 LivenessKind Kind() { return kRoot; }
194 bool NeedsFinalization() { return true; }
195 TracingStatus NeedsTracing(NeedsTracingOption) {
196 return TracingStatus::Unneeded();
198 void Accept(EdgeVisitor* visitor) { visitor->VisitPersistent(this); }
201 class Collection : public Edge {
202 public:
203 typedef std::vector<Edge*> Members;
204 Collection(RecordInfo* info, bool on_heap, bool is_root)
205 : info_(info),
206 on_heap_(on_heap),
207 is_root_(is_root) {}
208 ~Collection() {
209 for (Members::iterator it = members_.begin(); it != members_.end(); ++it) {
210 assert(*it && "Collection-edge members must be non-null");
211 delete *it;
214 bool IsCollection() { return true; }
215 LivenessKind Kind() { return is_root_ ? kRoot : kStrong; }
216 bool on_heap() { return on_heap_; }
217 bool is_root() { return is_root_; }
218 Members& members() { return members_; }
219 void Accept(EdgeVisitor* visitor) { visitor->VisitCollection(this); }
220 void AcceptMembers(EdgeVisitor* visitor) {
221 for (Members::iterator it = members_.begin(); it != members_.end(); ++it)
222 (*it)->Accept(visitor);
224 bool NeedsFinalization();
225 TracingStatus NeedsTracing(NeedsTracingOption) {
226 if (is_root_)
227 return TracingStatus::Unneeded();
228 if (on_heap_)
229 return TracingStatus::Needed();
230 // For off-heap collections, determine tracing status of members.
231 TracingStatus status = TracingStatus::Unneeded();
232 for (Members::iterator it = members_.begin(); it != members_.end(); ++it) {
233 // Do a non-recursive test here since members could equal the holder.
234 status = status.LUB((*it)->NeedsTracing(kNonRecursive));
236 return status;
239 private:
240 RecordInfo* info_;
241 Members members_;
242 bool on_heap_;
243 bool is_root_;
246 #endif // TOOLS_BLINK_GC_PLUGIN_EDGE_H_